@reportwright/cli 0.13.1 → 0.13.2-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pw.mjs CHANGED
@@ -5415,18 +5415,18 @@ function fontsForDef(def, unknown = void 0) {
5415
5415
  const keys = /* @__PURE__ */ new Set();
5416
5416
  const seen = /* @__PURE__ */ new Set();
5417
5417
  const baseFamily = def?.styles?.base?.fontFamily;
5418
- const walk = (o) => {
5418
+ const walk2 = (o) => {
5419
5419
  if (!o || typeof o !== "object" || seen.has(o)) return;
5420
5420
  seen.add(o);
5421
5421
  if (Array.isArray(o)) {
5422
- for (const x of o) walk(x);
5422
+ for (const x of o) walk2(x);
5423
5423
  return;
5424
5424
  }
5425
5425
  if (o.fontFamily != null || o.fontWeight != null || o.fontStyle != null) keys.add(resolveFontKey(o.fontFamily ?? baseFamily, o.fontWeight, o.fontStyle, unknown));
5426
5426
  if (o.type === "chart") keys.add(resolveFontKey(o.fontFamily ?? baseFamily, "bold", "normal"));
5427
- for (const [k, v] of Object.entries(o)) if (v && typeof v === "object" && k !== "dataSources" && k !== "data") walk(v);
5427
+ for (const [k, v] of Object.entries(o)) if (v && typeof v === "object" && k !== "dataSources" && k !== "data") walk2(v);
5428
5428
  };
5429
- walk(def);
5429
+ walk2(def);
5430
5430
  return [...keys];
5431
5431
  }
5432
5432
  function fontsFor(texts) {
@@ -7126,8 +7126,8 @@ function formatDate(d, fmt2, locale, tz) {
7126
7126
  return localName(locale, "month", style, w) ?? fallback;
7127
7127
  };
7128
7128
  const p2 = (n5) => String(n5).padStart(2, "0");
7129
- return fmt2.replace(/(y+|M+|d+|H+|h+|m+|s+|f+|F+|t+|z+|\/)|'([^']*)'?|"([^"]*)"?|\\(.?)/g, (tok, run, q1, q22, esc8) => {
7130
- if (!run) return q1 ?? q22 ?? esc8 ?? "";
7129
+ return fmt2.replace(/(y+|M+|d+|H+|h+|m+|s+|f+|F+|t+|z+|\/)|'([^']*)'?|"([^"]*)"?|\\(.?)/g, (tok, run, q1, q22, esc9) => {
7130
+ if (!run) return q1 ?? q22 ?? esc9 ?? "";
7131
7131
  const n5 = run.length;
7132
7132
  switch (run[0]) {
7133
7133
  case "y": {
@@ -7728,8 +7728,8 @@ function rowLocal(ast) {
7728
7728
  const k = n5.name.toLowerCase();
7729
7729
  return !n5.obj && (k in FUNCTIONS || k === "iif" || k === "switch" || k === "choose" || k === "lookup" || k === "lookupset");
7730
7730
  };
7731
- const walk = (n5) => !n5 || typeof n5 !== "object" || (Array.isArray(n5) ? n5.every(walk) : local(n5) && Object.values(n5).every(walk));
7732
- r = walk(ast);
7731
+ const walk2 = (n5) => !n5 || typeof n5 !== "object" || (Array.isArray(n5) ? n5.every(walk2) : local(n5) && Object.values(n5).every(walk2));
7732
+ r = walk2(ast);
7733
7733
  ROW_LOCAL.set(ast, r);
7734
7734
  }
7735
7735
  return r;
@@ -7801,8 +7801,8 @@ function aggregator(name, ctx) {
7801
7801
  function pureRows(ast) {
7802
7802
  let r = PURE_ROWS.get(ast);
7803
7803
  if (r === void 0) {
7804
- const walk = (n5) => !n5 || typeof n5 !== "object" || (Array.isArray(n5) ? n5.every(walk) : !(n5.type === "id" && ["globals", "parent", "partproperties"].includes(n5.name.toLowerCase())) && Object.values(n5).every(walk));
7805
- r = rowLocal(ast) && walk(ast);
7804
+ const walk2 = (n5) => !n5 || typeof n5 !== "object" || (Array.isArray(n5) ? n5.every(walk2) : !(n5.type === "id" && ["globals", "parent", "partproperties"].includes(n5.name.toLowerCase())) && Object.values(n5).every(walk2));
7805
+ r = rowLocal(ast) && walk2(ast);
7806
7806
  PURE_ROWS.set(ast, r);
7807
7807
  }
7808
7808
  return r;
@@ -8055,7 +8055,7 @@ function pad(fname, s, width, c, left) {
8055
8055
  function jasperValue(n5, ctx) {
8056
8056
  const a = n5.args;
8057
8057
  if (a.length < 6) throw new ExprError("JasperValue needs a data set, a calculation, an expression, a time, a reset and an end", n5.p);
8058
- const ds = String(evaluate(a[0], ctx)), at2 = String(evaluate(a[3], ctx)).toLowerCase();
8058
+ const ds = String(evaluate(a[0], ctx)), at3 = String(evaluate(a[3], ctx)).toLowerCase();
8059
8059
  const [calc, incrS] = String(evaluate(a[1], ctx)).toLowerCase().split("@");
8060
8060
  const incr = incrS ? Math.trunc(Number(incrS)) || 0 : 0;
8061
8061
  const reset = Math.trunc(Number(evaluate(a[4], ctx))) || 0, end = Math.trunc(Number(evaluate(a[5], ctx)));
@@ -8077,18 +8077,18 @@ function jasperValue(n5, ctx) {
8077
8077
  const N = rows.length;
8078
8078
  const posOf = (r) => r ? info.pos.get(r) : void 0;
8079
8079
  let anchor;
8080
- if (at2 === "detail") anchor = posOf(ctx.fields);
8081
- else if (at2 === "header") anchor = posOf(ctx.aggRows?.[0]);
8082
- else if (at2 === "footer") anchor = posOf(ctx.aggRows?.[ctx.aggRows.length - 1]);
8083
- else if (at2 === "start") anchor = -1;
8080
+ if (at3 === "detail") anchor = posOf(ctx.fields);
8081
+ else if (at3 === "header") anchor = posOf(ctx.aggRows?.[0]);
8082
+ else if (at3 === "footer") anchor = posOf(ctx.aggRows?.[ctx.aggRows.length - 1]);
8083
+ else if (at3 === "start") anchor = -1;
8084
8084
  else anchor = N - 1;
8085
8085
  if (anchor === void 0) return null;
8086
8086
  let b;
8087
8087
  if (end === 0) b = N - 1;
8088
8088
  else if (end > 0) b = N ? info.end[end][Math.max(0, anchor)] : -1;
8089
- else b = at2 === "header" ? anchor - 1 : anchor;
8089
+ else b = at3 === "header" ? anchor - 1 : anchor;
8090
8090
  if (b < 0) return calc === "rows" ? 0 : null;
8091
- if (end < 0 && at2 === "header" && reset > 0 && info.start[reset][anchor] > b) return calc === "rows" ? 0 : null;
8091
+ if (end < 0 && at3 === "header" && reset > 0 && info.start[reset][anchor] > b) return calc === "rows" ? 0 : null;
8092
8092
  const vk = `v|${astId(a[2])}|${calc}|${reset}|${incr}|${kid}`;
8093
8093
  let vals = byRows.get(vk);
8094
8094
  if (!vals) {
@@ -8378,10 +8378,10 @@ function callIssues(ast, custom, suggest) {
8378
8378
  }
8379
8379
  };
8380
8380
  const known = () => [...FUNCTION_NAMES, ...Object.keys(FUNCTIONS)];
8381
- const walk = (n5, depth) => {
8381
+ const walk2 = (n5, depth) => {
8382
8382
  if (!n5 || typeof n5 !== "object" || depth > 200) return;
8383
8383
  if (Array.isArray(n5)) {
8384
- for (const x of n5) walk(x, depth + 1);
8384
+ for (const x of n5) walk2(x, depth + 1);
8385
8385
  return;
8386
8386
  }
8387
8387
  if (n5.type === "call") {
@@ -8394,9 +8394,9 @@ function callIssues(ast, custom, suggest) {
8394
8394
  } else if (isCode && !custom.has(lower)) say(`code.${lower}`, `The report has no function "${n5.name}" (Code.${n5.name})`);
8395
8395
  else if (n5.obj && !isCode && !isString && !METHODS[lower]) say(`.${lower}`, `"${n5.name}(…)" after "." is not supported`);
8396
8396
  }
8397
- for (const k in n5) if (k !== "p" && n5[k] && typeof n5[k] === "object") walk(n5[k], depth + 1);
8397
+ for (const k in n5) if (k !== "p" && n5[k] && typeof n5[k] === "object") walk2(n5[k], depth + 1);
8398
8398
  };
8399
- walk(ast, 0);
8399
+ walk2(ast, 0);
8400
8400
  return out;
8401
8401
  }
8402
8402
  function checkFunctions(list2) {
@@ -9270,8 +9270,8 @@ function fetchFailure(e2, input) {
9270
9270
  const code = String(e2.cause?.code || e2.code || "");
9271
9271
  if (!code && e2.message !== "fetch failed") return e2;
9272
9272
  const why = CAUSES[code] || (/^ERR_TLS|CERT_|SSL/.test(code) ? "TLS error" : "");
9273
- const at2 = redactUrl(input?.href ?? input);
9274
- return Object.assign(new Error(`the request to ${at2} failed${why ? `: ${why}` : ""}${code ? ` (${code})` : ""}`), { code: e2.code });
9273
+ const at3 = redactUrl(input?.href ?? input);
9274
+ return Object.assign(new Error(`the request to ${at3} failed${why ? `: ${why}` : ""}${code ? ` (${code})` : ""}`), { code: e2.code });
9275
9275
  }
9276
9276
  function anySignal(list2) {
9277
9277
  const S3 = (
@@ -9330,7 +9330,7 @@ var init_guard = __esm({
9330
9330
  });
9331
9331
 
9332
9332
  // src/importers/xml.js
9333
- function decode(s, at2) {
9333
+ function decode(s, at3) {
9334
9334
  if (!s.includes("&")) return s;
9335
9335
  let out = "", i = 0;
9336
9336
  for (; ; ) {
@@ -9338,7 +9338,7 @@ function decode(s, at2) {
9338
9338
  if (amp < 0) return out + s.slice(i);
9339
9339
  out += s.slice(i, amp);
9340
9340
  const semi = s.indexOf(";", amp);
9341
- if (semi < 0 || semi - amp > 12) throw new XmlError(`A "&" that does not start a reference, near character ${at2 + amp}`);
9341
+ if (semi < 0 || semi - amp > 12) throw new XmlError(`A "&" that does not start a reference, near character ${at3 + amp}`);
9342
9342
  const ref2 = s.slice(amp + 1, semi);
9343
9343
  if (ref2[0] === "#") {
9344
9344
  const hex6 = ref2[1] === "x" || ref2[1] === "X";
@@ -9355,20 +9355,21 @@ function parseXml(src, limits = {}) {
9355
9355
  const L = { ...XML_LIMITS, ...limits };
9356
9356
  if (typeof src !== "string") throw new XmlError("The file is not text");
9357
9357
  if (src.length > L.maxChars) throw new XmlError(`The file is too large (more than ${L.maxChars} characters)`);
9358
- if (src.charCodeAt(0) === 65279) src = src.slice(1);
9358
+ const bom = src.charCodeAt(0) === 65279 ? 1 : 0;
9359
+ if (bom) src = src.slice(1);
9359
9360
  const stack2 = [];
9360
9361
  const nsStack = [Object.assign(/* @__PURE__ */ Object.create(null), { xml: "http://www.w3.org/XML/1998/namespace" })];
9361
9362
  let root = null;
9362
9363
  let count = 0, i = 0;
9363
9364
  const n5 = src.length;
9364
- const fail2 = (msg, at2 = i) => {
9365
- throw new XmlError(`${msg} (character ${at2})`);
9365
+ const fail2 = (msg, at3 = i) => {
9366
+ throw new XmlError(`${msg} (character ${at3})`);
9366
9367
  };
9367
- const addText = (t, at2) => {
9368
+ const addText = (t, at3) => {
9368
9369
  if (!t) return;
9369
9370
  const top = stack2[stack2.length - 1];
9370
9371
  if (top) top.text += t;
9371
- else for (let k = 0; k < t.length; k++) if (!isSpace(t[k])) fail2("Text outside the root element", at2 + k);
9372
+ else for (let k = 0; k < t.length; k++) if (!isSpace(t[k])) fail2("Text outside the root element", at3 + k);
9372
9373
  };
9373
9374
  while (i < n5) {
9374
9375
  const lt = src.indexOf("<", i);
@@ -9471,7 +9472,7 @@ function parseXml(src, limits = {}) {
9471
9472
  const colon = qname.indexOf(":");
9472
9473
  const prefix = colon < 0 ? "" : qname.slice(0, colon);
9473
9474
  const ns = scope[prefix] ?? (prefix ? fail2(`The prefix "${prefix}" is not declared`) : "");
9474
- const el = { name: colon < 0 ? qname : qname.slice(colon + 1), ns, attrs: attrsOut, children: [], text: "" };
9475
+ const el = { name: colon < 0 ? qname : qname.slice(colon + 1), ns, attrs: attrsOut, children: [], text: "", pos: i + bom };
9475
9476
  if (stack2.length) stack2[stack2.length - 1].children.push(el);
9476
9477
  else root = el;
9477
9478
  if (!selfClose) {
@@ -9521,15 +9522,15 @@ function soapBody(text2, src = {}) {
9521
9522
  DOCS.add(out);
9522
9523
  return out;
9523
9524
  }
9524
- function compileXPath(path2) {
9525
- path2 = String(path2 ?? "").trim();
9526
- const hit = pathCache.get(path2);
9525
+ function compileXPath(path3) {
9526
+ path3 = String(path3 ?? "").trim();
9527
+ const hit = pathCache.get(path3);
9527
9528
  if (hit) return hit;
9528
- if (path2.length > XPATH_MAX) throw new Error(`The XPath is longer than ${XPATH_MAX} characters`);
9529
- if (!path2) throw new Error("Give an XPath");
9529
+ if (path3.length > XPATH_MAX) throw new Error(`The XPath is longer than ${XPATH_MAX} characters`);
9530
+ if (!path3) throw new Error("Give an XPath");
9530
9531
  const parts = [];
9531
9532
  let cur = "", depth = 0, q3 = "";
9532
- for (const c of path2) {
9533
+ for (const c of path3) {
9533
9534
  if (q3) {
9534
9535
  if (c === q3) q3 = "";
9535
9536
  cur += c;
@@ -9549,7 +9550,7 @@ function compileXPath(path2) {
9549
9550
  }
9550
9551
  cur += c;
9551
9552
  }
9552
- if (q3 || depth) throw new Error(`The XPath "${path2}" has an unclosed quote or [`);
9553
+ if (q3 || depth) throw new Error(`The XPath "${path3}" has an unclosed quote or [`);
9553
9554
  parts.push(cur);
9554
9555
  const abs = parts[0] === "";
9555
9556
  if (abs) parts.shift();
@@ -9558,30 +9559,30 @@ function compileXPath(path2) {
9558
9559
  for (let k = 0; k < parts.length; k++) {
9559
9560
  const p = parts[k].trim();
9560
9561
  if (p === "") {
9561
- if (desc || k === parts.length - 1) throw new Error(`The XPath "${path2}" has an empty step`);
9562
+ if (desc || k === parts.length - 1) throw new Error(`The XPath "${path3}" has an empty step`);
9562
9563
  desc = true;
9563
9564
  continue;
9564
9565
  }
9565
- steps.push(step(p, desc, path2));
9566
+ steps.push(step(p, desc, path3));
9566
9567
  desc = false;
9567
9568
  }
9568
- if (!steps.length) throw new Error(`The XPath "${path2}" has no steps`);
9569
+ if (!steps.length) throw new Error(`The XPath "${path3}" has no steps`);
9569
9570
  steps.forEach((s, k) => {
9570
- if ((s.test.kind === "attr" || s.test.kind === "text") && k < steps.length - 1) throw new Error(`In "${path2}", @attribute and text() must come last`);
9571
+ if ((s.test.kind === "attr" || s.test.kind === "text") && k < steps.length - 1) throw new Error(`In "${path3}", @attribute and text() must come last`);
9571
9572
  });
9572
9573
  const out = { abs, steps };
9573
9574
  if (pathCache.size > 500) pathCache.clear();
9574
- pathCache.set(path2, out);
9575
+ pathCache.set(path3, out);
9575
9576
  return out;
9576
9577
  }
9577
- function step(p, desc, path2) {
9578
+ function step(p, desc, path3) {
9578
9579
  const b = p.indexOf("[");
9579
9580
  const head = (b < 0 ? p : p.slice(0, b)).trim();
9580
9581
  const preds = [];
9581
9582
  if (b >= 0) {
9582
9583
  let rest2 = p.slice(b);
9583
9584
  while (rest2) {
9584
- if (rest2[0] !== "[") throw new Error(`The XPath "${path2}": text after a predicate`);
9585
+ if (rest2[0] !== "[") throw new Error(`The XPath "${path3}": text after a predicate`);
9585
9586
  let k = 1, q3 = "";
9586
9587
  for (; k < rest2.length; k++) {
9587
9588
  const c = rest2[k];
@@ -9590,7 +9591,7 @@ function step(p, desc, path2) {
9590
9591
  } else if (c === "'" || c === '"') q3 = c;
9591
9592
  else if (c === "]") break;
9592
9593
  }
9593
- preds.push(pred(rest2.slice(1, k).trim(), path2));
9594
+ preds.push(pred(rest2.slice(1, k).trim(), path3));
9594
9595
  rest2 = rest2.slice(k + 1).trim();
9595
9596
  }
9596
9597
  }
@@ -9600,29 +9601,29 @@ function step(p, desc, path2) {
9600
9601
  else if (head === "text()") test = { kind: "text" };
9601
9602
  else if (head.startsWith("@")) {
9602
9603
  const m = NAME.exec(head.slice(1));
9603
- if (!m) throw new Error(`The XPath "${path2}": "${head}" is not an attribute name`);
9604
+ if (!m) throw new Error(`The XPath "${path3}": "${head}" is not an attribute name`);
9604
9605
  test = { kind: "attr", local: m[2] };
9605
9606
  } else {
9606
9607
  const m = NAME.exec(head);
9607
- if (!m) throw new Error(`The XPath "${path2}": "${head}" is not supported (names, *, ., .., @attr, text() and simple [predicates] are)`);
9608
+ if (!m) throw new Error(`The XPath "${path3}": "${head}" is not supported (names, *, ., .., @attr, text() and simple [predicates] are)`);
9608
9609
  test = { kind: "name", prefix: m[1] || "", local: m[2] };
9609
9610
  }
9610
- if (preds.length && test.kind !== "name") throw new Error(`The XPath "${path2}": a predicate goes on an element step`);
9611
+ if (preds.length && test.kind !== "name") throw new Error(`The XPath "${path3}": a predicate goes on an element step`);
9611
9612
  return { desc, test, preds };
9612
9613
  }
9613
- function pred(s, path2) {
9614
+ function pred(s, path3) {
9614
9615
  if (/^\d+$/.test(s)) {
9615
9616
  const n5 = Number(s);
9616
- if (n5 < 1) throw new Error(`The XPath "${path2}": positions start at 1`);
9617
+ if (n5 < 1) throw new Error(`The XPath "${path3}": positions start at 1`);
9617
9618
  return { pos: n5 };
9618
9619
  }
9619
9620
  if (s === "last()") return { last: true };
9620
9621
  const m = /^(@?[A-Za-z_][\w.:-]*|text\(\)|\.)\s*(?:(!?=)\s*(.+))?$/.exec(s);
9621
- if (!m) throw new Error(`The XPath "${path2}": the predicate [${s}] is not supported`);
9622
+ if (!m) throw new Error(`The XPath "${path3}": the predicate [${s}] is not supported`);
9622
9623
  let value = null;
9623
9624
  if (m[2]) {
9624
9625
  const l = LIT.exec(m[3].trim());
9625
- if (!l) throw new Error(`The XPath "${path2}": compare with a quoted value in [${s}]`);
9626
+ if (!l) throw new Error(`The XPath "${path3}": compare with a quoted value in [${s}]`);
9626
9627
  value = l[1] ?? l[2] ?? l[3];
9627
9628
  }
9628
9629
  const what = m[1];
@@ -9661,8 +9662,8 @@ function stringValue(el) {
9661
9662
  }
9662
9663
  return s.trim();
9663
9664
  }
9664
- function selectXml(doc, path2, context) {
9665
- const { abs, steps } = compileXPath(path2);
9665
+ function selectXml(doc, path3, context) {
9666
+ const { abs, steps } = compileXPath(path3);
9666
9667
  const root = doc.$xml;
9667
9668
  const DOC = { name: "#document", ns: "", attrs: {}, children: [root], text: "" };
9668
9669
  let cur = abs ? [DOC] : [context || root];
@@ -9731,8 +9732,8 @@ function filterPred(list2, p) {
9731
9732
  return p.op === "=" ? eq : vals.length > 0 && !eq;
9732
9733
  });
9733
9734
  }
9734
- function xmlValue(doc, el, path2) {
9735
- const r = selectXml(doc, path2, el)[0];
9735
+ function xmlValue(doc, el, path3) {
9736
+ const r = selectXml(doc, path3, el)[0];
9736
9737
  return r == null ? null : typeof r === "string" ? r : stringValue(r);
9737
9738
  }
9738
9739
  function xmlObject(el) {
@@ -9764,14 +9765,14 @@ function xmlRowPaths(doc) {
9764
9765
  const seen = /* @__PURE__ */ new Map();
9765
9766
  const stack2 = [{ e: doc.$xml, path: `/${doc.$xml.name}`, depth: 0 }];
9766
9767
  while (stack2.length) {
9767
- const { e: e2, path: path2, depth } = (
9768
+ const { e: e2, path: path3, depth } = (
9768
9769
  /** @type {any} */
9769
9770
  stack2.pop()
9770
9771
  );
9771
9772
  const counts = /* @__PURE__ */ new Map();
9772
9773
  for (const c of e2.children) counts.set(c.name, (counts.get(c.name) || 0) + 1);
9773
9774
  for (const c of e2.children) {
9774
- const p = `${path2}/${c.name}`;
9775
+ const p = `${path3}/${c.name}`;
9775
9776
  let s = seen.get(p);
9776
9777
  if (!s) seen.set(p, s = { rows: 0, repeats: false, fields: /* @__PURE__ */ new Set(), depth: depth + 1 });
9777
9778
  s.rows++;
@@ -9784,14 +9785,14 @@ function xmlRowPaths(doc) {
9784
9785
  if (c.children.length) stack2.push({ e: c, path: p, depth: depth + 1 });
9785
9786
  }
9786
9787
  }
9787
- return [...seen].filter(([, s]) => s.repeats).map(([path2, s]) => ({ path: path2, rows: s.rows, objects: true, fields: [...s.fields], spreads: s.depth }));
9788
+ return [...seen].filter(([, s]) => s.repeats).map(([path3, s]) => ({ path: path3, rows: s.rows, objects: true, fields: [...s.fields], spreads: s.depth }));
9788
9789
  }
9789
9790
  function bestXmlRows(doc) {
9790
9791
  const list2 = xmlRowPaths(doc).sort((a, b) => b.rows - a.rows || a.spreads - b.spreads);
9791
9792
  return list2[0] || null;
9792
9793
  }
9793
- function xmlRows(doc, path2) {
9794
- let p = path2 && path2 !== "$" ? path2 : bestXmlRows(doc)?.path;
9794
+ function xmlRows(doc, path3) {
9795
+ let p = path3 && path3 !== "$" ? path3 : bestXmlRows(doc)?.path;
9795
9796
  if (!p) return { els: [doc.$xml], rows: [xmlObject(doc.$xml)] };
9796
9797
  const found = selectXml(doc, p);
9797
9798
  const els = found.filter((x) => typeof x !== "string");
@@ -9914,23 +9915,23 @@ var init_odata = __esm({
9914
9915
  });
9915
9916
 
9916
9917
  // src/engine/data/index.js
9917
- function pathTokens(path2) {
9918
+ function pathTokens(path3) {
9918
9919
  const toks = [];
9919
9920
  const re = /\.([A-Za-z_$][\w$]*)|\[(\d+|\*)\]|\['([^']+)'\]|\["([^"]+)"\]/g;
9920
- const p = path2.startsWith("$") ? path2.slice(1) : "." + path2;
9921
+ const p = path3.startsWith("$") ? path3.slice(1) : "." + path3;
9921
9922
  let m, last = 0;
9922
9923
  while (m = re.exec(p)) {
9923
- if (m.index !== last) throw new Error(`Bad data path "${path2}"`);
9924
+ if (m.index !== last) throw new Error(`Bad data path "${path3}"`);
9924
9925
  toks.push(m[1] ?? m[3] ?? m[4] ?? (m[2] === "*" ? "*" : Number(m[2])));
9925
9926
  last = re.lastIndex;
9926
9927
  }
9927
- if (last !== p.length) throw new Error(`Bad data path "${path2}"`);
9928
+ if (last !== p.length) throw new Error(`Bad data path "${path3}"`);
9928
9929
  return toks;
9929
9930
  }
9930
- function jsonPath(obj, path2) {
9931
- if (!path2 || path2 === "$") return obj;
9931
+ function jsonPath(obj, path3) {
9932
+ if (!path3 || path3 === "$") return obj;
9932
9933
  let cur = [obj], spread = false;
9933
- for (const t of pathTokens(path2)) {
9934
+ for (const t of pathTokens(path3)) {
9934
9935
  const nxt = [];
9935
9936
  for (const c of cur) {
9936
9937
  if (c == null) continue;
@@ -9943,10 +9944,10 @@ function jsonPath(obj, path2) {
9943
9944
  }
9944
9945
  return spread ? cur : cur[0];
9945
9946
  }
9946
- function jsonPathRows(obj, path2) {
9947
- if (!path2 || path2 === "$") return { rows: obj, parents: null };
9947
+ function jsonPathRows(obj, path3) {
9948
+ if (!path3 || path3 === "$") return { rows: obj, parents: null };
9948
9949
  let cur = [obj], hold = [null], par = [null], spread = false;
9949
- for (const t of pathTokens(path2)) {
9950
+ for (const t of pathTokens(path3)) {
9950
9951
  const nv = [], nh = [], np = [];
9951
9952
  for (let i = 0; i < cur.length; i++) {
9952
9953
  const c = cur[i];
@@ -10424,8 +10425,8 @@ function buildDataSets(def, sources, baseCtx) {
10424
10425
  const declared = (ds.fields || []).filter((fd) => !fd.expr && !fd.path);
10425
10426
  const hasFields = Object.values(asObject).some((v) => v != null && typeof v !== "object");
10426
10427
  if (inner2.length && !hasFields && !declared.some((fd) => Object.hasOwn(asObject, fd.name))) {
10427
- const at2 = ds.path && ds.path !== "$" ? ds.path : `$.${ds.source}`;
10428
- baseCtx.warn?.(`Data set "${ds.name}": ${at2} is an object, not a list of rows, so it is one row; expected an array of rows (did you mean ${at2}.${inner2[0]}?)`);
10428
+ const at3 = ds.path && ds.path !== "$" ? ds.path : `$.${ds.source}`;
10429
+ baseCtx.warn?.(`Data set "${ds.name}": ${at3} is an object, not a list of rows, so it is one row; expected an array of rows (did you mean ${at3}.${inner2[0]}?)`);
10429
10430
  }
10430
10431
  }
10431
10432
  const keys = /* @__PURE__ */ new Set();
@@ -11315,6 +11316,8 @@ function newContext() {
11315
11316
  /** @type {Set<string>} part libraries referenced (report ids) */
11316
11317
  libraries: /* @__PURE__ */ new Set(),
11317
11318
  cells: 0,
11319
+ /** @type {any[]} every item tracked, with what happened to it (see items() in importRdlx's result) */
11320
+ items: [],
11318
11321
  warn(msg) {
11319
11322
  if (!cx.warnings.includes(msg)) cx.warnings.push(msg);
11320
11323
  }
@@ -11324,24 +11327,35 @@ function newContext() {
11324
11327
  function track(cx, ar, label) {
11325
11328
  cx.stats.items++;
11326
11329
  const name = String(ar?.Name || label || ar?.Type || "item");
11330
+ const say = (kind, msg) => {
11331
+ if (!t.notes.some((n5) => n5.message === msg)) t.notes.push({ kind, message: msg });
11332
+ cx.warn(`${name}: ${msg}`);
11333
+ };
11327
11334
  const t = {
11328
11335
  name,
11329
11336
  state: "mapped",
11337
+ pos: typeof ar?.__pos === "number" ? ar.__pos : void 0,
11338
+ /** @type {{ kind: string, message: string }[]} */
11339
+ notes: [],
11340
+ /** @type {string[]} expressions that could not be translated */
11341
+ exprs: [],
11330
11342
  /** in the report, with something lost or changed */
11331
11343
  approx(msg) {
11332
11344
  if (t.state === "mapped") t.state = "approximated";
11333
- cx.warn(`${name}: ${msg}`);
11345
+ say("approximated", msg);
11334
11346
  },
11335
11347
  /** for information only */
11336
11348
  note(msg) {
11337
- cx.warn(`${name}: ${msg}`);
11349
+ say("info", msg);
11338
11350
  },
11339
11351
  /** not in the report */
11340
11352
  drop(msg) {
11341
11353
  t.state = "dropped";
11342
- cx.warn(`${name}: ${msg}`);
11354
+ say("dropped", msg);
11343
11355
  }
11344
11356
  };
11357
+ cx.items.push(t);
11358
+ for (const x of Array.isArray(ar?.__exprs) ? ar.__exprs : []) if (typeof x === "string" && !t.exprs.includes(x)) t.exprs.push(x);
11345
11359
  for (const n5 of Array.isArray(ar?.__notes) ? ar.__notes : []) t.approx(n5);
11346
11360
  for (const n5 of Array.isArray(ar?.__info) ? ar.__info : []) t.note(n5);
11347
11361
  return t;
@@ -11359,6 +11373,7 @@ function uniq(cx, base, generated = false) {
11359
11373
  }
11360
11374
  function ex(cx, t, v, ctx, opt = {}) {
11361
11375
  const r = translateExpression(v, { text: opt.text, fields: opt.fields, lit: opt.lit, region: ctx.region, scopes: cx.scopes, runScopes: cx.runScopes });
11376
+ if (!r.ok && typeof v === "string" && !t.exprs.includes(v)) t.exprs.push(v);
11362
11377
  if (!r.ok) t.approx(`${r.notes.join("; ")}; ${opt.text ? "the expression is shown as text" : `${opt.what || "that setting"} is left out`}.`);
11363
11378
  else for (const n5 of r.notes) t.approx(`${n5}.`);
11364
11379
  return r.value;
@@ -11560,12 +11575,13 @@ function convertItem(ar, cx, ctx) {
11560
11575
  dropInside(ar, cx);
11561
11576
  return finish(cx, t, null);
11562
11577
  }
11563
- const snap = { ...cx.stats };
11578
+ const snap = { ...cx.stats }, tracked = cx.items.length;
11564
11579
  try {
11565
11580
  return conv(ar, cx, ctx);
11566
11581
  } catch (e2) {
11567
11582
  if (e2 instanceof ImportBudgetError) throw e2;
11568
11583
  Object.assign(cx.stats, snap);
11584
+ cx.items.length = tracked;
11569
11585
  const t = track(cx, ar);
11570
11586
  t.drop(`it could not be converted (${e2 instanceof Error ? e2.message : e2}), so it was left out.`);
11571
11587
  dropInside(ar, cx);
@@ -11574,25 +11590,25 @@ function convertItem(ar, cx, ctx) {
11574
11590
  }
11575
11591
  function dropInside(ar, cx) {
11576
11592
  let n5 = 0;
11577
- const walk = (o) => {
11593
+ const walk2 = (o) => {
11578
11594
  if (!o || typeof o !== "object") return;
11579
11595
  if (Array.isArray(o)) {
11580
- o.forEach(walk);
11596
+ o.forEach(walk2);
11581
11597
  return;
11582
11598
  }
11583
11599
  for (const [k, v] of Object.entries(o)) {
11584
11600
  if (k === "ReportItems" && Array.isArray(v)) {
11585
11601
  for (const x of v) if (x && typeof x === "object" && x.Type) {
11586
11602
  n5++;
11587
- walk(x);
11603
+ walk2(x);
11588
11604
  }
11589
11605
  } else if (k === "Item" && v && typeof v === "object" && v.Type) {
11590
11606
  n5++;
11591
- walk(v);
11592
- } else if (v && typeof v === "object") walk(v);
11607
+ walk2(v);
11608
+ } else if (v && typeof v === "object") walk2(v);
11593
11609
  }
11594
11610
  };
11595
- walk(ar);
11611
+ walk2(ar);
11596
11612
  cx.stats.items += n5;
11597
11613
  cx.stats.dropped += n5;
11598
11614
  }
@@ -12184,14 +12200,14 @@ function tablix(ar, cx, ctx) {
12184
12200
  function tablixItems(ar) {
12185
12201
  const out = [];
12186
12202
  for (const row of ar.Corner || []) for (const c of row || []) if (c?.Item) out.push(c.Item);
12187
- const walk = (ms) => {
12203
+ const walk2 = (ms) => {
12188
12204
  for (const m of ms || []) {
12189
12205
  if (m?.Header?.Item) out.push(m.Header.Item);
12190
- walk(m?.Children);
12206
+ walk2(m?.Children);
12191
12207
  }
12192
12208
  };
12193
- walk(ar.ColumnHierarchy?.Members);
12194
- walk(ar.RowHierarchy?.Members);
12209
+ walk2(ar.ColumnHierarchy?.Members);
12210
+ walk2(ar.RowHierarchy?.Members);
12195
12211
  for (const r of ar.Body?.Rows || []) for (const c of r?.Cells || []) if (c?.Item) out.push(c.Item);
12196
12212
  return out;
12197
12213
  }
@@ -12232,13 +12248,13 @@ function tablixTable(ar, cx, ctx) {
12232
12248
  }
12233
12249
  const groups = [], leaves = [];
12234
12250
  let detailVis, problem = null;
12235
- const walkRows = (ms, level, path2, depth, hint) => {
12251
+ const walkRows = (ms, level, path3, depth, hint) => {
12236
12252
  const localDyn = ms.some((m) => m.Group);
12237
12253
  if (ms.filter((m) => m.Group).length > 1) problem = "two row groups sit side by side";
12238
12254
  let seen = false;
12239
12255
  for (const m of ms) {
12240
12256
  const span = m.Header ? Number(m.Header.LevelCount) || 1 : 0;
12241
- const p = [...path2, { m, level, span }];
12257
+ const p = [...path3, { m, level, span }];
12242
12258
  const kids = members({ Members: m.Children });
12243
12259
  if (isDyn(m)) {
12244
12260
  if (depth !== groups.length) problem = "its row groups are not nested in one chain";
@@ -12365,15 +12381,15 @@ function tablixMatrix(ar, cx, ctx) {
12365
12381
  const leafIndex = (ms) => {
12366
12382
  const map = /* @__PURE__ */ new Map();
12367
12383
  let n5 = 0;
12368
- const walk = (list2) => {
12384
+ const walk2 = (list2) => {
12369
12385
  for (const m of list2) {
12370
12386
  map.set(m, m.BodyIndex ?? n5);
12371
12387
  const kids = members({ Members: m.Children });
12372
- if (kids.length) walk(kids);
12388
+ if (kids.length) walk2(kids);
12373
12389
  else n5++;
12374
12390
  }
12375
12391
  };
12376
- walk(ms);
12392
+ walk2(ms);
12377
12393
  return map;
12378
12394
  };
12379
12395
  const rIdx = leafIndex(rowMs), cIdx = leafIndex(colMs);
@@ -12506,9 +12522,9 @@ function tablixMatrix(ar, cx, ctx) {
12506
12522
  if (rhs && Object.keys(textStyle(rhs, cx, t, rctx)).length) it.style = { padding: textStyle(rhs, cx, t, rctx).padding ?? 0 };
12507
12523
  if (isFalse(ar.RepeatColumnHeaders)) it.repeatHeader = false;
12508
12524
  regionData(ar, it, cx, t, rctx, ctx);
12509
- for (const inside of tablixItems(ar)) {
12510
- const ti = track(cx, inside);
12511
- if (!used.has(inside) && inside.Value != null && String(inside.Value).trim() !== "") ti.approx("this cell is not shown: a ReportWright matrix shows group headers, values and totals.");
12525
+ for (const inside2 of tablixItems(ar)) {
12526
+ const ti = track(cx, inside2);
12527
+ if (!used.has(inside2) && inside2.Value != null && String(inside2.Value).trim() !== "") ti.approx("this cell is not shown: a ReportWright matrix shows group headers, values and totals.");
12512
12528
  finish(cx, ti, null);
12513
12529
  }
12514
12530
  return finish(cx, t, it);
@@ -13375,11 +13391,11 @@ function fixedPage(fp, cx, info) {
13375
13391
  }
13376
13392
  function collectScopes(ar, cx) {
13377
13393
  const seen = /* @__PURE__ */ new Set();
13378
- const walk = (o) => {
13394
+ const walk2 = (o) => {
13379
13395
  if (!o || typeof o !== "object" || seen.has(o)) return;
13380
13396
  seen.add(o);
13381
13397
  if (Array.isArray(o)) {
13382
- o.forEach(walk);
13398
+ o.forEach(walk2);
13383
13399
  return;
13384
13400
  }
13385
13401
  const type = String(o.Type || "").toLowerCase();
@@ -13412,9 +13428,9 @@ function collectScopes(ar, cx) {
13412
13428
  if (type.includes("chart")) {
13413
13429
  for (const p of o.Plots || []) for (const g of [...p?.CategoryGroupings || [], ...p?.SeriesGroupings || []]) if (g?.Grouping?.Name) cx.scopes.set(g.Grouping.Name, null);
13414
13430
  }
13415
- for (const v of Object.values(o)) if (v && typeof v === "object") walk(v);
13431
+ for (const v of Object.values(o)) if (v && typeof v === "object") walk2(v);
13416
13432
  };
13417
- walk(ar);
13433
+ walk2(ar);
13418
13434
  for (const d of Array.isArray(ar.DataSets) ? ar.DataSets : []) if (d?.Name) cx.scopes.set(d.Name, d.Name);
13419
13435
  }
13420
13436
  function convertReport(ar, cx, opts) {
@@ -13477,7 +13493,7 @@ function convertReport(ar, cx, opts) {
13477
13493
  if (cx.columns) body.columns = cx.columns;
13478
13494
  if (more.length) body.name = sec0?.Name || "Section1";
13479
13495
  return {
13480
- $schema: "pagewright/report@1",
13496
+ $schema: "reportwright/report@1",
13481
13497
  name,
13482
13498
  locale: lang,
13483
13499
  ...currencyOf(lang) ? { currency: currencyOf(lang) } : {},
@@ -13518,15 +13534,15 @@ function importRdlx(input, opts = {}) {
13518
13534
  } catch (e2) {
13519
13535
  if (e2 instanceof ImportBudgetError) {
13520
13536
  const error = `The report is too large to import: ${e2.message}`;
13521
- return { definition: convertReport({}, newContext(), opts), warnings: [`${error}.`], stats: { items: 0, mapped: 0, approximated: 0, dropped: 0 }, error };
13537
+ return { definition: convertReport({}, newContext(), opts), warnings: [`${error}.`], stats: { items: 0, mapped: 0, approximated: 0, dropped: 0 }, items: [], error };
13522
13538
  }
13523
13539
  cx.warn(`The import stopped early (${e2 instanceof Error ? e2.message : e2}), so parts of the report are missing.`);
13524
13540
  definition = convertReport({}, newContext(), opts);
13525
13541
  }
13526
- return { definition, warnings: cx.warnings, stats: cx.stats };
13542
+ return { definition, warnings: cx.warnings, stats: cx.stats, items: importedItems(cx.items) };
13527
13543
  }
13528
13544
  var UNIT2, r25, NAMED3, MONO2, weightOf, ALIGN, VALIGN, LITS, safeName, Untranslatable, no, bad, CONT, NUM, NAME2, at, MAX_RESULT, VB_OPS, BIN2, q2, wrap, atom, fn, ROOT, cap, GLOBALS, INTERVAL, DATEFORMAT, AGG2, SAME, CONVERT, MATH, VB_DAYS, escText, isExpr, inner, AGG_RE, ImportBudgetError, OUTPUT_LIMITS, hasDeco, CONVERTERS, TARGETS, bare, isTrue, isFalse, stripHtml, SYMBOLOGY, missing, FILTER_OPS,
13529
- joinKeys, CELL_ITEMS, TEXT_CELL, isDyn, anyDyn, members, shiftY, CHART_TYPES2, PALETTES2, SERIES_KIND, SQL_PROVIDERS, CONN_KEYS, getKey, unescapeTpl, TYPE_HINT, PTYPE, coerceLit, PAGE_NO;
13545
+ joinKeys, CELL_ITEMS, TEXT_CELL, isDyn, anyDyn, members, shiftY, CHART_TYPES2, PALETTES2, SERIES_KIND, SQL_PROVIDERS, CONN_KEYS, getKey, unescapeTpl, TYPE_HINT, PTYPE, coerceLit, PAGE_NO, importedItems, rewordItems;
13530
13546
  var init_rdlx = __esm({
13531
13547
  "src/importers/rdlx.js"() {
13532
13548
  init_units();
@@ -13536,13 +13552,13 @@ var init_rdlx = __esm({
13536
13552
  init_data();
13537
13553
  UNIT2 = { in: 72, cm: 72 / 2.54, mm: 72 / 25.4, pt: 1, pc: 12, px: 0.75 };
13538
13554
  r25 = (n5) => Math.round(n5 * 100) / 100;
13539
- NAMED3 = Object.fromEntries("aliceblue:f0f8ff,antiquewhite:faebd7,aqua:00ffff,aquamarine:7fffd4,azure:f0ffff,beige:f5f5dc,bisque:ffe4c4,black:000000,blanchedalmond:ffebcd,blue:0000ff,blueviolet:8a2be2,brown:a52a2a,burlywood:deb887,cadetblue:5f9ea0,chartreuse:7fff00,chocolate:d2691e,coral:ff7f50,cornflowerblue:6495ed,cornsilk:fff8dc,crimson:dc143c,cyan:00ffff,darkblue:00008b,darkcyan:008b8b,dar\
13540
- kgoldenrod:b8860b,darkgray:a9a9a9,darkgreen:006400,darkgrey:a9a9a9,darkkhaki:bdb76b,darkmagenta:8b008b,darkolivegreen:556b2f,darkorange:ff8c00,darkorchid:9932cc,darkred:8b0000,darksalmon:e9967a,darkseagreen:8fbc8f,darkslateblue:483d8b,darkslategray:2f4f4f,darkslategrey:2f4f4f,darkturquoise:00ced1,darkviolet:9400d3,deeppink:ff1493,deepskyblue:00bfff,dimgray:696969,dimgrey:696969,dodgerblue:1e90ff,f\
13541
- irebrick:b22222,floralwhite:fffaf0,forestgreen:228b22,fuchsia:ff00ff,gainsboro:dcdcdc,ghostwhite:f8f8ff,gold:ffd700,goldenrod:daa520,gray:808080,green:008000,greenyellow:adff2f,grey:808080,honeydew:f0fff0,hotpink:ff69b4,indianred:cd5c5c,indigo:4b0082,ivory:fffff0,khaki:f0e68c,lavender:e6e6fa,lavenderblush:fff0f5,lawngreen:7cfc00,lemonchiffon:fffacd,lightblue:add8e6,lightcoral:f08080,lightcyan:e0ff\
13542
- ff,lightgoldenrodyellow:fafad2,lightgray:d3d3d3,lightgreen:90ee90,lightgrey:d3d3d3,lightpink:ffb6c1,lightsalmon:ffa07a,lightseagreen:20b2aa,lightskyblue:87cefa,lightslategray:778899,lightslategrey:778899,lightsteelblue:b0c4de,lightyellow:ffffe0,lime:00ff00,limegreen:32cd32,linen:faf0e6,magenta:ff00ff,maroon:800000,mediumaquamarine:66cdaa,mediumblue:0000cd,mediumorchid:ba55d3,mediumpurple:9370db,me\
13543
- diumseagreen:3cb371,mediumslateblue:7b68ee,mediumspringgreen:00fa9a,mediumturquoise:48d1cc,mediumvioletred:c71585,midnightblue:191970,mintcream:f5fffa,mistyrose:ffe4e1,moccasin:ffe4b5,navajowhite:ffdead,navy:000080,oldlace:fdf5e6,olive:808000,olivedrab:6b8e23,orange:ffa500,orangered:ff4500,orchid:da70d6,palegoldenrod:eee8aa,palegreen:98fb98,paleturquoise:afeeee,palevioletred:db7093,papayawhip:ffef\
13544
- d5,peachpuff:ffdab9,peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple:800080,rebeccapurple:663399,red:ff0000,rosybrown:bc8f8f,royalblue:4169e1,saddlebrown:8b4513,salmon:fa8072,sandybrown:f4a460,seagreen:2e8b57,seashell:fff5ee,sienna:a0522d,silver:c0c0c0,skyblue:87ceeb,slateblue:6a5acd,slategray:708090,slategrey:708090,snow:fffafa,springgreen:00ff7f,steelblue:4682b4,tan:d2b48c,teal:00808\
13545
- 0,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32".split(",").map((p) => p.split(":")));
13555
+ NAMED3 = Object.fromEntries(("aliceblue:f0f8ff,antiquewhite:faebd7,aqua:00ffff,aquamarine:7fffd4,azure:f0ffff,beige:f5f5dc,bisque:ffe4c4,black:000000,blanchedalmond:ffebcd,blue:0000ff,blueviolet:8a2be2,brown:a52a2a,burlywood:deb887,cadetblue:5f9ea0,chartreuse:7fff00,chocolate:d2691e,coral:ff7f50,cornflowerblue:6495ed,cornsilk:fff8dc,crimson:dc143c,cyan:00ffff,darkblue:00008b,darkcyan:008b8b,dar"+
13556
+ "kgoldenrod:b8860b,darkgray:a9a9a9,darkgreen:006400,darkgrey:a9a9a9,darkkhaki:bdb76b,darkmagenta:8b008b,darkolivegreen:556b2f,darkorange:ff8c00,darkorchid:9932cc,darkred:8b0000,darksalmon:e9967a,darkseagreen:8fbc8f,darkslateblue:483d8b,darkslategray:2f4f4f,darkslategrey:2f4f4f,darkturquoise:00ced1,darkviolet:9400d3,deeppink:ff1493,deepskyblue:00bfff,dimgray:696969,dimgrey:696969,dodgerblue:1e90ff,f"+
13557
+ "irebrick:b22222,floralwhite:fffaf0,forestgreen:228b22,fuchsia:ff00ff,gainsboro:dcdcdc,ghostwhite:f8f8ff,gold:ffd700,goldenrod:daa520,gray:808080,green:008000,greenyellow:adff2f,grey:808080,honeydew:f0fff0,hotpink:ff69b4,indianred:cd5c5c,indigo:4b0082,ivory:fffff0,khaki:f0e68c,lavender:e6e6fa,lavenderblush:fff0f5,lawngreen:7cfc00,lemonchiffon:fffacd,lightblue:add8e6,lightcoral:f08080,lightcyan:e0ff"+
13558
+ "ff,lightgoldenrodyellow:fafad2,lightgray:d3d3d3,lightgreen:90ee90,lightgrey:d3d3d3,lightpink:ffb6c1,lightsalmon:ffa07a,lightseagreen:20b2aa,lightskyblue:87cefa,lightslategray:778899,lightslategrey:778899,lightsteelblue:b0c4de,lightyellow:ffffe0,lime:00ff00,limegreen:32cd32,linen:faf0e6,magenta:ff00ff,maroon:800000,mediumaquamarine:66cdaa,mediumblue:0000cd,mediumorchid:ba55d3,mediumpurple:9370db,me"+
13559
+ "diumseagreen:3cb371,mediumslateblue:7b68ee,mediumspringgreen:00fa9a,mediumturquoise:48d1cc,mediumvioletred:c71585,midnightblue:191970,mintcream:f5fffa,mistyrose:ffe4e1,moccasin:ffe4b5,navajowhite:ffdead,navy:000080,oldlace:fdf5e6,olive:808000,olivedrab:6b8e23,orange:ffa500,orangered:ff4500,orchid:da70d6,palegoldenrod:eee8aa,palegreen:98fb98,paleturquoise:afeeee,palevioletred:db7093,papayawhip:ffef"+
13560
+ "d5,peachpuff:ffdab9,peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple:800080,rebeccapurple:663399,red:ff0000,rosybrown:bc8f8f,royalblue:4169e1,saddlebrown:8b4513,salmon:fa8072,sandybrown:f4a460,seagreen:2e8b57,seashell:fff5ee,sienna:a0522d,silver:c0c0c0,skyblue:87ceeb,slateblue:6a5acd,slategray:708090,slategrey:708090,snow:fffafa,springgreen:00ff7f,steelblue:4682b4,tan:d2b48c,teal:00808"+
13561
+ "0,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32").split(",").map((p) => p.split(":")));
13546
13562
  MONO2 = /mono|courier|consol|menlo|monaco|lucida console|typewriter/i;
13547
13563
  weightOf = (w) => {
13548
13564
  const s = String(w).trim().toLowerCase();
@@ -13914,6 +13930,8 @@ d5,peachpuff:ffdab9,peru:cd853f,pink:ffc0cb,plum:dda0dd,powderblue:b0e0e6,purple
13914
13930
  return v;
13915
13931
  };
13916
13932
  PAGE_NO = /Globals!\s*(PageNumber|TotalPages|PageNumberInSection|TotalPagesInSection|OverallPageNumber|OverallTotalPages)\b/i;
13933
+ importedItems = (items) => items.filter((t) => t.state !== "mapped" || t.notes.length || t.exprs.length).map((t) => ({ name: t.name, state: t.state, ...t.pos != null ? { pos: t.pos } : {}, notes: t.notes, exprs: t.exprs }));
13934
+ rewordItems = (items, f4) => (items || []).map((i) => ({ ...i, notes: i.notes.map((n5) => ({ ...n5, message: f4(n5.message) })) }));
13917
13935
  }
13918
13936
  });
13919
13937
 
@@ -13935,7 +13953,7 @@ function importRdl(input, opts = {}) {
13935
13953
  const notes = [];
13936
13954
  let ar;
13937
13955
  try {
13938
- ar = toRdlx(root, notes, m ? Number(m[1]) : 2016);
13956
+ ar = toRdlx(root, notes, m ? Number(m[1]) : 2016, opts.resolve);
13939
13957
  } catch (e2) {
13940
13958
  if (e2 instanceof ImportBudgetError) {
13941
13959
  const error = `The report is too large to import: ${e2.message}`;
@@ -13949,10 +13967,12 @@ function importRdl(input, opts = {}) {
13949
13967
  const def = r.definition;
13950
13968
  for (const p of def.parameters || []) if (ar.__hidden?.has(p.name)) p.hidden = true;
13951
13969
  if (ar.__code) def.customCode = ar.__code;
13952
- const warnings = [...notes, ...r.warnings.filter((w) => !/is hidden in ActiveReports; ReportWright shows it/.test(w))].map((w) => w.replace(/ActiveReports/g, "SSRS"));
13953
- return { definition: def, warnings: [...new Set(warnings)], stats: r.stats };
13970
+ const hiddenNote = /is hidden in ActiveReports; ReportWright shows it/;
13971
+ const warnings = [...notes, ...r.warnings.filter((w) => !hiddenNote.test(w))].map((w) => w.replace(/ActiveReports/g, "SSRS"));
13972
+ const items = rewordItems(r.items.map((i) => ({ ...i, notes: i.notes.filter((n5) => !hiddenNote.test(n5.message)) })), (w) => w.replace(/ActiveReports/g, "SSRS"));
13973
+ return { definition: def, warnings: [...new Set(warnings)], stats: r.stats, items };
13954
13974
  }
13955
- function toRdlx(root, notes, year) {
13975
+ function toRdlx(root, notes, year, resolve) {
13956
13976
  const NS3 = root.ns;
13957
13977
  const kids = (e2, name) => e2 ? e2.children.filter((c) => c.ns === NS3 && (name == null || c.name === name)) : [];
13958
13978
  const kid = (e2, name) => e2?.children.find((c) => c.ns === NS3 && c.name === name);
@@ -13961,7 +13981,7 @@ function toRdlx(root, notes, year) {
13961
13981
  return c ? c.attrs.nil === "true" ? null : c.text : void 0;
13962
13982
  };
13963
13983
  const val = (e2, name) => fix(raw(e2, name));
13964
- const path2 = (e2, ...names) => names.reduce((x, n5) => kid(x, n5), e2);
13984
+ const path3 = (e2, ...names) => names.reduce((x, n5) => kid(x, n5), e2);
13965
13985
  const list2 = (e2, outer, inner2) => kids(kid(e2, outer), inner2);
13966
13986
  const variables = /* @__PURE__ */ new Map();
13967
13987
  const boxes = /* @__PURE__ */ new Map();
@@ -14119,6 +14139,7 @@ function toRdlx(root, notes, year) {
14119
14139
  Name: e2.attrs.Name,
14120
14140
  __notes: itemNotes,
14121
14141
  __info: itemInfo,
14142
+ __pos: e2.pos,
14122
14143
  Left: raw(e2, "Left"),
14123
14144
  Top: raw(e2, "Top"),
14124
14145
  Width: raw(e2, "Width"),
@@ -14544,7 +14565,7 @@ function toRdlx(root, notes, year) {
14544
14565
  const vals = kid(dp, "ChartDataPointValues");
14545
14566
  const srcs = pt.values.map((n5) => val(vals, n5)).filter((v) => v != null && v !== "");
14546
14567
  if (!srcs.length) return;
14547
- const caption = val(path2(s, "ChartItemInLegend"), "LegendText") || statics[i] && val(statics[i], "Label") || s.attrs.Name;
14568
+ const caption = val(path3(s, "ChartItemInLegend"), "LegendText") || statics[i] && val(statics[i], "Label") || s.attrs.Name;
14548
14569
  p.Encodings.Values.push({ Field: { Value: srcs }, Caption: isExpr2(caption) ? s.attrs.Name : caption });
14549
14570
  const x = val(vals, "X");
14550
14571
  if (x && !p.x) p.x = x;
@@ -14654,23 +14675,52 @@ function toRdlx(root, notes, year) {
14654
14675
  const r = e2.name === "Tablix" || e2.name === "Chart" ? e2.attrs.Name || reg : reg;
14655
14676
  for (const c of e2.children) prepass(c, r);
14656
14677
  })(root, null);
14678
+ function sharedSource(ref2) {
14679
+ let text2;
14680
+ try {
14681
+ text2 = resolve?.("datasource", ref2);
14682
+ } catch {
14683
+ text2 = null;
14684
+ }
14685
+ if (typeof text2 !== "string") return null;
14686
+ let doc;
14687
+ try {
14688
+ doc = parseXml(text2);
14689
+ } catch (e2) {
14690
+ notes.push(`The shared data source "${ref2}" could not be read (${e2 instanceof Error ? e2.message : e2}); it is treated as SQL Server.`);
14691
+ return null;
14692
+ }
14693
+ const sub = (e2, n5) => e2?.children.find((c) => c.name === n5);
14694
+ const props = doc.name === "RptDataSource" ? sub(doc, "ConnectionProperties") : doc.name === "DataSourceDefinition" ? doc : null;
14695
+ if (!props) {
14696
+ notes.push(`The shared data source "${ref2}" is not an SSRS data source (its root is <${doc.name}>); it is treated as SQL Server.`);
14697
+ return null;
14698
+ }
14699
+ return { provider: (sub(props, "Extension")?.text || "SQL").trim(), connect: (sub(props, "ConnectString")?.text ?? "").trim() };
14700
+ }
14657
14701
  const TYPE_OF = (t) => /datetime|date$/i.test(t) ? "date" : /int|decimal|double|single|byte|float/i.test(t) ? "number" : /boolean/i.test(t) ? "boolean" : null;
14658
14702
  const DataSources = list2(root, "DataSources", "DataSource").map((d) => {
14659
14703
  const name = d.attrs.Name;
14660
14704
  const cp = kid(d, "ConnectionProperties");
14661
14705
  let provider = raw(cp, "DataProvider") || "";
14706
+ let connect = raw(cp, "ConnectString") ?? "";
14662
14707
  if (!cp && kid(d, "DataSourceReference")) {
14663
- provider = "SQL";
14664
- notes.push(`Data source "${name}" is the shared data source "${raw(d, "DataSourceReference")}", whose connection is not in the file; it is treated as SQL Server.`);
14708
+ const ref2 = raw(d, "DataSourceReference") ?? "";
14709
+ const shared = sharedSource(ref2);
14710
+ if (shared) ({ provider, connect } = shared);
14711
+ else {
14712
+ provider = "SQL";
14713
+ notes.push(`Data source "${name}" is the shared data source "${ref2}", whose connection is not in the file; it is treated as SQL Server.`);
14714
+ }
14665
14715
  }
14666
14716
  if (/^(OLEDB-MD|ESSBASE|SAPBW|SQLAS|HYPERION)/i.test(provider)) provider = `${provider} (MDX)`;
14667
- return { Name: name, ConnectionProperties: { DataProvider: provider, ConnectString: raw(cp, "ConnectString") ?? "" } };
14717
+ return { Name: name, ConnectionProperties: { DataProvider: provider, ConnectString: connect } };
14668
14718
  });
14669
14719
  const entered = /* @__PURE__ */ new Map();
14670
14720
  const providers = new Map(DataSources.map((d) => [d.Name, String(d.ConnectionProperties.DataProvider).toUpperCase()]));
14671
14721
  const DataSets = list2(root, "DataSets", "DataSet").map((d) => {
14672
14722
  const q3 = kid(d, "Query");
14673
- const shared = path2(d, "SharedDataSet", "SharedDataSetReference");
14723
+ const shared = path3(d, "SharedDataSet", "SharedDataSetReference");
14674
14724
  if (shared) notes.push(`Data set "${d.attrs.Name}" is the shared data set "${shared.text}", which is not in the file; set its source and query.`);
14675
14725
  const types = /* @__PURE__ */ new Map();
14676
14726
  const Fields = list2(d, "Fields", "Field").map((f4) => {
@@ -15296,9 +15346,9 @@ function dotted(n5) {
15296
15346
  return null;
15297
15347
  }
15298
15348
  function emMember2(n5, env, d) {
15299
- const path2 = dotted(n5);
15300
- if (path2) {
15301
- const short = path2.replace(/^java\.(lang|math|util)\./, "");
15349
+ const path3 = dotted(n5);
15350
+ if (path3) {
15351
+ const short = path3.replace(/^java\.(lang|math|util)\./, "");
15302
15352
  if (short === "Boolean.TRUE") return A("True", "bool");
15303
15353
  if (short === "Boolean.FALSE") return A("False", "bool");
15304
15354
  if (short === "Math.PI") return A("Math.PI", "num");
@@ -15308,7 +15358,7 @@ function emMember2(n5, env, d) {
15308
15358
  if (/^(RoundingMode|BigDecimal)\.[A-Z_]+$/.test(short)) return A(vbStr(short.split(".")[1]), "str");
15309
15359
  }
15310
15360
  if (n5.name === "length" && n5.obj) throw new Untranslatable2("an array length");
15311
- throw new Untranslatable2(`the field ${path2 || `.${n5.name}`}`);
15361
+ throw new Untranslatable2(`the field ${path3 || `.${n5.name}`}`);
15312
15362
  }
15313
15363
  function emNew(n5, env, d) {
15314
15364
  const name = n5.name.replace(/^java\.(lang|math|util|sql)\./, "");
@@ -15338,9 +15388,9 @@ function emCall2(n5, env, d) {
15338
15388
  }
15339
15389
  throw new Untranslatable2(`the function ${n5.name}()`);
15340
15390
  }
15341
- const path2 = dotted(n5.obj);
15342
- if (path2 && !(n5.obj.k === "id" && /^[a-z]/.test(n5.obj.name) && !/^java$/.test(n5.obj.name))) {
15343
- const cls = path2.replace(/^java\.(lang|math|util|sql)\./, "");
15391
+ const path3 = dotted(n5.obj);
15392
+ if (path3 && !(n5.obj.k === "id" && /^[a-z]/.test(n5.obj.name) && !/^java$/.test(n5.obj.name))) {
15393
+ const cls = path3.replace(/^java\.(lang|math|util|sql)\./, "");
15344
15394
  const a2 = args();
15345
15395
  const m = n5.name;
15346
15396
  if (cls === "String" && m === "valueOf" && a2.length === 1) return jstr(a2[0]);
@@ -15521,7 +15571,7 @@ function importJrxml(input, opts = {}) {
15521
15571
  const charts = /* @__PURE__ */ new Map();
15522
15572
  let ar;
15523
15573
  try {
15524
- ar = toRdlx2(root, notes, charts, opts.name || root.attrs.name);
15574
+ ar = toRdlx2(root, notes, charts, opts.name || root.attrs.name, opts.resolve);
15525
15575
  } catch (e2) {
15526
15576
  if (e2 instanceof ImportBudgetError) {
15527
15577
  const error = `The report is too large to import: ${e2.message}`;
@@ -15547,7 +15597,7 @@ function importJrxml(input, opts = {}) {
15547
15597
  r.definition.arithmetic = "double";
15548
15598
  placeCharts(r.definition, charts);
15549
15599
  const warnings = [...notes, ...r.warnings].map((w) => w.replace(/ActiveReports/g, "JasperReports"));
15550
- return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats };
15600
+ return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats, items: rewordItems(r.items, (w) => w.replace(/ActiveReports/g, "JasperReports")) };
15551
15601
  }
15552
15602
  function stripJasperDoctype(s) {
15553
15603
  const i = s.indexOf("<!DOCTYPE");
@@ -15556,9 +15606,9 @@ function stripJasperDoctype(s) {
15556
15606
  if (e2 < 0) return s;
15557
15607
  const decl = s.slice(i, e2 + 1);
15558
15608
  if (decl.includes("[") || !/^<!DOCTYPE\s+jasperReport\s/.test(decl)) return s;
15559
- return s.slice(0, i) + s.slice(e2 + 1);
15609
+ return s.slice(0, i) + decl.replace(/[^\n]/g, " ") + s.slice(e2 + 1);
15560
15610
  }
15561
- function toRdlx2(root, notes, charts, reportName) {
15611
+ function toRdlx2(root, notes, charts, reportName, resolve) {
15562
15612
  const kid = (e2, n5) => e2?.children.find((c) => c.name === n5);
15563
15613
  const kids = (e2, n5) => e2 ? e2.children.filter((c) => n5 == null || c.name === n5) : [];
15564
15614
  const txt = (e2, n5) => {
@@ -15651,8 +15701,8 @@ function toRdlx2(root, notes, charts, reportName) {
15651
15701
  };
15652
15702
  const BAND_AT = { detail: "detail", gh: "header", gf: "footer", title: "start", summary: "end" };
15653
15703
  function jasper(calc, inner2, reset, c) {
15654
- const at2 = BAND_AT[c.band];
15655
- const keys = at2 && reset != null ? groupKeys() : null;
15704
+ const at3 = BAND_AT[c.band];
15705
+ const keys = at3 && reset != null ? groupKeys() : null;
15656
15706
  if (!keys) return null;
15657
15707
  let end = -1;
15658
15708
  if (c.evalTime === "Report") end = 0;
@@ -15660,7 +15710,7 @@ function toRdlx2(root, notes, charts, reportName) {
15660
15710
  const k = groups.findIndex((g) => g.attrs.name === c.evalGroup);
15661
15711
  end = k >= 0 ? k + 1 : -1;
15662
15712
  } else if (c.evalTime === "Auto") end = reset;
15663
- return `JasperValue("${MAIN}", "${calc}", ${inner2}, "${at2}", ${reset}, ${end}${keys.map((k) => `, ${k}`).join("")})`;
15713
+ return `JasperValue("${MAIN}", "${calc}", ${inner2}, "${at3}", ${reset}, ${end}${keys.map((k) => `, ${k}`).join("")})`;
15664
15714
  }
15665
15715
  const depthOf = (gname) => {
15666
15716
  const k = groups.findIndex((g) => g.attrs.name === gname);
@@ -15742,6 +15792,7 @@ function toRdlx2(root, notes, charts, reportName) {
15742
15792
  return "=" + v.s;
15743
15793
  } catch (e2) {
15744
15794
  if (!(e2 instanceof Untranslatable2)) throw e2;
15795
+ (item2.__exprs ||= []).push(s);
15745
15796
  (item2.__notes ||= []).push(`${e2.message} has no ReportWright equivalent, so the expression ${s.length > 200 ? s.slice(0, 200) + "…" : s} is shown as text.`);
15746
15797
  return s.startsWith("=") ? `="${s.replace(/"/g, '""')}"` : s;
15747
15798
  }
@@ -15751,12 +15802,50 @@ function toRdlx2(root, notes, charts, reportName) {
15751
15802
  return "=" + vb2(String(src).trim(), c);
15752
15803
  } catch (e2) {
15753
15804
  if (!(e2 instanceof Untranslatable2)) throw e2;
15805
+ (item2.__exprs ||= []).push(String(src).trim());
15754
15806
  (item2.__notes ||= []).push(`${what} uses ${e2.message}, which has no ReportWright equivalent, so it is left out.`);
15755
15807
  return void 0;
15756
15808
  }
15757
15809
  }
15758
15810
  const styles = new Map(kids(root, "style").map((s) => [s.attrs.name, s]));
15759
- const defStyle = kids(root, "style").find((s) => s.attrs.isDefault === "true" || s.attrs.default === "true");
15811
+ const seenTemplates = /* @__PURE__ */ new Set();
15812
+ (function templates(el, depth) {
15813
+ for (const t of kids(el, "template")) {
15814
+ const src = (kid(t, "expression")?.text ?? t.text).trim();
15815
+ const lit2 = /^"([^"]+)"$/.exec(src);
15816
+ const ref2 = lit2 ? lit2[1] : depth > 0 && !/["$(){}+]/.test(src) ? src : null;
15817
+ if (!ref2) {
15818
+ if (src) note(`A style template is chosen by an expression (${src.slice(0, 120)}), so its styles are missing.`);
15819
+ continue;
15820
+ }
15821
+ if (seenTemplates.has(ref2) || seenTemplates.size >= 32) continue;
15822
+ seenTemplates.add(ref2);
15823
+ let text2;
15824
+ try {
15825
+ text2 = resolve?.("template", ref2);
15826
+ } catch {
15827
+ text2 = null;
15828
+ }
15829
+ if (typeof text2 !== "string") {
15830
+ note(`The style template "${ref2}" is not in the file, so items that use its styles have the default style.`);
15831
+ continue;
15832
+ }
15833
+ let doc;
15834
+ try {
15835
+ doc = parseXml(text2);
15836
+ } catch (e2) {
15837
+ note(`The style template "${ref2}" could not be read (${e2 instanceof Error ? e2.message : e2}), so its styles are missing.`);
15838
+ continue;
15839
+ }
15840
+ if (doc.name !== "jasperTemplate") {
15841
+ note(`The style template "${ref2}" is not a JasperReports template (its root is <${doc.name}>), so its styles are missing.`);
15842
+ continue;
15843
+ }
15844
+ for (const s of kids(doc, "style")) if (s.attrs.name && !styles.has(s.attrs.name)) styles.set(s.attrs.name, s);
15845
+ if (depth < 8) templates(doc, depth + 1);
15846
+ }
15847
+ })(root, 0);
15848
+ const defStyle = [...styles.values()].find((s) => s.attrs.isDefault === "true" || s.attrs.default === "true");
15760
15849
  function styleAttrs(name, seen = 0) {
15761
15850
  const s = styles.get(name);
15762
15851
  if (!s || seen > 10) return {};
@@ -15910,7 +15999,7 @@ function toRdlx2(root, notes, charts, reportName) {
15910
15999
  }
15911
16000
  function item(n5, c) {
15912
16001
  const a = n5.a, re = n5.re, e2 = n5.el;
15913
- const base = { Name: nameFor(n5, n5.kind), Left: pt(a.x), Top: pt(a.y), Width: pt(a.width), Height: pt(a.height) };
16002
+ const base = { __pos: e2.pos, Name: nameFor(n5, n5.kind), Left: pt(a.x), Top: pt(a.y), Width: pt(a.width), Height: pt(a.height) };
15914
16003
  const it = { ...base };
15915
16004
  const st = { ...defStyle ? styleAttrs(defStyle.attrs.name) : {}, ...a.style ? styleAttrs(a.style) : {}, ...stripUndef(normAttrs(re.attrs === e2.attrs ? e2.attrs : { ...re.attrs, ...e2.attrs, ...n5.te?.attrs || {}, ...kid(n5.te, "font")?.attrs || {} })), ...boxAttrs(kid(e2, "box")) };
15916
16005
  if (a.style && !styles.has(a.style)) (it.__notes ||= []).push(`its style "${a.style}" is not in the file (a style template?), so it has the default style.`);
@@ -16371,9 +16460,9 @@ function toRdlx2(root, notes, charts, reportName) {
16371
16460
  DataSources.push({ Name: srcName, ConnectionProperties: { DataProvider: "SQL", ConnectString: "" } });
16372
16461
  } else if (xpath) {
16373
16462
  set.Query.CommandText = q3?.text.trim() || "";
16374
- const at2 = String(root.children.find((c) => c.name === "property" && c.attrs.name === "net.sf.jasperreports.xml.source")?.attrs.value || "").trim();
16375
- if (!at2) note(`Data set "${name}": JasperReports gets its XML from Java code; set the XML source's URL in ReportWright.`);
16376
- DataSources.push({ Name: srcName, ConnectionProperties: { DataProvider: "XML", ConnectString: at2 ? `XmlDoc=${at2}` : "" } });
16463
+ const at3 = String(root.children.find((c) => c.name === "property" && c.attrs.name === "net.sf.jasperreports.xml.source")?.attrs.value || "").trim();
16464
+ if (!at3) note(`Data set "${name}": JasperReports gets its XML from Java code; set the XML source's URL in ReportWright.`);
16465
+ DataSources.push({ Name: srcName, ConnectionProperties: { DataProvider: "XML", ConnectString: at3 ? `XmlDoc=${at3}` : "" } });
16377
16466
  } else {
16378
16467
  if (q3 && q3.text.trim()) note(`Data set "${name}": its ${q3.attrs.language || "query"} query is not converted; point the data source at the data (JSON or CSV) and set its path.`);
16379
16468
  else note(`Data set "${name}": JasperReports gets its rows from Java code (a data source); point the ReportWright data source at the data.`);
@@ -16513,19 +16602,19 @@ function importBirt(input, opts = {}) {
16513
16602
  const r = importRdlx(ar, { name });
16514
16603
  if (r.error) return r;
16515
16604
  const warnings = [...notes, ...r.warnings].map((w) => w.replace(/ActiveReports/g, "BIRT"));
16516
- const walk = (items) => {
16605
+ const walk2 = (items) => {
16517
16606
  for (const i of items || []) {
16518
16607
  if (i.type === "table" && PAGE_BREAKS.get(i.name) > 0) i.pageBreakEvery = PAGE_BREAKS.get(i.name);
16519
- walk(i.items);
16608
+ walk2(i.items);
16520
16609
  }
16521
16610
  };
16522
- for (const sec of [r.definition.sections?.body].flat()) walk(sec?.items);
16611
+ for (const sec of [r.definition.sections?.body].flat()) walk2(sec?.items);
16523
16612
  PAGE_BREAKS.clear();
16524
16613
  r.definition.collation = "ordinal";
16525
16614
  r.definition.nullOrder = "low";
16526
16615
  r.definition.arithmetic = "double";
16527
16616
  r.definition.bandRows = "first-last";
16528
- return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats };
16617
+ return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats, items: rewordItems(r.items, (w) => w.replace(/ActiveReports/g, "BIRT")) };
16529
16618
  }
16530
16619
  function toRdlx3(root, notes, reportName) {
16531
16620
  const kid = (e2, n5) => e2?.children.find((c) => c.name === n5);
@@ -16739,6 +16828,7 @@ function toRdlx3(root, notes, reportName) {
16739
16828
  return "=" + vb2(s, c);
16740
16829
  } catch (e2) {
16741
16830
  if (!(e2 instanceof Untranslatable2)) throw e2;
16831
+ (item2.__exprs ||= []).push(s);
16742
16832
  (item2.__notes ||= []).push(`${e2.message} has no ReportWright equivalent, so the expression ${s.length > 200 ? s.slice(0, 200) + "…" : s} is shown as text.`);
16743
16833
  return s.startsWith("=") ? `="${s.replace(/"/g, '""')}"` : s;
16744
16834
  }
@@ -16748,6 +16838,7 @@ function toRdlx3(root, notes, reportName) {
16748
16838
  return "=" + vb2(src, c);
16749
16839
  } catch (e2) {
16750
16840
  if (!(e2 instanceof Untranslatable2)) throw e2;
16841
+ (item2.__exprs ||= []).push(String(src));
16751
16842
  (item2.__notes ||= []).push(`${what} uses ${e2.message}, which has no ReportWright equivalent, so it is left out.`);
16752
16843
  return void 0;
16753
16844
  }
@@ -16829,8 +16920,8 @@ function toRdlx3(root, notes, reportName) {
16829
16920
  function rdlxStyle(st, item2, c, opt = {}) {
16830
16921
  const o = {};
16831
16922
  if (st.fontFamily) o.FontFamily = genericFont(st.fontFamily);
16832
- const fs2 = fontPt(st.fontSize);
16833
- if (fs2) o.FontSize = pt(fs2);
16923
+ const fs3 = fontPt(st.fontSize);
16924
+ if (fs3) o.FontSize = pt(fs3);
16834
16925
  if (st.fontWeight && /bold|[6-9]00/.test(st.fontWeight)) o.FontWeight = "Bold";
16835
16926
  if (st.fontStyle === "italic" || st.fontStyle === "oblique") o.FontStyle = "Italic";
16836
16927
  if (st.textUnderline === "underline") o.TextDecoration = "Underline";
@@ -16889,18 +16980,18 @@ function toRdlx3(root, notes, reportName) {
16889
16980
  const nameFor = (e2, kind) => e2.attrs.name && NAME_OK.test(e2.attrs.name) ? e2.attrs.name : `${kind}${++seq}`;
16890
16981
  const ITEM_KINDS = /* @__PURE__ */ new Set(["label", "data", "text", "text-data", "auto-text", "image", "grid", "table", "list", "extended-item", "line", "free-form", "template-report-item", "multi-line-data"]);
16891
16982
  const textH = (text2, st) => {
16892
- const fs2 = fontPt(st.fontSize) || 10;
16893
- return Math.max(1, String(text2 || "").split("\n").length) * fs2 * 1.25 + 2;
16983
+ const fs3 = fontPt(st.fontSize) || 10;
16984
+ return Math.max(1, String(text2 || "").split("\n").length) * fs3 * 1.25 + 2;
16894
16985
  };
16895
16986
  function htmlParts(html) {
16896
16987
  const parts = [];
16897
16988
  const re = /<value-of[^>]*>([\s\S]*?)<\/value-of>/gi;
16898
- let at2 = 0, m2;
16989
+ let at3 = 0, m2;
16899
16990
  while (m2 = re.exec(html)) {
16900
- parts.push({ t: html.slice(at2, m2.index) }, { e: m2[1] });
16901
- at2 = re.lastIndex;
16991
+ parts.push({ t: html.slice(at3, m2.index) }, { e: m2[1] });
16992
+ at3 = re.lastIndex;
16902
16993
  }
16903
- parts.push({ t: html.slice(at2) });
16994
+ parts.push({ t: html.slice(at3) });
16904
16995
  const out = parts.map((p) => p.t == null ? p : { t: decodeHtml(p.t, false) });
16905
16996
  if (out[0].t != null) out[0].t = out[0].t.trimStart();
16906
16997
  const last = out[out.length - 1];
@@ -16928,7 +17019,7 @@ function toRdlx3(root, notes, reportName) {
16928
17019
  const w = Math.min(W2, len(prop(e2, "width"), W2, W2)) || W2;
16929
17020
  const given = len(prop(e2, "height"), 0, 0);
16930
17021
  const x = len(prop(e2, "x"), W2, 0);
16931
- const it = { Name: nameFor(e2, e2.name.replace(/(^|-)(\w)/g, (_, __, ch) => ch.toUpperCase())), Left: pt(x), Width: pt(w) };
17022
+ const it = { __pos: e2.pos, Name: nameFor(e2, e2.name.replace(/(^|-)(\w)/g, (_, __, ch) => ch.toUpperCase())), Left: pt(x), Width: pt(w) };
16932
17023
  const vis = listProp(e2, "visibility")[0];
16933
17024
  if (vis) {
16934
17025
  const ve = prop(vis, "valueExpr");
@@ -16986,6 +17077,7 @@ function toRdlx3(root, notes, reportName) {
16986
17077
  v = "=" + binding(b, c, 0);
16987
17078
  } catch (er) {
16988
17079
  if (!(er instanceof Untranslatable2)) throw er;
17080
+ (it.__exprs ||= []).push(String(prop(b, "expression") ?? col3));
16989
17081
  (it.__notes ||= []).push(`its column "${col3}" uses ${er.message}, so it is shown as text.`);
16990
17082
  v = col3;
16991
17083
  }
@@ -17014,6 +17106,7 @@ function toRdlx3(root, notes, reportName) {
17014
17106
  pieces.push(`(${vb2(decodeHtml(p.e), c)})`);
17015
17107
  } catch (er) {
17016
17108
  if (!(er instanceof Untranslatable2)) throw er;
17109
+ (it.__exprs ||= []).push(decodeHtml(p.e));
17017
17110
  (it.__notes ||= []).push(`a <value-of> uses ${er.message}, so it is left out.`);
17018
17111
  }
17019
17112
  }
@@ -17407,6 +17500,7 @@ var init_birt = __esm({
17407
17500
  // src/importers/index.js
17408
17501
  var importers_exports = {};
17409
17502
  __export(importers_exports, {
17503
+ decodeXml: () => decodeXml,
17410
17504
  importXmlReport: () => importXmlReport,
17411
17505
  rootName: () => rootName
17412
17506
  });
@@ -17426,6 +17520,21 @@ function rootName(s) {
17426
17520
  }
17427
17521
  return "";
17428
17522
  }
17523
+ function decodeXml(bytes) {
17524
+ const b = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
17525
+ if (b[0] === 172 && b[1] === 237) throw new Error("This is a compiled JasperReports file; import the .jrxml source instead.");
17526
+ if (b[0] === 255 && b[1] === 254) return new TextDecoder("utf-16le").decode(b.subarray(2));
17527
+ if (b[0] === 254 && b[1] === 255) return new TextDecoder("utf-16be").decode(b.subarray(2));
17528
+ if (b[0] === 239 && b[1] === 187 && b[2] === 191) return new TextDecoder("utf-8").decode(b.subarray(3));
17529
+ const decl = /^\s*<\?xml[^>]*?\sencoding\s*=\s*["']([A-Za-z0-9._-]+)["']/.exec(String.fromCharCode(...b.subarray(0, 200)));
17530
+ let enc = decl ? decl[1].toLowerCase() : "utf-8";
17531
+ if (enc === "utf-16" || enc === "unicode") enc = "utf-8";
17532
+ try {
17533
+ return new TextDecoder(enc).decode(b);
17534
+ } catch {
17535
+ return new TextDecoder("utf-8").decode(b);
17536
+ }
17537
+ }
17429
17538
  function importXmlReport(text2, opts = {}) {
17430
17539
  const root = rootName(String(text2 ?? ""));
17431
17540
  if (root === "jasperReport") return importJrxml(text2, opts);
@@ -17440,9 +17549,337 @@ var init_importers = __esm({
17440
17549
  }
17441
17550
  });
17442
17551
 
17443
- // bin/pw.mjs
17552
+ // src/importers/batch.js
17553
+ var batch_exports = {};
17554
+ __export(batch_exports, {
17555
+ BATCH_LIMITS: () => BATCH_LIMITS,
17556
+ MANIFEST: () => MANIFEST,
17557
+ exitCode: () => exitCode,
17558
+ importFolder: () => importFolder,
17559
+ reportHtml: () => reportHtml
17560
+ });
17444
17561
  import fs from "node:fs";
17445
17562
  import path from "node:path";
17563
+ import crypto2 from "node:crypto";
17564
+ function walk(root, o) {
17565
+ const files = [];
17566
+ const refused = [];
17567
+ let capped2 = false;
17568
+ const visit = (dir, rel2) => {
17569
+ for (const ent of fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : 1)) {
17570
+ if (capped2) return;
17571
+ const r = join(rel2, ent.name), abs = path.join(dir, ent.name);
17572
+ let real = abs, st;
17573
+ try {
17574
+ if (ent.isSymbolicLink()) {
17575
+ real = fs.realpathSync(abs);
17576
+ if (!inside(root, real)) {
17577
+ refused.push({ path: r, reason: "a symbolic link to outside the input folder: not followed" });
17578
+ continue;
17579
+ }
17580
+ st = fs.statSync(real);
17581
+ if (st.isDirectory()) {
17582
+ refused.push({ path: r, reason: "a symbolic link to a folder: not followed" });
17583
+ continue;
17584
+ }
17585
+ } else st = fs.statSync(abs);
17586
+ } catch (e2) {
17587
+ refused.push({ path: r, reason: `cannot be read (${e2 instanceof Error ? e2.message : e2})` });
17588
+ continue;
17589
+ }
17590
+ if (st.isDirectory()) {
17591
+ if (o.recursive && real !== o.skip) visit(abs, r);
17592
+ continue;
17593
+ }
17594
+ if (!st.isFile() || !(REPORT.test(r) || IMAGE.test(r) || RESOURCE.test(r))) continue;
17595
+ if (files.length >= o.maxFiles) {
17596
+ capped2 = true;
17597
+ refused.push({ path: r, reason: `more than ${o.maxFiles} files: this one and the rest are not imported (--max-files)` });
17598
+ return;
17599
+ }
17600
+ files.push({ rel: r, abs: real, size: st.size });
17601
+ }
17602
+ };
17603
+ visit(root, "");
17604
+ return { files, refused };
17605
+ }
17606
+ function positions(text2) {
17607
+ let starts = null;
17608
+ return (pos) => {
17609
+ if (typeof pos !== "number") return {};
17610
+ starts ||= [0, ...[...text2.matchAll(/\n/g)].map((m) => (
17611
+ /** @type {number} */
17612
+ m.index + 1
17613
+ ))];
17614
+ let lo = 0, hi = starts.length - 1;
17615
+ while (lo < hi) {
17616
+ const mid = lo + hi + 1 >> 1;
17617
+ if (starts[mid] <= pos) lo = mid;
17618
+ else hi = mid - 1;
17619
+ }
17620
+ return { line: lo + 1, column: pos - starts[lo] + 1 };
17621
+ };
17622
+ }
17623
+ function* objects(o, depth = 0) {
17624
+ if (!o || typeof o !== "object" || depth > 200) return;
17625
+ yield o;
17626
+ for (const v of Array.isArray(o) ? o : Object.values(o)) if (v && typeof v === "object") yield* objects(v, depth + 1);
17627
+ }
17628
+ async function importFolder(input, output, opts = {}) {
17629
+ const maxFiles = opts.maxFiles ?? BATCH_LIMITS.maxFiles, maxBytes = opts.maxBytes ?? BATCH_LIMITS.maxBytes;
17630
+ const log = opts.log || (() => {
17631
+ });
17632
+ const inRoot = fs.realpathSync(input);
17633
+ if (!fs.statSync(inRoot).isDirectory()) throw new Error(`${input} is not a folder`);
17634
+ fs.mkdirSync(output, { recursive: true });
17635
+ const outRoot = fs.realpathSync(output);
17636
+ const { files, refused } = walk(inRoot, { recursive: opts.recursive, maxFiles, skip: outRoot });
17637
+ let old = {};
17638
+ try {
17639
+ const m = JSON.parse(fs.readFileSync(path.join(outRoot, MANIFEST), "utf8"));
17640
+ if (m && typeof m.files === "object") old = m.files;
17641
+ } catch {
17642
+ }
17643
+ const manifest = {};
17644
+ for (const [k, v] of Object.entries(old)) if (typeof v === "string" && /^[0-9a-f]{64}$/.test(v)) manifest[k] = v;
17645
+ function writeTarget(rel2, bytes) {
17646
+ const abs = path.resolve(outRoot, ...rel2.split("/"));
17647
+ if (!inside(outRoot, abs) || abs === outRoot) throw new Error(`the output path ${rel2} is outside the output folder`);
17648
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
17649
+ if (!inside(outRoot, fs.realpathSync(path.dirname(abs)))) throw new Error(`the output folder of ${rel2} is a link to outside the output folder`);
17650
+ const h = sha2(bytes);
17651
+ let st = null;
17652
+ try {
17653
+ st = fs.lstatSync(abs);
17654
+ } catch {
17655
+ }
17656
+ if (st && !st.isFile()) throw new Error(`${rel2} is in the output folder and is not a plain file (a link or a folder): not overwritten`);
17657
+ let previous2, cur;
17658
+ if (st) {
17659
+ previous2 = fs.readFileSync(abs);
17660
+ cur = sha2(previous2);
17661
+ if (cur === h) {
17662
+ manifest[rel2] = h;
17663
+ return { write: "unchanged", previous: previous2 };
17664
+ }
17665
+ if (cur !== old[rel2] && !opts.force) return { write: "skipped-edited", previous: previous2 };
17666
+ }
17667
+ const tmp = path.join(path.dirname(abs), `.${path.basename(abs)}.${process.pid}.tmp`);
17668
+ fs.rmSync(tmp, { force: true });
17669
+ fs.writeFileSync(tmp, bytes, { flag: "wx" });
17670
+ fs.renameSync(tmp, abs);
17671
+ manifest[rel2] = h;
17672
+ return { write: !st ? "written" : cur !== old[rel2] ? "overwritten" : "refreshed", previous: previous2 };
17673
+ }
17674
+ const byRel = new Map(files.map((f4) => [f4.rel, f4]));
17675
+ function find(test, ref2, fromDir) {
17676
+ const r = String(ref2 ?? "").trim().replace(/\\/g, "/").replace(/^file:(\/\/)?/i, "");
17677
+ if (!r || /^[a-z][a-z0-9+.-]*:/i.test(r) && !/^[a-z]:\//i.test(r)) return null;
17678
+ if (!r.startsWith("/") && !/^[a-z]:\//i.test(r)) {
17679
+ const rel2 = path.posix.normalize(join(fromDir, r));
17680
+ const hit = !rel2.startsWith("../") && byRel.get(rel2);
17681
+ if (hit && test.test(hit.rel)) return hit;
17682
+ }
17683
+ const base = r.split("/").pop()?.toLowerCase();
17684
+ const cands = files.filter((f4) => test.test(f4.rel) && (path.posix.basename(f4.rel).toLowerCase() === base || stemOf(f4.rel).toLowerCase() === base));
17685
+ return cands.find((f4) => dirOf(f4.rel) === fromDir) || cands[0] || null;
17686
+ }
17687
+ const readText = (f4) => {
17688
+ if (f4.size > maxBytes) throw new Error(`${f4.rel} is larger than ${maxBytes} bytes`);
17689
+ return decodeXml(fs.readFileSync(f4.abs));
17690
+ };
17691
+ const reports = files.filter((f4) => REPORT.test(f4.rel));
17692
+ const taken = /* @__PURE__ */ new Set();
17693
+ const outOf = new Map(reports.map((f4) => {
17694
+ const dir = dirOf(f4.rel);
17695
+ let id = reportId(path.posix.basename(f4.rel));
17696
+ if (taken.has(join(dir, id))) id = `${id}-${extOf(f4.rel)}`.slice(0, 64);
17697
+ for (let k = 2; taken.has(join(dir, id)); k++) id = `${reportId(path.posix.basename(f4.rel))}-${k}`;
17698
+ taken.add(join(dir, id));
17699
+ return [f4.rel, { dir, id, rel: join(dir, `${id}.pw.json`) }];
17700
+ }));
17701
+ const images = /* @__PURE__ */ new Map();
17702
+ const results = [];
17703
+ for (const f4 of reports) {
17704
+ const o = (
17705
+ /** @type {{ dir: string, id: string, rel: string }} */
17706
+ outOf.get(f4.rel)
17707
+ );
17708
+ const rec = { source: f4.rel, format: FORMAT[extOf(f4.rel)], output: o.rel, status: "failed", stats: { items: 0, mapped: 0, approximated: 0, dropped: 0 }, items: [], expressions: [], notes: [], references: [] };
17709
+ results.push(rec);
17710
+ try {
17711
+ const text2 = readText(f4);
17712
+ const at3 = positions(text2);
17713
+ const resolve = (kind, ref2) => {
17714
+ const hit = find(kind === "datasource" ? /\.rds$/i : /\.jrtx$/i, ref2, o.dir);
17715
+ rec.references.push({ kind: kind === "datasource" ? "shared data source" : "style template", ref: ref2, resolved: hit ? hit.rel : null });
17716
+ return hit ? readText(hit) : null;
17717
+ };
17718
+ const name = stemOf(f4.rel);
17719
+ const r = extOf(f4.rel) === "rdlx-json" ? importRdlx(JSON.parse(text2.replace(/^/, "")), { name }) : importXmlReport(text2, { name, resolve });
17720
+ if (r.error) throw new Error(r.error);
17721
+ const def = r.definition;
17722
+ rec.stats = r.stats;
17723
+ const itemLines = /* @__PURE__ */ new Set();
17724
+ for (const it of r.items || []) {
17725
+ const p = at3(it.pos);
17726
+ rec.items.push({ name: it.name, state: it.state, ...p, notes: it.notes });
17727
+ for (const n6 of it.notes) itemLines.add(`${it.name}: ${n6.message}`);
17728
+ for (const e2 of it.exprs) rec.expressions.push({ item: it.name, expression: e2, ...p });
17729
+ }
17730
+ rec.notes = r.warnings.filter((w2) => !itemLines.has(w2));
17731
+ for (const s of objects(def)) {
17732
+ if (s.type !== "subreport" || typeof s.report !== "string") continue;
17733
+ const hits = reports.filter((x) => outOf.get(x.rel)?.id === s.report);
17734
+ const hit = hits.find((x) => dirOf(x.rel) === o.dir) || hits[0];
17735
+ const where = hit && /** @type {any} */
17736
+ outOf.get(hit.rel).rel;
17737
+ rec.references.push({
17738
+ kind: "subreport",
17739
+ ref: s.report,
17740
+ resolved: hit ? hit.rel : null,
17741
+ ...hit ? { output: where } : {},
17742
+ ...hit && dirOf(hit.rel) !== o.dir ? { note: `it is imported to ${where}, another folder: pw render finds a subreport next to its report (the server by its id)` } : {}
17743
+ });
17744
+ }
17745
+ for (const im of objects(def)) {
17746
+ if (im.type !== "image" || typeof im.src !== "string" || !im.src || im.src.startsWith("=") || /^(https?:|data:|embedded:)/i.test(im.src)) continue;
17747
+ const hit = find(IMAGE, im.src, dirOf(f4.rel));
17748
+ if (!hit) {
17749
+ rec.references.push({ kind: "image", ref: im.src, resolved: null });
17750
+ continue;
17751
+ }
17752
+ if (hit.size > maxBytes) {
17753
+ rec.references.push({ kind: "image", ref: im.src, resolved: null, note: `${hit.rel} is larger than ${maxBytes} bytes` });
17754
+ continue;
17755
+ }
17756
+ const bytes = fs.readFileSync(hit.abs), h = sha2(bytes);
17757
+ let copy = images.get(h);
17758
+ if (!copy) {
17759
+ const base = path.posix.basename(hit.rel);
17760
+ copy = join(o.dir, base);
17761
+ if ([...images.values()].includes(copy)) copy = join(o.dir, `${stemOf(base)}-${h.slice(0, 8)}${path.posix.extname(base)}`);
17762
+ const w2 = writeTarget(copy, bytes);
17763
+ if (w2.write === "skipped-edited") rec.notes.push(`The image ${copy} in the output folder was changed since the last import, so it was not replaced (--force replaces it).`);
17764
+ images.set(h, copy);
17765
+ }
17766
+ rec.references.push({ kind: "image", ref: im.src, resolved: hit.rel, output: copy });
17767
+ im.src = path.posix.relative(o.dir, copy);
17768
+ }
17769
+ if (extOf(f4.rel) === "rptdesign") {
17770
+ const libs = /<list-property\s+name="libraries">([\s\S]*?)<\/list-property>/.exec(text2)?.[1] || "";
17771
+ for (const m of libs.matchAll(/<property\s+name="fileName">([^<]{1,500})<\/property>/g)) {
17772
+ const hit = find(/\.rptlibrary$/i, m[1], o.dir);
17773
+ rec.references.push({ kind: "BIRT library", ref: m[1], resolved: hit ? hit.rel : null, note: "the BIRT importer does not read libraries: items from it are missing" });
17774
+ }
17775
+ }
17776
+ const w = writeTarget(o.rel, JSON.stringify(def, null, 2) + "\n");
17777
+ rec.status = "imported";
17778
+ rec.write = w.write;
17779
+ if (w.write === "skipped-edited") rec.notes.unshift(`${o.rel} was changed since the last import, so it was not overwritten (--force overwrites it).`);
17780
+ log(`${f4.rel} → ${o.rel}: ${w.write}${rec.references.some((x) => !x.resolved) ? `, ${rec.references.filter((x) => !x.resolved).length} unresolved` : ""}`);
17781
+ if (opts.verify) {
17782
+ let baseline = null, onDisk = def;
17783
+ try {
17784
+ if (w.write === "skipped-edited") onDisk = JSON.parse(fs.readFileSync(path.join(outRoot, ...o.rel.split("/")), "utf8"));
17785
+ else if (w.previous && w.write !== "unchanged") baseline = JSON.parse(w.previous.toString("utf8"));
17786
+ } catch {
17787
+ }
17788
+ try {
17789
+ rec.verify = await opts.verify({ file: path.join(outRoot, ...o.rel.split("/")), definition: onDisk, baseline });
17790
+ } catch (e2) {
17791
+ rec.verify = { status: "failed", error: e2 instanceof Error ? e2.message : String(e2) };
17792
+ }
17793
+ }
17794
+ } catch (e2) {
17795
+ rec.status = "failed";
17796
+ rec.error = e2 instanceof Error ? e2.message : String(e2);
17797
+ log(`${f4.rel}: FAILED: ${rec.error}`);
17798
+ }
17799
+ }
17800
+ fs.writeFileSync(path.join(outRoot, MANIFEST), JSON.stringify({ version: 1, note: "pw import: the hash of each file as written; a file whose hash differs was edited and is not overwritten without --force", files: manifest }, null, 2) + "\n");
17801
+ const n5 = (s) => results.filter((r) => r.status === s).length;
17802
+ return {
17803
+ tool: "pw import",
17804
+ schema: 1,
17805
+ created: (/* @__PURE__ */ new Date()).toISOString(),
17806
+ input: inRoot,
17807
+ output: outRoot,
17808
+ options: { recursive: !!opts.recursive, force: !!opts.force, verify: !!opts.verify, maxFiles, maxBytes },
17809
+ summary: {
17810
+ reports: results.length,
17811
+ imported: n5("imported"),
17812
+ failed: n5("failed"),
17813
+ refused: refused.length,
17814
+ images: images.size,
17815
+ skippedEdited: results.filter((r) => r.write === "skipped-edited").length,
17816
+ unresolved: results.reduce((k, r) => k + r.references.filter((x) => !x.resolved).length, 0)
17817
+ },
17818
+ files: results,
17819
+ refused
17820
+ };
17821
+ }
17822
+ function reportHtml(r) {
17823
+ const s = r.summary;
17824
+ const verifyCell = (v) => !v ? "" : `<span class="v-${esc8(v.status)}">${esc8(v.status)}</span>`;
17825
+ const rows = r.files.map((f4, i) => `<tr class="${f4.status}"><td><a href="#f${i}">${esc8(f4.source)}</a></td><td>${esc8(f4.format)}</td><td>${esc8(f4.status)}${f4.write ? ` · ${esc8(f4.write)}` : ""}</td><td class="n">${f4.stats.mapped}</td><td class="n">${f4.stats.approximated}</td><td class="n">${f4.stats.dropped}</td><td class="n">${f4.expressions.length}</td><td class="n">${f4.references.filter(
17826
+ (x) => !x.resolved).length}</td><td>${verifyCell(f4.verify)}</td></tr>`).join("\n");
17827
+ const detail = r.files.map((f4, i) => {
17828
+ const items = f4.items.filter((it) => it.notes.length);
17829
+ return `<section id="f${i}"><h2>${esc8(f4.source)} <small>${esc8(f4.format)} → ${esc8(f4.output)}</small></h2>` + (f4.error ? `<p class="err">Failed: ${esc8(f4.error)}</p>` : "") + (f4.references.length ? `<h3>References</h3><table><tr><th>Kind</th><th>Name</th><th>Resolved to</th><th>Note</th></tr>${f4.references.map((x) => `<tr class="${x.resolved ? "" : "failed"}"><td>${esc8(x.kind)}</td>${
17830
+ ""}<td><code>${esc8(x.ref)}</code></td><td>${x.resolved ? esc8(x.resolved) + (x.output ? ` → ${esc8(x.output)}` : "") : "<b>unresolved</b>"}</td><td>${esc8(x.note)}</td></tr>`).join("")}</table>` : "") + (f4.expressions.length ? `<h3>Expressions not translated</h3><table><tr><th>Line:col</th><th>Item</th><th>Expression</th></tr>${f4.expressions.map((e2) => `<tr><td>${esc8(at2(e2))}</td><td>${esc8(e2.
17831
+ item)}</td><td><code>${esc8(e2.expression)}</code></td></tr>`).join("")}</table>` : "") + (items.length ? `<h3>Items</h3><table><tr><th>Line:col</th><th>Item</th><th>Status</th><th>Why</th></tr>${items.map((it) => `<tr class="${esc8(it.state)}"><td>${esc8(at2(it))}</td><td>${esc8(it.name)}</td><td>${esc8(it.state)}</td><td><ul>${it.notes.map((n5) => `<li class="${esc8(n5.kind)}">${esc8(n5.message)}${
17832
+ ""}</li>`).join("")}</ul></td></tr>`).join("")}</table>` : "") + (f4.notes.length ? `<h3>Report notes</h3><ul>${f4.notes.map((n5) => `<li>${esc8(n5)}</li>`).join("")}</ul>` : "") + (f4.verify ? `<h3>Verify</h3><p>${verifyCell(f4.verify)} ${esc8(f4.verify.note || f4.verify.error || "")}${f4.verify.pages != null ? ` (${f4.verify.pages} pages)` : ""}</p>${f4.verify.diff?.length ? `<pre>${esc8(f4.verify.
17833
+ diff.join("\n"))}</pre>` : ""}` : "") + "</section>";
17834
+ }).join("\n");
17835
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
17836
+ <title>Import report</title><style>
17837
+ :root{color-scheme:light dark;--bg:#fff;--fg:#1d2025;--mute:#636a74;--line:#dfe2e6;--bad:#b42318;--warn:#9a6700;--ok:#1a7f37;--head:#f4f5f7}
17838
+ @media (prefers-color-scheme:dark){:root{--bg:#16181c;--fg:#e6e8eb;--mute:#9aa1ab;--line:#30343a;--bad:#ff7b72;--warn:#d29922;--ok:#3fb950;--head:#1f2228}}
17839
+ body{margin:0;padding:16px 24px;background:var(--bg);color:var(--fg);font:14px/1.45 system-ui,sans-serif}
17840
+ h1{font-size:20px;margin:0 0 4px}h2{font-size:16px;margin:28px 0 6px;border-top:1px solid var(--line);padding-top:14px;overflow-wrap:anywhere}h2 small{color:var(--mute);font-weight:400}h3{font-size:14px;margin:14px 0 4px}
17841
+ p.meta{color:var(--mute);margin:0 0 12px;overflow-wrap:anywhere}
17842
+ table{border-collapse:collapse;width:100%;margin:4px 0}th,td{border-bottom:1px solid var(--line);padding:4px 8px;text-align:left;vertical-align:top;overflow-wrap:anywhere}
17843
+ th{background:var(--head);font-weight:600}td.n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
17844
+ tr.failed td:first-child,.err,li.dropped,.v-failed,.v-changed{color:var(--bad)}tr.dropped td,li.approximated{color:var(--warn)}.v-ok{color:var(--ok)}
17845
+ code,pre{font:12px/1.4 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere}ul{margin:0;padding-left:18px}
17846
+ .cards{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0 16px}.cards div{border:1px solid var(--line);border-radius:6px;padding:6px 12px}.cards b{display:block;font-size:18px}
17847
+ </style></head><body><h1>Import report</h1>
17848
+ <p class="meta">${esc8(r.input)} → ${esc8(r.output)} · ${esc8(r.created)}</p>
17849
+ <div class="cards"><div><b>${s.reports}</b>reports</div><div><b>${s.imported}</b>imported</div><div><b>${s.failed}</b>failed</div><div><b>${s.unresolved}</b>unresolved references</div><div><b>${s.images}</b>images copied</div><div><b>${s.skippedEdited}</b>kept (edited)</div><div><b>${s.refused}</b>refused</div></div>
17850
+ <table><tr><th>File</th><th>Format</th><th>Status</th><th>Mapped</th><th>Approximated</th><th>Dropped</th><th>Expressions not translated</th><th>Unresolved</th><th>Verify</th></tr>
17851
+ ${rows}</table>
17852
+ ${r.refused.length ? `<h2>Refused</h2><ul>${r.refused.map((x) => `<li><code>${esc8(x.path)}</code>: ${esc8(x.reason)}</li>`).join("")}</ul>` : ""}
17853
+ ${detail}
17854
+ </body></html>
17855
+ `;
17856
+ }
17857
+ var BATCH_LIMITS, MANIFEST, REPORT, IMAGE, RESOURCE, FORMAT, sha2, inside, extOf, stemOf, dirOf, join, exitCode, esc8, at2;
17858
+ var init_batch = __esm({
17859
+ "src/importers/batch.js"() {
17860
+ init_importers();
17861
+ init_rdlx();
17862
+ BATCH_LIMITS = { maxFiles: 2e3, maxBytes: 16 * 1024 * 1024 };
17863
+ MANIFEST = ".pw-import.json";
17864
+ REPORT = /\.(rdlc?|jrxml|rptdesign|rdlx-json)$/i;
17865
+ IMAGE = /\.(png|jpe?g|gif|svg|bmp|webp)$/i;
17866
+ RESOURCE = /\.(rds|jrtx|rptlibrary)$/i;
17867
+ FORMAT = { rdl: "SSRS", rdlc: "SSRS", jrxml: "JasperReports", rptdesign: "BIRT", "rdlx-json": "ActiveReports" };
17868
+ sha2 = (b) => crypto2.createHash("sha256").update(b).digest("hex");
17869
+ inside = (root, p) => p === root || p.startsWith(root + path.sep);
17870
+ extOf = (f4) => /\.rdlx-json$/i.test(f4) ? "rdlx-json" : path.extname(f4).slice(1).toLowerCase();
17871
+ stemOf = (f4) => path.basename(f4).replace(/\.rdlx-json$/i, "").replace(/\.[^.]+$/, "");
17872
+ dirOf = (rel2) => path.posix.dirname(rel2) === "." ? "" : path.posix.dirname(rel2);
17873
+ join = (dir, f4) => dir ? `${dir}/${f4}` : f4;
17874
+ exitCode = (report) => !report.summary.imported ? 1 : report.summary.failed ? 2 : 0;
17875
+ esc8 = (s) => String(s ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[c]);
17876
+ at2 = (o) => o.line ? `${o.line}:${o.column}` : "";
17877
+ }
17878
+ });
17879
+
17880
+ // bin/pw.mjs
17881
+ import fs2 from "node:fs";
17882
+ import path2 from "node:path";
17446
17883
  import { createRequire } from "node:module";
17447
17884
  import { parseArgs } from "node:util";
17448
17885
 
@@ -17807,10 +18244,10 @@ var TextMeasurer = class {
17807
18244
  wrapComplex(para2, key, size, maxWidth, dir, sp, out) {
17808
18245
  const tokens = [];
17809
18246
  const sa = SA.test(para2) ? saBreaks(para2) : null;
17810
- let cur = "", space = false, prev = "", at2 = 0;
18247
+ let cur = "", space = false, prev = "", at3 = 0;
17811
18248
  for (const ch of para2) {
17812
- const i = at2;
17813
- at2 += ch.length;
18249
+ const i = at3;
18250
+ at3 += ch.length;
17814
18251
  if (ch === " ") {
17815
18252
  if (cur) {
17816
18253
  tokens.push({ text: cur, space });
@@ -18961,7 +19398,7 @@ function paintRound(type, g) {
18961
19398
  return paintPie(type, g);
18962
19399
  }
18963
19400
  function paintPie(type, g) {
18964
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, bold, text: text2, measure, fmtV, pointFill, pointLink, pal, label, labelText, anim } = g;
19401
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, bold, text: text2, measure, fmtV, pointFill, pointLink, pal, label, labelText, anim } = g;
18965
19402
  const vals = (data.series[0]?.values || []).map((v) => Math.max(0, v || 0));
18966
19403
  const total = vals.reduce((a, b) => a + b, 0) || 1;
18967
19404
  const showL = item.showValues !== false;
@@ -18990,7 +19427,7 @@ function paintPie(type, g) {
18990
19427
  lw[0] *= k;
18991
19428
  lw[1] *= k;
18992
19429
  }
18993
- r = Math.max(4, Math.min((W2 - lw[0] - lw[1] - gap * 2) / 2, (bottom - top) / 2 - fs2));
19430
+ r = Math.max(4, Math.min((W2 - lw[0] - lw[1] - gap * 2) / 2, (bottom - top) / 2 - fs3));
18994
19431
  const slack = W2 - lw[0] - lw[1] - gap * 2 - r * 2;
18995
19432
  cx = X + gap + lw[0] + r + slack / 2;
18996
19433
  } else r = Math.max(4, Math.min(W2, bottom - top) / 2 - 6);
@@ -19010,16 +19447,16 @@ function paintPie(type, g) {
19010
19447
  else if (!outside && frac >= 0.05 && showL) {
19011
19448
  const s = item.labelTemplate ? labelText(i, data.series[0], v, frac) : pctOf(v);
19012
19449
  const lr = ri ? (r + ri) / 2 : r * 0.62;
19013
- label(s, cx + Math.cos(mid) * lr, cy + Math.sin(mid) * lr + fs2 * 0.35, { color: inkOn(fill3), f: bold, size: fs2 });
19450
+ label(s, cx + Math.cos(mid) * lr, cy + Math.sin(mid) * lr + fs3 * 0.35, { color: inkOn(fill3), f: bold, size: fs3 });
19014
19451
  }
19015
19452
  a0 = a1;
19016
19453
  });
19017
- if (outside) placeOutside(sides, { cx, cy, r, lw, lh: fs2 * 1.3, lo: top + fs2 * 0.9, hi: bottom - fs2 * 0.4, out, text: text2, texts, fs: fs2, ink: g.ink });
19454
+ if (outside) placeOutside(sides, { cx, cy, r, lw, lh: fs3 * 1.3, lo: top + fs3 * 0.9, hi: bottom - fs3 * 0.4, out, text: text2, texts, fs: fs3, ink: g.ink });
19018
19455
  if (type === "donut" && item.centerText !== false) {
19019
- text2(fmtV(total), cx, cy + fs2 * 0.45, { align: "center", size: fs2 * 1.4, f: bold, color: "#111827" });
19456
+ text2(fmtV(total), cx, cy + fs3 * 0.45, { align: "center", size: fs3 * 1.4, f: bold, color: "#111827" });
19020
19457
  }
19021
19458
  }
19022
- function placeOutside(sides, { cx, cy, r, lw, lh, lo, hi, out, text: text2, texts, fs: fs2, ink }) {
19459
+ function placeOutside(sides, { cx, cy, r, lw, lh, lo, hi, out, text: text2, texts, fs: fs3, ink }) {
19023
19460
  sides.forEach((list2, right) => {
19024
19461
  const room = Math.max(1, Math.floor((hi - lo) / lh) + 1);
19025
19462
  if (list2.length > room) {
@@ -19044,16 +19481,16 @@ function placeOutside(sides, { cx, cy, r, lw, lh, lo, hi, out, text: text2, text
19044
19481
  const ex2 = cx + c * (r + 8), ey = cy + s * (r + 8);
19045
19482
  const kx = cx + dir * (r + 12);
19046
19483
  out.push({ t: "path", x: 0, y: 0, d: `M ${f(cx + c * r)} ${f(cy + s * r)} L ${f(ex2)} ${f(ey)} L ${f(kx)} ${f(l.y)}`, fill: null, stroke: "#9ca3af", strokeWidth: 0.6 });
19047
- text2(texts[l.i], kx + dir * 3, l.y + fs2 * 0.35, { align: right ? "left" : "right", maxW: Math.max(fs2, lw[right] + 1), color: ink });
19484
+ text2(texts[l.i], kx + dir * 3, l.y + fs3 * 0.35, { align: right ? "left" : "right", maxW: Math.max(fs3, lw[right] + 1), color: ink });
19048
19485
  }
19049
19486
  });
19050
19487
  }
19051
19488
  function paintRadar(g) {
19052
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, text: text2, measure, fmtV, pointLink, label, labelsOn, labelText, grid, anim, axes } = g;
19489
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, text: text2, measure, fmtV, pointLink, label, labelsOn, labelText, grid, anim, axes } = g;
19053
19490
  const n5 = data.categories.length;
19054
19491
  const catW = Math.min(W2 * 0.25, data.categories.reduce((m, c) => Math.max(m, measure(c).w), 10));
19055
- const cx = X + W2 / 2, cy = (top + bottom) / 2 + fs2 * 0.3;
19056
- const R2 = Math.max(6, Math.min(W2 / 2 - catW - 8, (bottom - top) / 2 - fs2 * 1.6));
19492
+ const cx = X + W2 / 2, cy = (top + bottom) / 2 + fs3 * 0.3;
19493
+ const R2 = Math.max(6, Math.min(W2 / 2 - catW - 8, (bottom - top) / 2 - fs3 * 1.6));
19057
19494
  let lo = 0, hi = 0;
19058
19495
  for (const s of data.series) for (const v of s.values) if (v != null) {
19059
19496
  lo = Math.min(lo, v);
@@ -19065,34 +19502,34 @@ function paintRadar(g) {
19065
19502
  const ticks = linearTicks(a, b, sc.step);
19066
19503
  const rad = (v) => Math.max(0, Math.min(1, (v - a) / (b - a || 1))) * R2;
19067
19504
  const ang = (i) => -Math.PI / 2 + i / Math.max(1, n5) * Math.PI * 2;
19068
- const at2 = (i, r) => ({ x: cx + Math.cos(ang(i)) * r, y: cy + Math.sin(ang(i)) * r });
19069
- const poly = (r) => Array.from({ length: n5 }, (_, i) => at2(i, r)).map((p, i) => `${i ? "L" : "M"} ${f(p.x)} ${f(p.y)}`).join(" ") + " Z";
19505
+ const at3 = (i, r) => ({ x: cx + Math.cos(ang(i)) * r, y: cy + Math.sin(ang(i)) * r });
19506
+ const poly = (r) => Array.from({ length: n5 }, (_, i) => at3(i, r)).map((p, i) => `${i ? "L" : "M"} ${f(p.x)} ${f(p.y)}`).join(" ") + " Z";
19070
19507
  if (ys.gridlines !== false) {
19071
19508
  for (const t of ticks) if (rad(t) > 0) out.push({ t: "path", x: 0, y: 0, d: n5 > 2 ? poly(rad(t)) : "", fill: null, stroke: grid, strokeWidth: 0.5 });
19072
19509
  }
19073
19510
  for (let i = 0; i < n5; i++) {
19074
- const e2 = at2(i, R2);
19511
+ const e2 = at3(i, R2);
19075
19512
  out.push({ t: "line", x1: cx, y1: cy, x2: e2.x, y2: e2.y, stroke: grid, strokeWidth: 0.5 });
19076
19513
  }
19077
- for (const t of ticks) if (rad(t) > 0 && rad(t) < R2 - 0.5) text2(fmtV(t), cx + 3, cy - rad(t) + fs2 * 0.3, { size: fs2 * 0.8, color: "#6b7280" });
19514
+ for (const t of ticks) if (rad(t) > 0 && rad(t) < R2 - 0.5) text2(fmtV(t), cx + 3, cy - rad(t) + fs3 * 0.3, { size: fs3 * 0.8, color: "#6b7280" });
19078
19515
  data.categories.forEach((c, i) => {
19079
- const p = at2(i, R2 + 4), cos = Math.cos(ang(i));
19080
- text2(c, p.x, p.y + fs2 * 0.35 + (Math.sin(ang(i)) > 0.5 ? fs2 * 0.5 : 0), { align: Math.abs(cos) < 0.2 ? "center" : cos > 0 ? "left" : "right", maxW: catW });
19516
+ const p = at3(i, R2 + 4), cos = Math.cos(ang(i));
19517
+ text2(c, p.x, p.y + fs3 * 0.35 + (Math.sin(ang(i)) > 0.5 ? fs3 * 0.5 : 0), { align: Math.abs(cos) < 0.2 ? "center" : cos > 0 ? "left" : "right", maxW: catW });
19081
19518
  });
19082
19519
  data.series.forEach((s, si) => {
19083
- const pts2 = s.values.map((v, i) => v == null ? null : { ...at2(i, rad(v)), v, i }).filter(Boolean);
19520
+ const pts2 = s.values.map((v, i) => v == null ? null : { ...at3(i, rad(v)), v, i }).filter(Boolean);
19084
19521
  if (!pts2.length) return;
19085
19522
  const d = pts2.map((p, i) => `${i ? "L" : "M"} ${f(p.x)} ${f(p.y)}`).join(" ") + " Z";
19086
19523
  out.push(tag({ t: "path", x: 0, y: 0, d, fill: s.color + (s.def.type === "line" ? "00" : "2e"), stroke: s.color, strokeWidth: 1.4 }, anim && { k: anim === "grow" ? "scale" : "fade", i: si }));
19087
19524
  if (n5 <= 40) for (const p of pts2) out.push({ t: "ellipse", cx: p.x, cy: p.y, rx: 1.8, ry: 1.8, fill: s.color, stroke: null });
19088
19525
  for (const p of pts2) pointLink(p.i, { x: p.x - 4, y: p.y - 4, w: 8, h: 8 }, `${data.categories[p.i]}${data.series.length > 1 ? ` · ${s.name}` : ""}: ${fmtV(p.v)}`);
19089
- if (labelsOn || item.labelTemplate) for (const p of pts2) label(labelText(p.i, s, p.v), p.x, p.y - 3, { size: fs2 * 0.85 });
19526
+ if (labelsOn || item.labelTemplate) for (const p of pts2) label(labelText(p.i, s, p.v), p.x, p.y - 3, { size: fs3 * 0.85 });
19090
19527
  });
19091
19528
  }
19092
19529
  var GAUGE_SHAPES = { half: [Math.PI, Math.PI], threeQuarter: [Math.PI * 0.75, Math.PI * 1.5], full: [-Math.PI / 2, Math.PI * 2] };
19093
19530
  var GAUGE_INDICATORS = ["needle", "pointer", "bar"];
19094
19531
  function paintGauge(g) {
19095
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, bold, text: text2, fmtV, pointLink, axes, lc, who, safe: safe3, ctx } = g;
19532
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, bold, text: text2, fmtV, pointLink, axes, lc, who, safe: safe3, ctx } = g;
19096
19533
  const v = data.series[0]?.values?.[0] ?? null;
19097
19534
  const ys = axes.y || {};
19098
19535
  const num6 = (x) => x == null || x === "" ? null : Number.isFinite(Number(x)) ? Number(x) : null;
@@ -19111,14 +19548,14 @@ function paintGauge(g) {
19111
19548
  R2 = Math.max(8, Math.min(W2 / 2 - 8, H / 2 - 4));
19112
19549
  cy = (top + bottom) / 2;
19113
19550
  } else if (shape2 === "threeQuarter") {
19114
- R2 = Math.max(8, Math.min(W2 / 2 - 8, (H - fs2 * 1.4 - 4) / (1 + Math.SQRT1_2)));
19551
+ R2 = Math.max(8, Math.min(W2 / 2 - 8, (H - fs3 * 1.4 - 4) / (1 + Math.SQRT1_2)));
19115
19552
  cy = top + 4 + R2;
19116
19553
  } else {
19117
- R2 = Math.max(8, Math.min(W2 / 2 - 8, H - fs2 * 3.6));
19554
+ R2 = Math.max(8, Math.min(W2 / 2 - 8, H - fs3 * 3.6));
19118
19555
  cy = top + 4 + R2;
19119
19556
  }
19120
19557
  const th = R2 * 0.22;
19121
- const at2 = (a2, rad) => ({ x: cx + Math.cos(a2) * rad, y: cy + Math.sin(a2) * rad });
19558
+ const at3 = (a2, rad) => ({ x: cx + Math.cos(a2) * rad, y: cy + Math.sin(a2) * rad });
19122
19559
  const scope = { ...ctx, fields: data.rows[0] || null, aggRows: data.rows, aggIndex: void 0 };
19123
19560
  const val = (o, k) => typeof o[k] === "number" ? o[k] : num6(safe3(o[k], scope, lc, who));
19124
19561
  const overlays = (Array.isArray(item.overlays) ? item.overlays : []).slice(0, 20).filter((o) => o && typeof o === "object");
@@ -19139,55 +19576,55 @@ function paintGauge(g) {
19139
19576
  for (const o of overlays) if (o.type === "line") {
19140
19577
  const t = val(o, "value");
19141
19578
  if (t == null) continue;
19142
- const a2 = ang(t), p1 = at2(a2, R2 - th - 2), p2 = at2(a2, R2 + 2);
19579
+ const a2 = ang(t), p1 = at3(a2, R2 - th - 2), p2 = at3(a2, R2 + 2);
19143
19580
  out.push({ t: "line", x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y, stroke: o.color || "#111827", strokeWidth: 1.5 });
19144
19581
  }
19145
19582
  const sc = niceScale(lo, hi, shape2 === "half" ? 5 : 7);
19146
19583
  const ticks = linearTicks(Math.ceil(lo / sc.step - 1e-9) * sc.step, hi, sc.step).filter((t) => t >= lo - 1e-9 && t <= hi + 1e-9);
19147
- const tickOn = item.gaugeTicks !== false && R2 >= fs2 * 5 && ticks.length > 1;
19584
+ const tickOn = item.gaugeTicks !== false && R2 >= fs3 * 5 && ticks.length > 1;
19148
19585
  if (tickOn) {
19149
19586
  const ri = R2 - th - 1;
19150
19587
  const minor = sc.step / 5;
19151
19588
  for (let t = ticks[0] - sc.step, k = 0; t <= hi + 1e-9 && k < 200; t += minor, k++) {
19152
19589
  if (t < lo - 1e-9) continue;
19153
19590
  const isMajor = ticks.some((m) => Math.abs(m - t) < minor / 2);
19154
- const a2 = ang(t), p1 = at2(a2, ri), p2 = at2(a2, ri - th * (isMajor ? 0.4 : 0.2));
19591
+ const a2 = ang(t), p1 = at3(a2, ri), p2 = at3(a2, ri - th * (isMajor ? 0.4 : 0.2));
19155
19592
  out.push({ t: "line", x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y, stroke: isMajor ? "#6b7280" : "#9ca3af", strokeWidth: isMajor ? 0.9 : 0.5 });
19156
19593
  }
19157
- const lr = ri - th * 0.4 - fs2 * 1.1;
19594
+ const lr = ri - th * 0.4 - fs3 * 1.1;
19158
19595
  ticks.forEach((t, k) => {
19159
19596
  if (shape2 === "full" && k === ticks.length - 1 && Math.abs(frac(t) - 1) < 1e-9) return;
19160
- const p = at2(ang(t), lr);
19161
- text2(fmtV(t), p.x, p.y + fs2 * 0.3, { align: "center", size: fs2 * 0.8, color: "#6b7280" });
19597
+ const p = at3(ang(t), lr);
19598
+ text2(fmtV(t), p.x, p.y + fs3 * 0.3, { align: "center", size: fs3 * 0.8, color: "#6b7280" });
19162
19599
  });
19163
19600
  } else if (shape2 !== "full") {
19164
- const e0 = at2(start, R2 - th / 2), e1 = at2(start + sweep2, R2 - th / 2);
19165
- text2(fmtV(lo), e0.x, e0.y + fs2 * 1.3, { align: "center", color: "#6b7280" });
19166
- text2(fmtV(hi), e1.x, e1.y + fs2 * 1.3, { align: "center", color: "#6b7280" });
19601
+ const e0 = at3(start, R2 - th / 2), e1 = at3(start + sweep2, R2 - th / 2);
19602
+ text2(fmtV(lo), e0.x, e0.y + fs3 * 1.3, { align: "center", color: "#6b7280" });
19603
+ text2(fmtV(hi), e1.x, e1.y + fs3 * 1.3, { align: "center", color: "#6b7280" });
19167
19604
  }
19168
- const vy = shape2 === "half" ? cy + fs2 * 2.6 : cy + R2 * 0.5 + fs2 * 0.6;
19605
+ const vy = shape2 === "half" ? cy + fs3 * 2.6 : cy + R2 * 0.5 + fs3 * 0.6;
19169
19606
  if (v == null) {
19170
- text2("No data", cx, shape2 === "half" ? cy - R2 / 3 : cy + fs2 * 0.35, { align: "center", color: "#9ca3af" });
19607
+ text2("No data", cx, shape2 === "half" ? cy - R2 / 3 : cy + fs3 * 0.35, { align: "center", color: "#9ca3af" });
19171
19608
  return;
19172
19609
  }
19173
19610
  const a = ang(v), ink = typeof item.pointerColor === "string" && /^#[0-9a-f]{6}$/i.test(item.pointerColor) ? item.pointerColor : "#1f2937";
19174
19611
  if (indicator2 === "needle") {
19175
19612
  const len = R2 - th * 0.4, bw = Math.max(1.5, R2 * 0.03);
19176
- const tip = at2(a, len), n1 = at2(a + Math.PI / 2, bw), n22 = at2(a - Math.PI / 2, bw);
19613
+ const tip = at3(a, len), n1 = at3(a + Math.PI / 2, bw), n22 = at3(a - Math.PI / 2, bw);
19177
19614
  const d = `M ${f(n1.x)} ${f(n1.y)} L ${f(tip.x)} ${f(tip.y)} L ${f(n22.x)} ${f(n22.y)} Z`;
19178
19615
  out.push(tag({ t: "path", x: 0, y: 0, d, fill: ink, stroke: null }, g.anim && { k: "fade", i: 0 }));
19179
19616
  out.push({ t: "ellipse", cx, cy, rx: bw * 1.4, ry: bw * 1.4, fill: ink, stroke: null });
19180
19617
  } else if (indicator2 === "pointer") {
19181
- const tip = at2(a, R2 - th * 0.85), half = Math.max(0.05, Math.min(0.2, th * 0.55 / Math.max(1, R2 - th)));
19182
- const b1 = at2(a - half, R2 - th * 1.7), b2 = at2(a + half, R2 - th * 1.7);
19618
+ const tip = at3(a, R2 - th * 0.85), half = Math.max(0.05, Math.min(0.2, th * 0.55 / Math.max(1, R2 - th)));
19619
+ const b1 = at3(a - half, R2 - th * 1.7), b2 = at3(a + half, R2 - th * 1.7);
19183
19620
  const d = `M ${f(b1.x)} ${f(b1.y)} L ${f(tip.x)} ${f(tip.y)} L ${f(b2.x)} ${f(b2.y)} Z`;
19184
19621
  out.push(tag({ t: "path", x: 0, y: 0, d, fill: ink, stroke: "#ffffff", strokeWidth: 0.6 }, g.anim && { k: "fade", i: 0 }));
19185
19622
  }
19186
- text2(item.labelTemplate ? g.labelText(0, data.series[0], v) : fmtV(v), cx, indicator2 === "needle" || shape2 === "half" ? vy : cy + fs2 * 0.55, { align: "center", size: fs2 * 1.6, f: bold, color: "#111827" });
19623
+ text2(item.labelTemplate ? g.labelText(0, data.series[0], v) : fmtV(v), cx, indicator2 === "needle" || shape2 === "half" ? vy : cy + fs3 * 0.55, { align: "center", size: fs3 * 1.6, f: bold, color: "#111827" });
19187
19624
  pointLink(0, { x: cx - R2, y: cy - R2, w: R2 * 2, h: shape2 === "half" ? R2 : R2 * 2 }, `${data.series[0]?.name || "Value"}: ${fmtV(v)}`);
19188
19625
  }
19189
19626
  function paintFunnel(g) {
19190
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, text: text2, measure, fmtV, pointFill, pointLink, pal, labelText, anim } = g;
19627
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, text: text2, measure, fmtV, pointFill, pointLink, pal, labelText, anim } = g;
19191
19628
  const vals = (data.series[0]?.values || []).map((v) => Math.max(0, v || 0));
19192
19629
  const n5 = vals.length;
19193
19630
  let max = 0;
@@ -19197,9 +19634,9 @@ function paintFunnel(g) {
19197
19634
  return;
19198
19635
  }
19199
19636
  const gap = n5 > 1 ? Math.min(2, (bottom - top) / n5 / 4) : 0;
19200
- const sh = (bottom - top - fs2 * 0.6 - gap * (n5 - 1)) / n5;
19637
+ const sh = (bottom - top - fs3 * 0.6 - gap * (n5 - 1)) / n5;
19201
19638
  const maxW = W2 * 0.62, cx = X + W2 * 0.36;
19202
- let y = top + fs2 * 0.6;
19639
+ let y = top + fs3 * 0.6;
19203
19640
  const total = vals.reduce((a, b) => a + b, 0) || 1;
19204
19641
  vals.forEach((v, i) => {
19205
19642
  const tw = Math.max(2, maxW * v / max), bw = Math.max(2, i < n5 - 1 ? maxW * vals[i + 1] / max : tw * 0.6);
@@ -19209,7 +19646,7 @@ function paintFunnel(g) {
19209
19646
  pointLink(i, { x: cx - tw / 2, y, w: tw, h: sh }, `${data.categories[i]}: ${fmtV(v)} (${Math.round(v / total * 100)}%)`, d);
19210
19647
  if (item.showValues !== false) {
19211
19648
  const s = item.labelTemplate ? labelText(i, data.series[0], v, v / total) : `${data.categories[i]}: ${fmtV(v)}`;
19212
- const sz = Math.min(fs2, sh * 0.7);
19649
+ const sz = Math.min(fs3, sh * 0.7);
19213
19650
  const { w } = measure(s, { size: sz });
19214
19651
  const narrow = Math.min(tw, bw);
19215
19652
  if (w + 6 < narrow) text2(s, cx, y + sh / 2 + sz * 0.35, { align: "center", size: sz, color: inkOn(fill3) });
@@ -19270,32 +19707,32 @@ function capRows(g, rows) {
19270
19707
  }
19271
19708
  var noData = (g) => g.text("No data", g.X + g.W / 2, (g.top + g.bottom) / 2, { align: "center", color: "#9ca3af" });
19272
19709
  function frame(g, lo, hi, fmt2, { cats = null, catW = 0 } = {}) {
19273
- const { item, lc, X, W: W2, top, bottom, fs: fs2, text: text2, out, axes, who, grid } = g;
19710
+ const { item, lc, X, W: W2, top, bottom, fs: fs3, text: text2, out, axes, who, grid } = g;
19274
19711
  const ys = axes.y || {};
19275
- const plotTop = top + fs2 * 0.6;
19712
+ const plotTop = top + fs3 * 0.6;
19276
19713
  const xTitle = axes.x?.title || item.xTitle, yTitle = ys.title;
19277
- const plotBottom = bottom - fs2 * 1.8 - (xTitle ? fs2 * 1.6 : 0);
19278
- const ay = g.valueAxis(ys, lo, hi, Infinity, { includeZero: true, len: plotBottom - plotTop, fs: fs2, fmt: fmt2, lc, who, name: "y" });
19279
- const valW = Math.max(10, ...ay.ticks.map((t) => lc.m.width(ay.fmt(t), g.font, fs2)));
19280
- const left = X + 4 + (yTitle ? fs2 * 1.6 : 0) + valW + 6, right = X + W2 - 6;
19714
+ const plotBottom = bottom - fs3 * 1.8 - (xTitle ? fs3 * 1.6 : 0);
19715
+ const ay = g.valueAxis(ys, lo, hi, Infinity, { includeZero: true, len: plotBottom - plotTop, fs: fs3, fmt: fmt2, lc, who, name: "y" });
19716
+ const valW = Math.max(10, ...ay.ticks.map((t) => lc.m.width(ay.fmt(t), g.font, fs3)));
19717
+ const left = X + 4 + (yTitle ? fs3 * 1.6 : 0) + valW + 6, right = X + W2 - 6;
19281
19718
  const vy = (v) => {
19282
19719
  const fr = Math.max(0, Math.min(1, ay.frac(v) ?? 0));
19283
19720
  return ys.reversed ? plotTop + fr * (plotBottom - plotTop) : plotBottom - fr * (plotBottom - plotTop);
19284
19721
  };
19285
19722
  for (const t of ay.ticks) {
19286
19723
  if (ys.gridlines !== false) out.push({ t: "line", x1: left, y1: vy(t), x2: right, y2: vy(t), stroke: grid, strokeWidth: 0.5 });
19287
- text2(ay.fmt(t), left - 5, vy(t) + fs2 * 0.35, { align: "right" });
19724
+ text2(ay.fmt(t), left - 5, vy(t) + fs3 * 0.35, { align: "right" });
19288
19725
  }
19289
19726
  if (xTitle) text2(xTitle, (left + right) / 2, bottom - 2, { align: "center", color: "#6b7280" });
19290
19727
  if (yTitle) {
19291
19728
  const my = (plotTop + plotBottom) / 2;
19292
- text2(yTitle, X + 4 + fs2, my, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: -90, cx: X + 4 + fs2, cy: my } });
19729
+ text2(yTitle, X + 4 + fs3, my, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: -90, cx: X + 4 + fs3, cy: my } });
19293
19730
  }
19294
19731
  const band = (right - left) / Math.max(1, cats ? cats.length : 1);
19295
19732
  if (cats) {
19296
19733
  const every = Math.max(1, Math.ceil((catW + 6) / band));
19297
19734
  cats.forEach((c, i) => {
19298
- if (i % every === 0) text2(c, left + band * (i + 0.5), plotBottom + fs2 * 1.35, { align: "center", maxW: band * every - 2 });
19735
+ if (i % every === 0) text2(c, left + band * (i + 0.5), plotBottom + fs3 * 1.35, { align: "center", maxW: band * every - 2 });
19299
19736
  });
19300
19737
  }
19301
19738
  return { left, right, plotTop, plotBottom, vy, band, ay };
@@ -19348,7 +19785,7 @@ function squarify(items, x, y, w, h) {
19348
19785
  return out;
19349
19786
  }
19350
19787
  function paintTreemap(g) {
19351
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, pal, pointFill, pointLink, fmtV, lc, who, anim } = g;
19788
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, pal, pointFill, pointLink, fmtV, lc, who, anim } = g;
19352
19789
  const s = data.series[0];
19353
19790
  const items = [];
19354
19791
  let dropped = 0;
@@ -19366,10 +19803,10 @@ function paintTreemap(g) {
19366
19803
  out.push({ t: "rect", x: r.x, y: r.y, w: r.w, h: r.h, fill: fill3, stroke: "#ffffff", strokeWidth: 1, ...anim ? { anim: { k: "fade", i: r.i } } : {} });
19367
19804
  const v = s.values[r.i];
19368
19805
  pointLink(r.i, { x: r.x, y: r.y, w: r.w, h: r.h }, `${data.categories[r.i]}: ${fmtV(v)} (${Math.round(v / total * 100)}%)`);
19369
- if (r.w > fs2 * 3 && r.h > fs2 * 1.6) {
19806
+ if (r.w > fs3 * 3 && r.h > fs3 * 1.6) {
19370
19807
  const ink = inkOn(fill3);
19371
- g.text(data.categories[r.i], r.x + 4, r.y + fs2 * 1.3, { color: ink, maxW: r.w - 8, f: g.bold });
19372
- if (r.h > fs2 * 3 && item.showValues !== false) g.text(g.labelText(r.i, s, v, v / total), r.x + 4, r.y + fs2 * 2.5, { color: ink, maxW: r.w - 8, size: fs2 * 0.9 });
19808
+ g.text(data.categories[r.i], r.x + 4, r.y + fs3 * 1.3, { color: ink, maxW: r.w - 8, f: g.bold });
19809
+ if (r.h > fs3 * 3 && item.showValues !== false) g.text(g.labelText(r.i, s, v, v / total), r.x + 4, r.y + fs3 * 2.5, { color: ink, maxW: r.w - 8, size: fs3 * 0.9 });
19373
19810
  }
19374
19811
  }
19375
19812
  }
@@ -19406,7 +19843,7 @@ function binValues(vals, { binCount, binWidth } = {}) {
19406
19843
  return { lo, hi: lo + width * n5, width, counts, capped: capped2 };
19407
19844
  }
19408
19845
  function paintHistogram(g) {
19409
- const { item, data, out, fs: fs2, lc, who, ctx, pal, axes, anim } = g;
19846
+ const { item, data, out, fs: fs3, lc, who, ctx, pal, axes, anim } = g;
19410
19847
  const s = data.series[0];
19411
19848
  const rows = capRows(g, data.rows);
19412
19849
  const vals = rowValues(g, s?.def?.value || "=0", rows).filter((v) => v != null);
@@ -19422,11 +19859,11 @@ function paintHistogram(g) {
19422
19859
  const x = f4.left + i * bw, y = f4.vy(c), base = f4.vy(0);
19423
19860
  if (c > 0) out.push({ t: "rect", x: x + 0.5, y, w: Math.max(0.5, bw - 1), h: base - y, fill: color2, ...anim ? { anim: { k: anim === "grow" ? "growY" : "fade", o: "bottom", i } } : {} });
19424
19861
  if (item.tooltips !== false) g.links.push({ t: "link", x, y: f4.plotTop, w: bw, h: f4.plotBottom - f4.plotTop, action: null, tip: `${fmtX(b.lo + i * b.width)} – ${fmtX(b.lo + (i + 1) * b.width)}: ${c}` });
19425
- if (g.labelsOn && c > 0) g.label(String(c), x + bw / 2, y - 3, { size: fs2 * 0.85 });
19862
+ if (g.labelsOn && c > 0) g.label(String(c), x + bw / 2, y - 3, { size: fs3 * 0.85 });
19426
19863
  });
19427
19864
  const edgeW = Math.max(...[b.lo, b.hi].map((v) => g.measure(fmtX(v)).w));
19428
19865
  const every = Math.max(1, Math.ceil((edgeW + 6) / bw));
19429
- for (let i = 0; i <= n5; i += every) g.text(fmtX(b.lo + i * b.width), f4.left + i * bw, f4.plotBottom + fs2 * 1.35, { align: "center" });
19866
+ for (let i = 0; i <= n5; i += every) g.text(fmtX(b.lo + i * b.width), f4.left + i * bw, f4.plotBottom + fs3 * 1.35, { align: "center" });
19430
19867
  out.push({ t: "line", x1: f4.left, y1: f4.plotBottom, x2: f4.right, y2: f4.plotBottom, stroke: "#9ca3af", strokeWidth: 0.75 });
19431
19868
  }
19432
19869
  function boxStats(sorted) {
@@ -19451,7 +19888,7 @@ function boxStats(sorted) {
19451
19888
  return { min: sorted[0], max: sorted[n5 - 1], q1, med, q3: q32, lo, hi, outliers, mean: sum / n5, n: n5 };
19452
19889
  }
19453
19890
  function paintBoxPlot(g) {
19454
- const { item, data, out, fs: fs2, pal, lc, who, pointFill, pointLink, fmtV, ctx } = g;
19891
+ const { item, data, out, fs: fs3, pal, lc, who, pointFill, pointLink, fmtV, ctx } = g;
19455
19892
  const s = data.series[0];
19456
19893
  let budget = CAPS.points;
19457
19894
  const stats = data.buckets.map((bk) => {
@@ -19495,13 +19932,13 @@ function paintBoxPlot(g) {
19495
19932
  out.push({ t: "ellipse", cx, cy: f4.vy(v), rx: 2, ry: 2, fill: null, stroke: color2, strokeWidth: 0.9 });
19496
19933
  }
19497
19934
  pointLink(i, { x: cx - f4.band / 2, y: f4.plotTop, w: f4.band, h: f4.plotBottom - f4.plotTop }, `${data.categories[i]}: min ${fmtV(st.lo)}, Q1 ${fmtV(st.q1)}, median ${fmtV(st.med)}, Q3 ${fmtV(st.q3)}, max ${fmtV(st.hi)}${st.outliers.length ? `, ${st.outliers.length} outliers` : ""} (n ${st.n})`);
19498
- if (g.labelsOn) g.label(fmtV(st.med), cx + bw / 2 + 3, f4.vy(st.med) + fs2 * 0.3, { align: "left", size: fs2 * 0.85 });
19935
+ if (g.labelsOn) g.label(fmtV(st.med), cx + bw / 2 + 3, f4.vy(st.med) + fs3 * 0.3, { align: "left", size: fs3 * 0.85 });
19499
19936
  });
19500
19937
  if (cut) lc.warn(`${who}: more than ${MORE_CAPS.outliers} outliers; the rest are not drawn`);
19501
19938
  out.push({ t: "line", x1: f4.left, y1: f4.plotBottom, x2: f4.right, y2: f4.plotBottom, stroke: "#9ca3af", strokeWidth: 0.75 });
19502
19939
  }
19503
19940
  function paintWaterfall(g) {
19504
- const { item, data, out, fs: fs2, ctx, lc, who, pointLink, fmtV, anim } = g;
19941
+ const { item, data, out, fs: fs3, ctx, lc, who, pointLink, fmtV, anim } = g;
19505
19942
  const s = data.series[0];
19506
19943
  const up = item.upColor || "#16a34a", down = item.downColor || "#dc2626", tot = item.totalColor || "#2563eb";
19507
19944
  const isTotal = (i) => {
@@ -19547,7 +19984,7 @@ function paintWaterfall(g) {
19547
19984
  const tip = `${b.label}: ${b.kind === "total" ? fmtV(b.v) : `${b.v >= 0 ? "+" : ""}${fmtV(b.v)} → ${fmtV(b.b)}`}`;
19548
19985
  if (b.i >= 0) pointLink(b.i, rect, tip);
19549
19986
  else if (item.tooltips !== false) g.links.push({ t: "link", ...rect, action: null, tip });
19550
- if (g.labelsOn) g.label(b.kind === "total" ? fmtV(b.v) : `${b.v >= 0 ? "+" : ""}${fmtV(b.v)}`, cx, Math.min(y0, y1) - 3, { size: fs2 * 0.85, alt: { y: Math.max(y0, y1) + fs2, color: g.ink } });
19987
+ if (g.labelsOn) g.label(b.kind === "total" ? fmtV(b.v) : `${b.v >= 0 ? "+" : ""}${fmtV(b.v)}`, cx, Math.min(y0, y1) - 3, { size: fs3 * 0.85, alt: { y: Math.max(y0, y1) + fs3, color: g.ink } });
19551
19988
  });
19552
19989
  out.push({ t: "line", x1: f4.left, y1: f4.vy(0), x2: f4.right, y2: f4.vy(0), stroke: "#9ca3af", strokeWidth: 0.75 });
19553
19990
  }
@@ -19611,7 +20048,7 @@ function step2(d, n5, u) {
19611
20048
  else d.setUTCFullYear(d.getUTCFullYear() + n5);
19612
20049
  }
19613
20050
  function paintGantt(g) {
19614
- const { item, data, out, X, W: W2, top, bottom, fs: fs2, ctx, lc, who, pal, pointFill, pointLink, axes, grid, text: text2, anim } = g;
20051
+ const { item, data, out, X, W: W2, top, bottom, fs: fs3, ctx, lc, who, pal, pointFill, pointLink, axes, grid, text: text2, anim } = g;
19615
20052
  const cats = data.categories;
19616
20053
  if (!item.ganttStart || !item.ganttEnd) {
19617
20054
  text2("Set the start and end of the bars", X + W2 / 2, (top + bottom) / 2, { align: "center", color: "#9ca3af" });
@@ -19671,18 +20108,18 @@ function paintGantt(g) {
19671
20108
  }
19672
20109
  const catW = Math.min(cats.reduce((m, s) => Math.max(m, g.measure(s).w), 10), W2 * 0.32);
19673
20110
  const plotLeft = X + 4 + catW + 6, plotRight = X + W2 - 6;
19674
- const plotTop = top + fs2 * 0.6, plotBottom = bottom - fs2 * 1.8 - (xs.title ? fs2 * 1.6 : 0);
20111
+ const plotTop = top + fs3 * 0.6, plotBottom = bottom - fs3 * 1.8 - (xs.title ? fs3 * 1.6 : 0);
19675
20112
  const px = (t) => plotLeft + (t - lo) / (hi - lo) * (plotRight - plotLeft);
19676
20113
  for (const t of ticks) {
19677
20114
  if (t < lo || t > hi) continue;
19678
20115
  if (xs.gridlines !== false) out.push({ t: "line", x1: px(t), y1: plotTop, x2: px(t), y2: plotBottom, stroke: grid, strokeWidth: 0.5 });
19679
- text2(fmtT(t), px(t), plotBottom + fs2 * 1.35, { align: "center" });
20116
+ text2(fmtT(t), px(t), plotBottom + fs3 * 1.35, { align: "center" });
19680
20117
  }
19681
20118
  if (xs.title) text2(xs.title, (plotLeft + plotRight) / 2, bottom - 2, { align: "center", color: "#6b7280" });
19682
20119
  const lane = (plotBottom - plotTop) / Math.max(1, cats.length);
19683
- const every = Math.max(1, Math.ceil(fs2 * 1.2 / lane));
20120
+ const every = Math.max(1, Math.ceil(fs3 * 1.2 / lane));
19684
20121
  cats.forEach((s, i) => {
19685
- if (i % every === 0) text2(s, plotLeft - 5, plotTop + lane * (i + 0.5) + fs2 * 0.35, { align: "right", maxW: catW });
20122
+ if (i % every === 0) text2(s, plotLeft - 5, plotTop + lane * (i + 0.5) + fs3 * 0.35, { align: "right", maxW: catW });
19686
20123
  });
19687
20124
  const bh = Math.max(1, Math.min(lane * 0.62, 22));
19688
20125
  bars.forEach((b, k) => {
@@ -19691,13 +20128,13 @@ function paintGantt(g) {
19691
20128
  const fill3 = groups.keyOf.get(b.r)?.color || pointFill(b.ci, pal[0]);
19692
20129
  out.push({ t: "rect", x: x0, y, w: Math.max(1, x1 - x0), h: bh, fill: fill3, radius: Math.min(2, bh / 4), ...anim ? { anim: { k: anim === "grow" ? "growX" : "fade", o: "left", i: k } } : {} });
19693
20130
  pointLink(b.ci, { x: x0, y, w: Math.max(4, x1 - x0), h: bh }, `${cats[b.ci]}: ${fmtT(b.a)} – ${fmtT(b.b)}`);
19694
- if (g.labelsOn) g.label(cats[b.ci], x1 + 3, y + bh / 2 + fs2 * 0.3, { align: "left", size: fs2 * 0.85 });
20131
+ if (g.labelsOn) g.label(cats[b.ci], x1 + 3, y + bh / 2 + fs3 * 0.3, { align: "left", size: fs3 * 0.85 });
19695
20132
  });
19696
20133
  out.push({ t: "line", x1: plotLeft, y1: plotBottom, x2: plotRight, y2: plotBottom, stroke: "#9ca3af", strokeWidth: 0.75 });
19697
20134
  if (today != null && today >= lo && today <= hi) {
19698
20135
  const tx = px(today);
19699
20136
  out.push({ t: "line", x1: tx, y1: plotTop, x2: tx, y2: plotBottom, stroke: item.todayColor || "#dc2626", strokeWidth: 1, dash: [3, 2] });
19700
- text2("Today", tx + 2, plotTop + fs2 * 0.9, { color: item.todayColor || "#dc2626", size: fs2 * 0.85 });
20137
+ text2("Today", tx + 2, plotTop + fs3 * 0.9, { color: item.todayColor || "#dc2626", size: fs3 * 0.85 });
19701
20138
  }
19702
20139
  }
19703
20140
 
@@ -19829,18 +20266,18 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19829
20266
  const m = lc.m;
19830
20267
  const font = resolveFontKey(base.fontFamily, "normal", "normal");
19831
20268
  const bold = resolveFontKey(base.fontFamily, "bold", "normal");
19832
- const fs2 = Math.max(6, Number(item.fontSize) || 7.5);
20269
+ const fs3 = Math.max(6, Number(item.fontSize) || 7.5);
19833
20270
  const ink = item.textColor || "#374151";
19834
20271
  const grid = "#e5e7eb";
19835
20272
  const X = item.x, W2 = item.w, H = item.h;
19836
20273
  const who = item.name || "Chart";
19837
20274
  const out = [];
19838
- const measure = (s, { size = fs2, f: fk2 = font, maxW = 9999 } = {}) => {
20275
+ const measure = (s, { size = fs3, f: fk2 = font, maxW = 9999 } = {}) => {
19839
20276
  let str = String(s).slice(0, 200);
19840
20277
  if (m.width(str, fk2, size) > maxW) str = m.ellipsize(str, fk2, size, maxW);
19841
20278
  return { str, w: m.width(str, fk2, size) };
19842
20279
  };
19843
- const text2 = (s, x, y, { size = fs2, f: fk2 = font, color: color2 = ink, align = "left", maxW = 9999, rotate = null } = {}) => {
20280
+ const text2 = (s, x, y, { size = fs3, f: fk2 = font, color: color2 = ink, align = "left", maxW = 9999, rotate = null } = {}) => {
19844
20281
  const { str, w } = measure(s, { size, f: fk2, maxW });
19845
20282
  const lx = align === "right" ? x - w : align === "center" ? x - w / 2 : x;
19846
20283
  const t = { t: "text", font: fk2, size, color: color2, lines: [{ x: lx, y, text: str, w }] };
@@ -19878,19 +20315,19 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19878
20315
  let top = 4, bottom = H - 4;
19879
20316
  const title2 = item.title ? String(safe2(item.title, ctx, lc, who) ?? "") : "";
19880
20317
  if (title2) {
19881
- const tw = W2 - 8, full = fs2 * 1.35, s = String(title2).slice(0, 200);
19882
- const fit = m.width(s, bold, full) <= tw ? full : Math.max(fs2, Math.floor(full * tw / m.width(s, bold, full) * 10) / 10);
20318
+ const tw = W2 - 8, full = fs3 * 1.35, s = String(title2).slice(0, 200);
20319
+ const fit = m.width(s, bold, full) <= tw ? full : Math.max(fs3, Math.floor(full * tw / m.width(s, bold, full) * 10) / 10);
19883
20320
  if (m.width(s, bold, fit) <= tw) {
19884
- text2(s, X + 4, top + fs2 * 1.4, { size: fit, f: bold, color: "#111827", maxW: tw });
19885
- top += fs2 * 2.1;
20321
+ text2(s, X + 4, top + fs3 * 1.4, { size: fit, f: bold, color: "#111827", maxW: tw });
20322
+ top += fs3 * 2.1;
19886
20323
  } else {
19887
20324
  const words = s.split(/\s+/);
19888
20325
  let first = "";
19889
- while (words.length && m.width(first ? `${first} ${words[0]}` : words[0], bold, fs2) <= tw) first = first ? `${first} ${words.shift()}` : words.shift();
20326
+ while (words.length && m.width(first ? `${first} ${words[0]}` : words[0], bold, fs3) <= tw) first = first ? `${first} ${words.shift()}` : words.shift();
19890
20327
  if (!first) first = words.shift() || "";
19891
- text2(first, X + 4, top + fs2 * 1.4, { size: fs2, f: bold, color: "#111827", maxW: tw });
19892
- if (words.length) text2(words.join(" "), X + 4, top + fs2 * 2.6, { size: fs2, f: bold, color: "#111827", maxW: tw });
19893
- top += fs2 * (words.length ? 3.3 : 2.1);
20328
+ text2(first, X + 4, top + fs3 * 1.4, { size: fs3, f: bold, color: "#111827", maxW: tw });
20329
+ if (words.length) text2(words.join(" "), X + 4, top + fs3 * 2.6, { size: fs3, f: bold, color: "#111827", maxW: tw });
20330
+ top += fs3 * (words.length ? 3.3 : 2.1);
19894
20331
  }
19895
20332
  }
19896
20333
  const byCategory = type === "pie" || type === "donut" || type === "funnel";
@@ -19903,7 +20340,7 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19903
20340
  let line3 = [], lw = 0;
19904
20341
  for (const li of legendItems.slice(0, 200)) {
19905
20342
  const key = li.mark ? 14 : 10;
19906
- const w = key + m.width(String(li.name).slice(0, 200), font, fs2) + 12;
20343
+ const w = key + m.width(String(li.name).slice(0, 200), font, fs3) + 12;
19907
20344
  if (lw + w > W2 - 8 && line3.length) {
19908
20345
  rowsL.push(line3);
19909
20346
  line3 = [];
@@ -19913,16 +20350,16 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19913
20350
  lw += w;
19914
20351
  }
19915
20352
  if (line3.length) rowsL.push(line3);
19916
- const lh = fs2 * 1.6;
20353
+ const lh = fs3 * 1.6;
19917
20354
  const keep = rowsL.slice(0, Math.max(1, Math.floor((bottom - top) / 2 / lh)));
19918
20355
  bottom -= keep.length * lh;
19919
20356
  keep.forEach((ln, ri) => {
19920
20357
  let lx = X + (W2 - ln.reduce((s, l) => s + l.w, 0)) / 2;
19921
20358
  const ly = bottom + ri * lh + lh * 0.75;
19922
20359
  for (const l of ln) {
19923
- if (l.mark === "line") out.push({ t: "line", x1: lx, y1: ly - fs2 * 0.35, x2: lx + 11, y2: ly - fs2 * 0.35, stroke: l.color, strokeWidth: 1.4, ...l.dash ? { dash: [3, 2] } : {} });
19924
- else if (l.mark === "band") out.push({ t: "rect", x: lx, y: ly - fs2 * 0.75, w: 11, h: 7, fill: l.color + "40", stroke: l.color, strokeWidth: 0.5, radius: 1.5 });
19925
- else out.push({ t: "rect", x: lx, y: ly - fs2 * 0.75, w: 7, h: 7, fill: l.color, radius: 1.5 });
20360
+ if (l.mark === "line") out.push({ t: "line", x1: lx, y1: ly - fs3 * 0.35, x2: lx + 11, y2: ly - fs3 * 0.35, stroke: l.color, strokeWidth: 1.4, ...l.dash ? { dash: [3, 2] } : {} });
20361
+ else if (l.mark === "band") out.push({ t: "rect", x: lx, y: ly - fs3 * 0.75, w: 11, h: 7, fill: l.color + "40", stroke: l.color, strokeWidth: 0.5, radius: 1.5 });
20362
+ else out.push({ t: "rect", x: lx, y: ly - fs3 * 0.75, w: 7, h: 7, fill: l.color, radius: 1.5 });
19926
20363
  text2(l.name, lx + l.key, ly, { maxW: l.w - l.key });
19927
20364
  lx += l.w;
19928
20365
  }
@@ -19937,7 +20374,7 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19937
20374
  const fmtV = (v) => toText(v, axes.y?.format || item.valueFormat || "N0", ctx);
19938
20375
  const anim = item.animation === "grow" || item.animation === "fade" ? item.animation : null;
19939
20376
  const placer = new LabelPlacer({ x: X, y: 0, w: W2, h: H });
19940
- const label = (s, x, y, { size = fs2 * 0.9, align = "center", color: color2 = ink, f: fk2 = font, alt: alt2 = null } = {}) => {
20377
+ const label = (s, x, y, { size = fs3 * 0.9, align = "center", color: color2 = ink, f: fk2 = font, alt: alt2 = null } = {}) => {
19941
20378
  const { str, w } = measure(s, { size, f: fk2 });
19942
20379
  if (!str.trim()) return false;
19943
20380
  const tries = [{ x, y, align, color: color2 }];
@@ -19960,7 +20397,7 @@ function paintChart(item, ctx, lc, base, meta = {}) {
19960
20397
  return String(tpl).slice(0, 500).replace(/\{(\w+)\}/g, (all, k) => Object.hasOwn(vars, k.toLowerCase()) ? vars[k.toLowerCase()] : all);
19961
20398
  };
19962
20399
  const inLegend = (o) => legendOn && o.legend !== false;
19963
- const g = { inLegend, item, ctx, lc, data, out, links, X, W: W2, H, top, bottom, fs: fs2, font, bold, ink, grid, text: text2, measure, fmtV, pointFill, pointLink, pointCtx, pal, label, labelsOn, labelText, anim, who, axes, safe: safe2, valueAxis };
20400
+ const g = { inLegend, item, ctx, lc, data, out, links, X, W: W2, H, top, bottom, fs: fs3, font, bold, ink, grid, text: text2, measure, fmtV, pointFill, pointLink, pointCtx, pal, label, labelsOn, labelText, anim, who, axes, safe: safe2, valueAxis };
19964
20401
  if (MORE_TYPES.has(type)) paintMore(type, g);
19965
20402
  else if (ROUND_TYPES.has(type)) paintRound(type, g);
19966
20403
  else if (PER_ROW.has(type)) paintXY(type, g);
@@ -20005,7 +20442,7 @@ var stepDecimals = (step3) => {
20005
20442
  const m = /\.(\d+)$/.exec(t);
20006
20443
  return t.includes("e-") ? Math.min(6, Number(t.split("e-")[1])) : m ? Math.min(6, m[1].length) : 0;
20007
20444
  };
20008
- function valueAxis(spec, lo, hi, minPos, { includeZero = true, len = 100, fs: fs2 = 7.5, fmt: fmt2, percent = false, pad: pad2 = 0, lc, who, name, autoFmt }) {
20445
+ function valueAxis(spec, lo, hi, minPos, { includeZero = true, len = 100, fs: fs3 = 7.5, fmt: fmt2, percent = false, pad: pad2 = 0, lc, who, name, autoFmt }) {
20009
20446
  spec = spec && typeof spec === "object" ? spec : {};
20010
20447
  const smin = numOrNull(spec.min), smax = numOrNull(spec.max);
20011
20448
  if (spec.log) {
@@ -20031,7 +20468,7 @@ function valueAxis(spec, lo, hi, minPos, { includeZero = true, len = 100, fs: fs
20031
20468
  if (smax == null) hi = hi <= 0 && hi + d > 0 ? 0 : hi + d;
20032
20469
  padded = true;
20033
20470
  }
20034
- const want = len < fs2 * 6 ? 3 : 5;
20471
+ const want = len < fs3 * 6 ? 3 : 5;
20035
20472
  const sc = padded && smin == null && smax == null && (lo >= 0 || hi <= 0) ? niceScaleSpan(lo, hi, want) : niceScale(smin ?? lo, smax ?? hi, want);
20036
20473
  let a = sc.lo, b = sc.hi, ticks;
20037
20474
  if (smin != null || smax != null) {
@@ -20079,7 +20516,7 @@ function overlaysOf(item, lc, who) {
20079
20516
  }
20080
20517
  var CAT_KINDS = /* @__PURE__ */ new Set(["column", "bar", "line", "area"]);
20081
20518
  function paintCartesian(type, g) {
20082
- const { item, lc, data, out, X, W: W2, top, bottom, fs: fs2, font, text: text2, measure, pointFill, pointLink, label, labelsOn, labelText, anim, who, axes, ink, grid } = g;
20519
+ const { item, lc, data, out, X, W: W2, top, bottom, fs: fs3, font, text: text2, measure, pointFill, pointLink, label, labelsOn, labelText, anim, who, axes, ink, grid } = g;
20083
20520
  const m = lc.m;
20084
20521
  const horiz = type === "bar";
20085
20522
  const financialChart = type === "candlestick" || type === "ohlc";
@@ -20183,18 +20620,18 @@ function paintCartesian(type, g) {
20183
20620
  const angleSet = !horiz ? Math.max(-90, Math.min(90, Number(xSpec.labelAngle) || 0)) : 0;
20184
20621
  const layoutAt = (angle2) => {
20185
20622
  const sin2 = Math.abs(Math.sin(angle2 * Math.PI / 180)), cos2 = Math.abs(Math.cos(angle2 * Math.PI / 180));
20186
- const catBand2 = angle2 ? Math.min(catW, (bottom - top) * 0.4) * sin2 + fs2 * cos2 + fs2 * 0.8 : fs2 * 1.8;
20187
- const plotTop2 = top + fs2 * 0.6 + (horiz && hasY2 ? fs2 * 1.6 : 0);
20188
- const plotBottom2 = bottom - (horiz ? fs2 * 1.6 : catBand2) - (bottomTitle ? fs2 * 1.6 : 0);
20189
- const opt = { len: horiz ? W2 * 0.6 : plotBottom2 - plotTop2, fs: fs2, lc, who, percent: stackMode === "percent" };
20623
+ const catBand2 = angle2 ? Math.min(catW, (bottom - top) * 0.4) * sin2 + fs3 * cos2 + fs3 * 0.8 : fs3 * 1.8;
20624
+ const plotTop2 = top + fs3 * 0.6 + (horiz && hasY2 ? fs3 * 1.6 : 0);
20625
+ const plotBottom2 = bottom - (horiz ? fs3 * 1.6 : catBand2) - (bottomTitle ? fs3 * 1.6 : 0);
20626
+ const opt = { len: horiz ? W2 * 0.6 : plotBottom2 - plotTop2, fs: fs3, lc, who, percent: stackMode === "percent" };
20190
20627
  const ax2 = [
20191
20628
  valueAxis(ySpec, rng[0].lo, rng[0].hi, rng[0].minPos, { ...opt, includeZero: !rng[0].allFin || !rng[0].any, fmt: fmt1, name: "y", autoFmt: auto(ySpec, item.valueFormat) }),
20192
20629
  valueAxis(y2Spec, rng[1].lo, rng[1].hi, rng[1].minPos, { ...opt, includeZero: !rng[1].allFin, fmt: fmt2, name: "secondary y", autoFmt: auto(y2Spec, ySpec.format, item.valueFormat) })
20193
20630
  ];
20194
- const valW3 = Math.max(10, ...ax2[0].ticks.map((t) => m.width(ax2[0].fmt(t), font, fs2)));
20195
- const valW22 = hasY2 ? Math.max(10, ...ax2[1].ticks.map((t) => m.width(ax2[1].fmt(t), font, fs2))) : 0;
20196
- const left2 = X + 4 + (leftTitle ? fs2 * 1.6 : 0) + (horiz ? Math.min(catW, W2 * 0.32) : valW3) + 6;
20197
- const right2 = X + W2 - 6 - (!horiz && hasY2 ? valW22 + 6 + (y2Spec.title ? fs2 * 1.6 : 0) : 0);
20631
+ const valW3 = Math.max(10, ...ax2[0].ticks.map((t) => m.width(ax2[0].fmt(t), font, fs3)));
20632
+ const valW22 = hasY2 ? Math.max(10, ...ax2[1].ticks.map((t) => m.width(ax2[1].fmt(t), font, fs3))) : 0;
20633
+ const left2 = X + 4 + (leftTitle ? fs3 * 1.6 : 0) + (horiz ? Math.min(catW, W2 * 0.32) : valW3) + 6;
20634
+ const right2 = X + W2 - 6 - (!horiz && hasY2 ? valW22 + 6 + (y2Spec.title ? fs3 * 1.6 : 0) : 0);
20198
20635
  return { angle: angle2, sin: sin2, cos: cos2, catBand: catBand2, plotTop: plotTop2, plotBottom: plotBottom2, ax: ax2, valW: valW3, valW2: valW22, left: left2, right: right2 };
20199
20636
  };
20200
20637
  let lay = layoutAt(angleSet);
@@ -20206,10 +20643,10 @@ function paintCartesian(type, g) {
20206
20643
  }
20207
20644
  if (bottomTitle) text2(bottomTitle, (left + right) / 2, bottom - 2, { align: "center", color: "#6b7280" });
20208
20645
  const midY = (plotTop + plotBottom) / 2;
20209
- if (leftTitle) text2(leftTitle, X + 4 + fs2, midY, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: -90, cx: X + 4 + fs2, cy: midY } });
20646
+ if (leftTitle) text2(leftTitle, X + 4 + fs3, midY, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: -90, cx: X + 4 + fs3, cy: midY } });
20210
20647
  if (hasY2 && y2Spec.title) {
20211
- if (horiz) text2(y2Spec.title, (left + right) / 2, top + fs2, { align: "center", color: "#6b7280" });
20212
- else text2(y2Spec.title, X + W2 - 4 - fs2, midY, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: 90, cx: X + W2 - 4 - fs2, cy: midY } });
20648
+ if (horiz) text2(y2Spec.title, (left + right) / 2, top + fs3, { align: "center", color: "#6b7280" });
20649
+ else text2(y2Spec.title, X + W2 - 4 - fs3, midY, { align: "center", color: "#6b7280", maxW: plotBottom - plotTop, rotate: { a: 90, cx: X + W2 - 4 - fs3, cy: midY } });
20213
20650
  }
20214
20651
  const vpos = (ai, v) => {
20215
20652
  let fr = ax[ai].frac(v);
@@ -20226,10 +20663,10 @@ function paintCartesian(type, g) {
20226
20663
  const showGrid = ySpec.gridlines !== false;
20227
20664
  if (horiz) {
20228
20665
  if (showGrid) out.push({ t: "line", x1: p, y1: plotTop, x2: p, y2: plotBottom, stroke: grid, strokeWidth: 0.5 });
20229
- if (i % e1 === 0) text2(ax[0].fmt(t), p, plotBottom + fs2 * 1.3, { align: "center" });
20666
+ if (i % e1 === 0) text2(ax[0].fmt(t), p, plotBottom + fs3 * 1.3, { align: "center" });
20230
20667
  } else {
20231
20668
  if (showGrid) out.push({ t: "line", x1: left, y1: p, x2: right, y2: p, stroke: grid, strokeWidth: 0.5 });
20232
- text2(ax[0].fmt(t), left - 5, p + fs2 * 0.35, { align: "right" });
20669
+ text2(ax[0].fmt(t), left - 5, p + fs3 * 0.35, { align: "right" });
20233
20670
  }
20234
20671
  });
20235
20672
  if (hasY2) {
@@ -20238,8 +20675,8 @@ function paintCartesian(type, g) {
20238
20675
  const p = vpos(1, t);
20239
20676
  if (y2Spec.gridlines) out.push(horiz ? { t: "line", x1: p, y1: plotTop, x2: p, y2: plotBottom, stroke: grid, strokeWidth: 0.5, dash: [2, 2] } : { t: "line", x1: left, y1: p, x2: right, y2: p, stroke: grid, strokeWidth: 0.5, dash: [2, 2] });
20240
20677
  if (horiz) {
20241
- if (i % e2 === 0) text2(ax[1].fmt(t), p, plotTop - fs2 * 0.5, { align: "center" });
20242
- } else text2(ax[1].fmt(t), right + 5, p + fs2 * 0.35);
20678
+ if (i % e2 === 0) text2(ax[1].fmt(t), p, plotTop - fs3 * 0.5, { align: "center" });
20679
+ } else text2(ax[1].fmt(t), right + 5, p + fs3 * 0.35);
20243
20680
  });
20244
20681
  }
20245
20682
  const span = horiz ? plotBottom - plotTop : right - left;
@@ -20258,25 +20695,25 @@ function paintCartesian(type, g) {
20258
20695
  const p0 = vpos(ai, o.vals[0]), p1 = vpos(ai, o.vals[1]);
20259
20696
  const color2 = typeof o.color === "string" && /^#[0-9a-f]{6}$/i.test(o.color) ? o.color : "#f59e0b";
20260
20697
  out.push(horiz ? { t: "rect", x: Math.min(p0, p1), y: plotTop, w: Math.abs(p1 - p0), h: plotBottom - plotTop, fill: color2 + "26" } : { t: "rect", x: left, y: Math.min(p0, p1), w: right - left, h: Math.abs(p1 - p0), fill: color2 + "26" });
20261
- if (o.label && !g.inLegend(o)) text2(String(o.label), horiz ? Math.max(p0, p1) - 2 : right - 2, horiz ? plotTop + fs2 : Math.min(p0, p1) + fs2 * 1.1, { align: "right", color: "#92400e", size: fs2 * 0.9 });
20698
+ if (o.label && !g.inLegend(o)) text2(String(o.label), horiz ? Math.max(p0, p1) - 2 : right - 2, horiz ? plotTop + fs3 : Math.min(p0, p1) + fs3 * 1.1, { align: "right", color: "#92400e", size: fs3 * 0.9 });
20262
20699
  }
20263
20700
  const zero = vpos(0, baseOf(0));
20264
20701
  out.push(horiz ? { t: "line", x1: zero, y1: plotTop, x2: zero, y2: plotBottom, stroke: "#9ca3af", strokeWidth: 0.75 } : { t: "line", x1: left, y1: zero, x2: right, y2: zero, stroke: "#9ca3af", strokeWidth: 0.75 });
20265
20702
  if (angle) {
20266
- const every = Math.max(1, Math.ceil(fs2 * 1.2 / Math.max(band * sin, 0.01)));
20267
- const maxW = Math.max(10, (catBand - fs2 * cos - fs2 * 0.8) / Math.max(sin, 0.01));
20703
+ const every = Math.max(1, Math.ceil(fs3 * 1.2 / Math.max(band * sin, 0.01)));
20704
+ const maxW = Math.max(10, (catBand - fs3 * cos - fs3 * 0.8) / Math.max(sin, 0.01));
20268
20705
  data.categories.forEach((c, i) => {
20269
20706
  if (i % every) return;
20270
- const cx = center(i), cy = plotBottom + fs2 * 0.6;
20271
- text2(c, cx, cy + fs2 * 0.35 * cos, { align: angle < 0 ? "right" : "left", maxW, rotate: { a: angle, cx, cy } });
20707
+ const cx = center(i), cy = plotBottom + fs3 * 0.6;
20708
+ text2(c, cx, cy + fs3 * 0.35 * cos, { align: angle < 0 ? "right" : "left", maxW, rotate: { a: angle, cx, cy } });
20272
20709
  });
20273
20710
  if (every > 1) lc.warn(`${who}: ${n5 - Math.ceil(n5 / every)} of ${n5} category labels do not fit even turned, so they are not shown (every bar is drawn)`);
20274
20711
  } else {
20275
- const every = Math.max(1, Math.ceil((horiz ? fs2 * 1.3 : catW + 6) / band));
20712
+ const every = Math.max(1, Math.ceil((horiz ? fs3 * 1.3 : catW + 6) / band));
20276
20713
  data.categories.forEach((c, i) => {
20277
20714
  if (i % every) return;
20278
- if (horiz) text2(c, left - 5, center(i) + fs2 * 0.35, { align: "right", maxW: left - X - 8 - (leftTitle ? fs2 * 1.6 : 0) });
20279
- else text2(c, center(i), plotBottom + fs2 * 1.35, { align: "center", maxW: band * every - 2 });
20715
+ if (horiz) text2(c, left - 5, center(i) + fs3 * 0.35, { align: "right", maxW: left - X - 8 - (leftTitle ? fs3 * 1.6 : 0) });
20716
+ else text2(c, center(i), plotBottom + fs3 * 1.35, { align: "center", maxW: band * every - 2 });
20280
20717
  });
20281
20718
  if (every > 1) lc.warn(`${who}: ${n5 - Math.ceil(n5 / every)} of ${n5} category labels do not fit, so they are not shown (every bar is drawn)`);
20282
20719
  }
@@ -20336,7 +20773,7 @@ function paintCartesian(type, g) {
20336
20773
  pointLink(ci, horiz ? { x: Math.min(ph, pl2) - 2, y: c - band / 2, w: Math.abs(ph - pl2) + 4, h: band } : { x: c - band / 2, y: Math.min(ph, pl2) - 2, w: band, h: Math.abs(ph - pl2) + 4 }, tipOf(r, ci, p));
20337
20774
  if (labelsOn) {
20338
20775
  const q3 = P(c, ph);
20339
- if (horiz) label(labelText(ci, s, p.v), q3.x + 3, q3.y + fs2 * 0.35, { align: "left" });
20776
+ if (horiz) label(labelText(ci, s, p.v), q3.x + 3, q3.y + fs3 * 0.35, { align: "left" });
20340
20777
  else label(labelText(ci, s, p.v), q3.x, q3.y - 3);
20341
20778
  }
20342
20779
  });
@@ -20354,14 +20791,14 @@ function paintCartesian(type, g) {
20354
20791
  if (!labelsOn) return;
20355
20792
  const str = labelText(ci, s, p.v, p.pct ?? share(r, p.v));
20356
20793
  const where = pos === "inside" || pos === "center" || pos === "outside" ? pos : r.stacks ? "center" : "outside";
20357
- const sz = fs2 * 0.9;
20794
+ const sz = fs3 * 0.9;
20358
20795
  const color2 = where === "outside" ? ink : inkOn(fill3);
20359
20796
  const back = horiz ? p1 < p0 : p1 > p0;
20360
20797
  if (where === "center") label(str, rect.x + rect.w / 2, rect.y + rect.h / 2 + sz * 0.35, { color: color2, size: sz });
20361
20798
  else if (where === "inside") {
20362
20799
  if (horiz) label(str, back ? rect.x + 3 : rect.x + rect.w - 3, rect.y + rect.h / 2 + sz * 0.35, { align: back ? "left" : "right", color: color2, size: sz });
20363
20800
  else label(str, rect.x + rect.w / 2, back ? rect.y + rect.h - 3 : rect.y + sz + 2, { color: color2, size: sz });
20364
- } else if (horiz) label(str, Math.max(p0, p1) + 3, rect.y + rect.h / 2 + fs2 * 0.35, { align: "left", size: sz, alt: { x: Math.max(p0, p1) - 3, align: "right", color: inkOn(fill3) } });
20801
+ } else if (horiz) label(str, Math.max(p0, p1) + 3, rect.y + rect.h / 2 + fs3 * 0.35, { align: "left", size: sz, alt: { x: Math.max(p0, p1) - 3, align: "right", color: inkOn(fill3) } });
20365
20802
  else label(str, rect.x + rect.w / 2, Math.min(p0, p1) - 3, { size: sz, alt: { y: Math.min(p0, p1) + sz + 2, color: inkOn(fill3) } });
20366
20803
  });
20367
20804
  continue;
@@ -20388,7 +20825,7 @@ function paintCartesian(type, g) {
20388
20825
  for (const q3 of pts2) pointLink(q3.ci, horiz ? { x: left, y: q3.y - band / 2, w: right - left, h: band } : { x: q3.x - band / 2, y: plotTop, w: band, h: plotBottom - plotTop }, tipOf(r, q3.ci, q3.p));
20389
20826
  if (labelsOn) for (const q3 of pts2) {
20390
20827
  const str = labelText(q3.ci, s, q3.v, q3.p.pct ?? share(r, q3.v));
20391
- const sz = fs2 * 0.85;
20828
+ const sz = fs3 * 0.85;
20392
20829
  if (horiz) label(str, q3.x + 4, q3.y - 3, { align: "left", size: sz, alt: q3.y + sz + 3 });
20393
20830
  else if (pos === "center" || pos === "inside") label(str, q3.x, q3.y + sz * 0.35, { size: sz });
20394
20831
  else label(str, q3.x, q3.y - 4, { size: sz, alt: q3.y + sz + 4 });
@@ -20404,8 +20841,8 @@ function paintCartesian(type, g) {
20404
20841
  out.push(horiz ? { t: "line", x1: p, y1: plotTop, x2: p, y2: plotBottom, stroke: color2, strokeWidth: 1, dash: [4, 3] } : { t: "line", x1: left, y1: p, x2: right, y2: p, stroke: color2, strokeWidth: 1, dash: [4, 3] });
20405
20842
  if (o.label) {
20406
20843
  const s = `${o.label}${o.showValue === false ? "" : ` ${ax[ai2].fmt(v)}`}`;
20407
- if (horiz) text2(s, p + 2, plotTop + fs2, { color: color2, size: fs2 * 0.9 });
20408
- else text2(s, right - 2, p - 2.5, { align: "right", color: color2, size: fs2 * 0.9 });
20844
+ if (horiz) text2(s, p + 2, plotTop + fs3, { color: color2, size: fs3 * 0.9 });
20845
+ else text2(s, right - 2, p - 2.5, { align: "right", color: color2, size: fs3 * 0.9 });
20409
20846
  }
20410
20847
  }
20411
20848
  continue;
@@ -20438,16 +20875,16 @@ function paintCartesian(type, g) {
20438
20875
  out.push({ t: "path", x: 0, y: 0, d: curvePath(pts2, "straight"), fill: null, stroke: color2, strokeWidth: 1.2, ...o.type === "trend" ? { dash: [4, 3] } : {} });
20439
20876
  if (o.label && !g.inLegend(o)) {
20440
20877
  const e2 = pts2[pts2.length - 1];
20441
- if (horiz) text2(String(o.label), e2.x + 3, e2.y + fs2 * 0.35, { color: color2, size: fs2 * 0.9 });
20442
- else text2(String(o.label), Math.min(e2.x, right) - 2, e2.y - 4, { align: "right", color: color2, size: fs2 * 0.9 });
20878
+ if (horiz) text2(String(o.label), e2.x + 3, e2.y + fs3 * 0.35, { color: color2, size: fs3 * 0.9 });
20879
+ else text2(String(o.label), Math.min(e2.x, right) - 2, e2.y - 4, { align: "right", color: color2, size: fs3 * 0.9 });
20443
20880
  }
20444
20881
  }
20445
20882
  }
20446
20883
  function robustWindow(vals) {
20447
20884
  const s = vals.filter(Number.isFinite).sort((a, b) => a - b);
20448
20885
  if (s.length < 2) return null;
20449
- const at2 = (q3) => s[Math.min(s.length - 1, Math.floor(q3 * (s.length - 1)))];
20450
- const p1 = at2(0.01), p99 = at2(0.99);
20886
+ const at3 = (q3) => s[Math.min(s.length - 1, Math.floor(q3 * (s.length - 1)))];
20887
+ const p1 = at3(0.01), p99 = at3(0.99);
20451
20888
  return { p1, p99, extreme: p99 > p1 && s[s.length - 1] - s[0] > 5 * (p99 - p1) };
20452
20889
  }
20453
20890
  function rowPoints(type, g) {
@@ -20484,7 +20921,7 @@ function rowPoints(type, g) {
20484
20921
  return sets;
20485
20922
  }
20486
20923
  function paintXY(type, g) {
20487
- const { item, ctx, lc, out, X, W: W2, top, bottom, fs: fs2, font, text: text2, label, labelsOn, axes, who, grid, anim } = g;
20924
+ const { item, ctx, lc, out, X, W: W2, top, bottom, fs: fs3, font, text: text2, label, labelsOn, axes, who, grid, anim } = g;
20488
20925
  const sets = rowPoints(type, g);
20489
20926
  g.xy = sets;
20490
20927
  if (!sets.some((x) => x.pts.length)) {
@@ -20527,11 +20964,11 @@ function paintXY(type, g) {
20527
20964
  ylo = clipY.lo;
20528
20965
  yhi = clipY.hi;
20529
20966
  }
20530
- const ay = valueAxis(ys, ylo, yhi, ymp, { includeZero: false, pad: 0.05, len: bottom - top, fs: fs2, fmt: fmtY, lc, who, name: "y" });
20531
- const axx = valueAxis(xs, xlo, xhi, xmp, { includeZero: false, pad: 0.05, len: W2, fs: fs2, fmt: fmtX, lc, who, name: "x" });
20967
+ const ay = valueAxis(ys, ylo, yhi, ymp, { includeZero: false, pad: 0.05, len: bottom - top, fs: fs3, fmt: fmtY, lc, who, name: "y" });
20968
+ const axx = valueAxis(xs, xlo, xhi, xmp, { includeZero: false, pad: 0.05, len: W2, fs: fs3, fmt: fmtX, lc, who, name: "x" });
20532
20969
  const leftTitle = ys.title, bottomTitle = xs.title || item.xTitle;
20533
- const left = X + 10 + (leftTitle ? fs2 * 1.6 : 0) + Math.max(...ay.ticks.map((t) => lc.m.width(fmtY(t), font, fs2)));
20534
- const right = X + W2 - 6, pb = bottom - fs2 * 1.8 - (bottomTitle ? fs2 * 1.6 : 0), pt = top + fs2 * 0.6;
20970
+ const left = X + 10 + (leftTitle ? fs3 * 1.6 : 0) + Math.max(...ay.ticks.map((t) => lc.m.width(fmtY(t), font, fs3)));
20971
+ const right = X + W2 - 6, pb = bottom - fs3 * 1.8 - (bottomTitle ? fs3 * 1.6 : 0), pt = top + fs3 * 0.6;
20535
20972
  const maxR = Math.max(4, Math.min(right - left, pb - pt) / 12);
20536
20973
  const ins = type === "bubble" ? maxR : 0;
20537
20974
  const clamp2 = (v) => Math.max(0, Math.min(1, v ?? 0));
@@ -20544,16 +20981,16 @@ function paintXY(type, g) {
20544
20981
  return ys.reversed ? pt + ins + fr * (pb - pt - 2 * ins) : pb - ins - fr * (pb - pt - 2 * ins);
20545
20982
  };
20546
20983
  if (bottomTitle) text2(bottomTitle, (left + right) / 2, bottom - 2, { align: "center", color: "#6b7280" });
20547
- if (leftTitle) text2(leftTitle, X + 4 + fs2, (pt + pb) / 2, { align: "center", color: "#6b7280", rotate: { a: -90, cx: X + 4 + fs2, cy: (pt + pb) / 2 } });
20984
+ if (leftTitle) text2(leftTitle, X + 4 + fs3, (pt + pb) / 2, { align: "center", color: "#6b7280", rotate: { a: -90, cx: X + 4 + fs3, cy: (pt + pb) / 2 } });
20548
20985
  for (const t of ay.ticks) {
20549
20986
  if (ys.gridlines !== false) out.push({ t: "line", x1: left, y1: py(t), x2: right, y2: py(t), stroke: grid, strokeWidth: 0.5 });
20550
- text2(fmtY(t), left - 5, py(t) + fs2 * 0.35, { align: "right" });
20987
+ text2(fmtY(t), left - 5, py(t) + fs3 * 0.35, { align: "right" });
20551
20988
  }
20552
- const tw = Math.max(...axx.ticks.map((t) => lc.m.width(fmtX(t), font, fs2)));
20989
+ const tw = Math.max(...axx.ticks.map((t) => lc.m.width(fmtX(t), font, fs3)));
20553
20990
  const every = Math.max(1, Math.ceil((tw + 6) / (Math.abs(right - left) / Math.max(1, axx.ticks.length - 1))));
20554
20991
  axx.ticks.forEach((t, i) => {
20555
20992
  if (xs.gridlines) out.push({ t: "line", x1: px(t), y1: pt, x2: px(t), y2: pb, stroke: grid, strokeWidth: 0.5 });
20556
- if (i % every === 0) text2(fmtX(t), px(t), pb + fs2 * 1.35, { align: "center" });
20993
+ if (i % every === 0) text2(fmtX(t), px(t), pb + fs3 * 1.35, { align: "center" });
20557
20994
  });
20558
20995
  out.push({ t: "line", x1: left, y1: pb, x2: right, y2: pb, stroke: "#9ca3af", strokeWidth: 0.75 });
20559
20996
  const overlays = overlaysOf(item, lc, who);
@@ -20572,11 +21009,11 @@ function paintXY(type, g) {
20572
21009
  out.push(tag2(e2, anim && { k: anim === "grow" ? "scale" : "fade", i: j }));
20573
21010
  const isClipped = clipped && beyond(p) || pastAxis(p);
20574
21011
  if (isClipped) out.push({ t: "ellipse", cx: e2.cx, cy: e2.cy, rx: r + 1.6, ry: r + 1.6, fill: "none", stroke: col3, strokeWidth: 0.9 });
20575
- if (item.tooltips !== false && (type === "bubble" || multi || isClipped)) g.links.push({ t: "link", x: e2.cx - r, y: e2.cy - r, w: r * 2, h: r * 2, action: null, tip: `${multi ? `${s.name}: ` : ""}${fmtX(p.x)}, ${fmtY(p.y)}${type === "bubble" ? ` (${toText(p.size, null, ctx)})` : ""}${isClipped ? clipped && beyond(p) ? " (outlier, drawn at the edge)" : " (outside the axis range you set, draw\
20576
- n at the edge)" : ""}` });
21012
+ if (item.tooltips !== false && (type === "bubble" || multi || isClipped)) g.links.push({ t: "link", x: e2.cx - r, y: e2.cy - r, w: r * 2, h: r * 2, action: null, tip: `${multi ? `${s.name}: ` : ""}${fmtX(p.x)}, ${fmtY(p.y)}${type === "bubble" ? ` (${toText(p.size, null, ctx)})` : ""}${isClipped ? clipped && beyond(p) ? " (outlier, drawn at the edge)" : (" (outside the axis range you set, draw"+
21013
+ "n at the edge)") : ""}` });
20577
21014
  if (labelsOn) {
20578
21015
  const str = item.labelTemplate ? String(item.labelTemplate).slice(0, 500).replace(/\{(\w+)\}/g, (all, k) => ({ value: fmtY(p.y), x: fmtX(p.x), series: s.name, size: toText(p.size, null, ctx) })[k.toLowerCase()] ?? all) : fmtY(p.y);
20579
- label(str, e2.cx, e2.cy - r - 2, { size: fs2 * 0.85 });
21016
+ label(str, e2.cx, e2.cy - r - 2, { size: fs3 * 0.85 });
20580
21017
  }
20581
21018
  });
20582
21019
  }
@@ -20585,7 +21022,7 @@ n at the edge)" : ""}` });
20585
21022
  if (o.type === "line") {
20586
21023
  for (const v of overlayValues(o, g)) {
20587
21024
  out.push({ t: "line", x1: left, y1: py(v), x2: right, y2: py(v), stroke: color2, strokeWidth: 1, dash: [4, 3] });
20588
- if (o.label) text2(`${o.label} ${fmtY(v)}`, right - 2, py(v) - 2.5, { align: "right", color: color2, size: fs2 * 0.9 });
21025
+ if (o.label) text2(`${o.label} ${fmtY(v)}`, right - 2, py(v) - 2.5, { align: "right", color: color2, size: fs3 * 0.9 });
20589
21026
  }
20590
21027
  } else if (o.type === "trend") {
20591
21028
  const set = sets[Math.max(0, Math.min(sets.length - 1, Math.floor(Number(o.series)) || 0))];
@@ -20604,24 +21041,24 @@ n at the edge)" : ""}` });
20604
21041
  }
20605
21042
  if (pts2.length > 1) {
20606
21043
  out.push({ t: "path", x: 0, y: 0, d: curvePath(pts2, "straight"), fill: null, stroke: color2, strokeWidth: 1.2, dash: [4, 3] });
20607
- if (o.label && !g.inLegend(o)) text2(String(o.label), pts2[pts2.length - 1].x - 2, pts2[pts2.length - 1].y - 4, { align: "right", color: color2, size: fs2 * 0.9 });
21044
+ if (o.label && !g.inLegend(o)) text2(String(o.label), pts2[pts2.length - 1].x - 2, pts2[pts2.length - 1].y - 4, { align: "right", color: color2, size: fs3 * 0.9 });
20608
21045
  }
20609
21046
  }
20610
21047
  }
20611
21048
  }
20612
21049
  function paintPolar(g, sets) {
20613
- const { item, ctx, out, X, W: W2, top, bottom, fs: fs2, text: text2, grid, axes, lc, who, anim } = g;
21050
+ const { item, ctx, out, X, W: W2, top, bottom, fs: fs3, text: text2, grid, axes, lc, who, anim } = g;
20614
21051
  const cx = X + W2 / 2, cy = (top + bottom) / 2;
20615
- const R2 = Math.max(6, Math.min(W2, bottom - top) / 2 - fs2 * 2);
21052
+ const R2 = Math.max(6, Math.min(W2, bottom - top) / 2 - fs3 * 2);
20616
21053
  let hi = 0, lo = 0;
20617
21054
  for (const st of sets) for (const p of st.pts) {
20618
21055
  hi = Math.max(hi, p.y);
20619
21056
  lo = Math.min(lo, p.y);
20620
21057
  }
20621
21058
  const fmtY = (v) => toText(v, axes.y?.format || item.valueFormat || "N0", ctx);
20622
- const ay = valueAxis(axes.y, lo, hi, Infinity, { includeZero: true, len: R2 * 2, fs: fs2, fmt: fmtY, lc, who, name: "radius" });
21059
+ const ay = valueAxis(axes.y, lo, hi, Infinity, { includeZero: true, len: R2 * 2, fs: fs3, fmt: fmtY, lc, who, name: "radius" });
20623
21060
  const rad = (v) => Math.max(0, Math.min(1, ay.frac(v) ?? 0)) * R2;
20624
- const at2 = (deg, r) => {
21061
+ const at3 = (deg, r) => {
20625
21062
  const a = (deg - 90) * Math.PI / 180;
20626
21063
  return { x: cx + Math.cos(a) * r, y: cy + Math.sin(a) * r };
20627
21064
  };
@@ -20630,13 +21067,13 @@ function paintPolar(g, sets) {
20630
21067
  if (r > 0) out.push({ t: "ellipse", cx, cy, rx: r, ry: r, fill: null, stroke: grid, strokeWidth: 0.5 });
20631
21068
  }
20632
21069
  for (let d = 0; d < 360; d += 45) {
20633
- const e2 = at2(d, R2), l = at2(d, R2 + fs2 * 0.9);
21070
+ const e2 = at3(d, R2), l = at3(d, R2 + fs3 * 0.9);
20634
21071
  out.push({ t: "line", x1: cx, y1: cy, x2: e2.x, y2: e2.y, stroke: grid, strokeWidth: 0.5 });
20635
- text2(`${d}°`, l.x, l.y + fs2 * 0.35, { align: Math.abs(l.x - cx) < 1 ? "center" : l.x > cx ? "left" : "right", size: fs2 * 0.85, color: "#6b7280" });
21072
+ text2(`${d}°`, l.x, l.y + fs3 * 0.35, { align: Math.abs(l.x - cx) < 1 ? "center" : l.x > cx ? "left" : "right", size: fs3 * 0.85, color: "#6b7280" });
20636
21073
  }
20637
- for (const t of ay.ticks) if (rad(t) > 0 && rad(t) < R2 - 0.5) text2(fmtY(t), cx + 3, cy - rad(t) + fs2 * 0.3, { size: fs2 * 0.8, color: "#6b7280" });
21074
+ for (const t of ay.ticks) if (rad(t) > 0 && rad(t) < R2 - 0.5) text2(fmtY(t), cx + 3, cy - rad(t) + fs3 * 0.3, { size: fs3 * 0.8, color: "#6b7280" });
20638
21075
  for (const { s, pts: pts2, i } of sets) {
20639
- const q3 = pts2.map((p) => ({ ...at2(p.x, rad(p.y)), p }));
21076
+ const q3 = pts2.map((p) => ({ ...at3(p.x, rad(p.y)), p }));
20640
21077
  if (s.def.type === "line" || s.def.type === "area") {
20641
21078
  const deg = (e2) => (e2.p.x % 360 + 360) % 360;
20642
21079
  const sorted = [...q3].sort((a, b) => deg(a) - deg(b));
@@ -21341,14 +21778,14 @@ function paintMap(item, ctx, lc, base) {
21341
21778
  }
21342
21779
  const out = [];
21343
21780
  const font = resolveFontKey(base.fontFamily, "normal", "normal");
21344
- const fs2 = Math.max(6, Number(item.fontSize) || 7);
21781
+ const fs3 = Math.max(6, Number(item.fontSize) || 7);
21345
21782
  const text2 = (s, x, y, align = "left") => {
21346
- const str = String(s), w = lc.m.width(str, font, fs2);
21347
- out.push({ t: "text", font, size: fs2, color: "#374151", lines: [{ x: align === "right" ? x - w : x, y, text: str, w }] });
21783
+ const str = String(s), w = lc.m.width(str, font, fs3);
21784
+ out.push({ t: "text", font, size: fs3, color: "#374151", lines: [{ x: align === "right" ? x - w : x, y, text: str, w }] });
21348
21785
  };
21349
21786
  const pts2 = [...shapes.flatMap((s) => s.polys.flat(2)), ...lines.flatMap((l) => l.lines.flat(1)), ...points.map((p) => [p.lon, p.lat])].map(([lon, lat]) => project(lon, lat));
21350
21787
  if (!pts2.length) {
21351
- text2("No shapes or points to draw", item.x + 4, fs2 + 4);
21788
+ text2("No shapes or points to draw", item.x + 4, fs3 + 4);
21352
21789
  return out;
21353
21790
  }
21354
21791
  const showLegend = item.legend !== "none" && values.size > 0;
@@ -21414,14 +21851,14 @@ function paintMap(item, ctx, lc, base) {
21414
21851
  const [cx, cy] = toXY(p.lon, p.lat);
21415
21852
  const r = p.size != null && maxSize > 0 ? Math.max(1, maxR * Math.sqrt(Math.max(0, p.size) / maxSize)) : 3;
21416
21853
  out.push({ t: "ellipse", cx, cy, rx: r, ry: r, fill: item.pointColor || "#dc2626", stroke: "#ffffff", strokeWidth: 0.5 });
21417
- if (p.label != null && p.label !== "") text2(p.label, cx + r + 2, cy + fs2 / 3);
21854
+ if (p.label != null && p.label !== "") text2(p.label, cx + r + 2, cy + fs3 / 3);
21418
21855
  }
21419
21856
  if (showLegend) {
21420
21857
  const ly = H + 4;
21421
21858
  if (nk) {
21422
21859
  const step3 = (hi - lo) / nk;
21423
21860
  const labels = Array.from({ length: nk }, (_, i) => `${fmt2(lo + step3 * i)} – ${fmt2(i === nk - 1 ? hi : lo + step3 * (i + 1))}`);
21424
- const ws = labels.map((s) => 10 + lc.m.width(s, font, fs2) + 8);
21861
+ const ws = labels.map((s) => 10 + lc.m.width(s, font, fs3) + 8);
21425
21862
  let lx = item.x + Math.max(0, (W2 - ws.reduce((a, b) => a + b, 0)) / 2);
21426
21863
  labels.forEach((s, i) => {
21427
21864
  out.push({ t: "rect", x: lx, y: ly, w: 8, h: 8, fill: mix(low, high, i / (nk - 1)) });
@@ -22335,10 +22772,10 @@ function buildTree(groups, rows, ctx, lc, who, axis, state) {
22335
22772
  }
22336
22773
  const seen = /* @__PURE__ */ new Set(), late = [];
22337
22774
  let deep = false;
22338
- const visit = (x, d, path2) => {
22775
+ const visit = (x, d, path3) => {
22339
22776
  seen.add(x);
22340
22777
  x.depth = d;
22341
- x.path = `${path2}/${x.text}`;
22778
+ x.path = `${path3}/${x.text}`;
22342
22779
  let all = x.rows;
22343
22780
  const kids = [];
22344
22781
  for (const c of x.rec || []) {
@@ -22436,7 +22873,7 @@ function visible(root, groups) {
22436
22873
  for (let p = n5; p && p.level >= 0; p = p.parent) c.unshift(p);
22437
22874
  return c;
22438
22875
  };
22439
- const walk = (n5, l) => {
22876
+ const walk2 = (n5, l) => {
22440
22877
  const g = groups[l];
22441
22878
  const total = { kind: "total", node: n5, level: l, chain: chainOf(n5) };
22442
22879
  if (g.total === "before") out.push(total);
@@ -22451,11 +22888,11 @@ function visible(root, groups) {
22451
22888
  for (const c of n5.children || []) {
22452
22889
  if (l === groups.length - 1) leaf(c);
22453
22890
  else if (!c.open) out.push({ kind: "collapsed", node: c, level: l, chain: chainOf(c) });
22454
- else walk(c, l + 1);
22891
+ else walk2(c, l + 1);
22455
22892
  }
22456
22893
  if (g.total === "after") out.push(total);
22457
22894
  };
22458
- walk(root, 0);
22895
+ walk2(root, 0);
22459
22896
  return out;
22460
22897
  }
22461
22898
  function spans(entries) {
@@ -22710,10 +23147,10 @@ function sliceColumns(o) {
22710
23147
  if (k >= 2) {
22711
23148
  const base = Math.floor(blocks.length / k), extra = blocks.length % k;
22712
23149
  const even = [];
22713
- let at2 = 0;
23150
+ let at3 = 0;
22714
23151
  for (let p = 0; p < k; p++) {
22715
- const part2 = blocks.slice(at2, at2 + base + (p < extra ? 1 : 0));
22716
- at2 += part2.length;
23152
+ const part2 = blocks.slice(at3, at3 + base + (p < extra ? 1 : 0));
23153
+ at3 += part2.length;
22717
23154
  even.push({ from: part2[0].from, to: part2[part2.length - 1].to, w: part2.reduce((s, b) => s + b.w, 0) });
22718
23155
  }
22719
23156
  if (even.every((s) => s.w <= avail + EPS)) sets = even;
@@ -22842,16 +23279,16 @@ function sliceColumns(o) {
22842
23279
  function rowCells(cells, ncols) {
22843
23280
  const list2 = Array.isArray(cells) ? cells : [];
22844
23281
  const span = (c) => Math.max(1, Math.floor(Number(c?.colSpan)) || 1);
22845
- const at2 = new Array(ncols).fill(null);
23282
+ const at3 = new Array(ncols).fill(null);
22846
23283
  const covered = [];
22847
23284
  if (list2.length < ncols && list2.some((c) => span(c) > 1)) {
22848
23285
  let pos = 0;
22849
23286
  for (const c of list2) {
22850
23287
  if (pos >= ncols) break;
22851
- at2[pos] = c ?? null;
23288
+ at3[pos] = c ?? null;
22852
23289
  pos += span(c);
22853
23290
  }
22854
- return { at: at2, covered };
23291
+ return { at: at3, covered };
22855
23292
  }
22856
23293
  let until = -1, by = -1;
22857
23294
  for (let k = 0; k < Math.min(list2.length, ncols); k++) {
@@ -22860,13 +23297,13 @@ function rowCells(cells, ncols) {
22860
23297
  if (c) covered.push([k, by]);
22861
23298
  continue;
22862
23299
  }
22863
- at2[k] = c ?? null;
23300
+ at3[k] = c ?? null;
22864
23301
  if (span(c) > 1) {
22865
23302
  until = k + span(c) - 1;
22866
23303
  by = k;
22867
23304
  }
22868
23305
  }
22869
- return { at: at2, covered };
23306
+ return { at: at3, covered };
22870
23307
  }
22871
23308
 
22872
23309
  // src/engine/items/index.js
@@ -22930,20 +23367,20 @@ function paintTextbox(item, lc, ctx, forcedH) {
22930
23367
  const size0 = Number(st.fontSize) || 9;
22931
23368
  const shrink = (min, fits, step3) => {
22932
23369
  const steps = Number.isFinite(size0) ? Math.max(0, Math.floor((size0 - min) / step3 + 1e-9)) : 0;
22933
- const at2 = (i) => {
23370
+ const at3 = (i) => {
22934
23371
  const s2 = { ...st, fontSize: Math.max(min, size0 - step3 * (i + 1)) };
22935
23372
  return { s2, t2: layoutTextLines(text2, s2, layoutW, lc.m) };
22936
23373
  };
22937
23374
  let lo = 0, hi = steps - 1, best = null;
22938
23375
  while (lo <= hi) {
22939
23376
  const mid = Math.floor((lo + hi) / 2);
22940
- const c = at2(mid);
23377
+ const c = at3(mid);
22941
23378
  if (fits(c.t2)) {
22942
23379
  best = c;
22943
23380
  hi = mid - 1;
22944
23381
  } else lo = mid + 1;
22945
23382
  }
22946
- return { best, last: steps > 0 ? () => at2(steps - 1) : null };
23383
+ return { best, last: steps > 0 ? () => at3(steps - 1) : null };
22947
23384
  };
22948
23385
  const fitsBox = (t) => t.needed <= layoutH + GROW_TOLERANCE;
22949
23386
  if (item.shrinkToFit && !fitsBox(tl)) {
@@ -23182,9 +23619,9 @@ function fitColumns(item, cols, rows, tctx, lc) {
23182
23619
  const nat = cols.map(() => 0);
23183
23620
  const measure = (row, ctx) => {
23184
23621
  const rst = resolveStyle([lc.base, lc.named?.[item.styleName], item.style, row.style], ctx);
23185
- const { at: at2 } = rowCells(row.cells, cols.length);
23622
+ const { at: at3 } = rowCells(row.cells, cols.length);
23186
23623
  for (let ci = 0; ci < cols.length; ci++) {
23187
- const cell = at2[ci];
23624
+ const cell = at3[ci];
23188
23625
  if (!auto[ci] || !cell || (cell.colSpan || 1) > 1 || cell.item) continue;
23189
23626
  let v;
23190
23627
  try {
@@ -23314,10 +23751,10 @@ register("table", {
23314
23751
  const cells = [];
23315
23752
  let started = null;
23316
23753
  let need = row.height || 18;
23317
- let at2 = cellsAt.get(row);
23318
- if (!at2) cellsAt.set(row, at2 = rowCells(row.cells, cols.length).at);
23754
+ let at3 = cellsAt.get(row);
23755
+ if (!at3) cellsAt.set(row, at3 = rowCells(row.cells, cols.length).at);
23319
23756
  for (let ci = 0; ci < cols.length; ci++) {
23320
- const cell = at2[ci];
23757
+ const cell = at3[ci];
23321
23758
  if (!cell || covered(ci)) continue;
23322
23759
  const span = Math.max(1, Math.min(cell.colSpan || 1, cols.length - ci));
23323
23760
  let cw = 0;
@@ -23494,8 +23931,8 @@ register("table", {
23494
23931
  cellLinks(add2, s, u.height, kind, s.level);
23495
23932
  if (s.toggle) add2.push(toggleLink(s, s.w, u.height));
23496
23933
  }
23497
- const at2 = u.items.findIndex((it) => itemLeft(it) >= s.x + s.w - 0.01);
23498
- u.items.splice(at2 < 0 ? u.items.length : at2, 0, ...add2);
23934
+ const at3 = u.items.findIndex((it) => itemLeft(it) >= s.x + s.w - 0.01);
23935
+ u.items.splice(at3 < 0 ? u.items.length : at3, 0, ...add2);
23499
23936
  });
23500
23937
  if (s.tl.needed > s.units[0].height + GROW_TOLERANCE || s.st.verticalAlign && s.st.verticalAlign !== "top") {
23501
23938
  const id = `${item.name || item.type}:span:${lc.nextId()}`;
@@ -23633,8 +24070,8 @@ register("table", {
23633
24070
  gctx.level = depth;
23634
24071
  if (g.indent) gctx.indent = (ctx.indent || 0) + depth * Number(g.indent);
23635
24072
  }
23636
- const path2 = `${parentPath}/${bk.text}`;
23637
- const tkey = `${item.name || item.type}|${level}|${path2}`;
24073
+ const path3 = `${parentPath}/${bk.text}`;
24074
+ const tkey = `${item.name || item.type}|${level}|${path3}`;
23638
24075
  const dflt = kids && g.expandLevels != null ? depth < Number(g.expandLevels) : !g.initiallyCollapsed;
23639
24076
  const open = !g.collapsible ? true : lc.state?.toggles?.[tkey] ?? dflt;
23640
24077
  const start = units.length;
@@ -23655,9 +24092,9 @@ register("table", {
23655
24092
  if (rep) gctx.__rep = rep;
23656
24093
  const ch = kids?.get(bk) || [];
23657
24094
  if (open) {
23658
- emit2(level + 1, bk.rows, gctx, [...chain, sc], path2);
24095
+ emit2(level + 1, bk.rows, gctx, [...chain, sc], path3);
23659
24096
  if (ch.length && depth + 1 >= MAX_TREE_DEPTH) lc.warn(`${item.name || item.type}: the group "${gname}" is more than ${MAX_TREE_DEPTH} levels deep; deeper rows are listed at the top level`);
23660
- else ch.forEach((c, ci) => node3(c, ci, ch, depth + 1, path2));
24097
+ else ch.forEach((c, ci) => node3(c, ci, ch, depth + 1, path3));
23661
24098
  } else {
23662
24099
  const rs = recOf.get(bk) || bk.rows;
23663
24100
  for (const s of [...chain, sc]) {
@@ -23685,7 +24122,7 @@ register("table", {
23685
24122
  if (g.newSection) units[start].sectionStart = true;
23686
24123
  if (g.pageBreak === "after" && bi < sibs.length - 1) units[units.length - 1].breakAfter = true;
23687
24124
  if (g.keepTogether) {
23688
- const id = `${item.name || item.type}:g${level}:${path2}:${lc.nextId()}`;
24125
+ const id = `${item.name || item.type}:g${level}:${path3}:${lc.nextId()}`;
23689
24126
  for (let k = start; k < units.length; k++) if (!units[k].block) {
23690
24127
  units[k].block = id;
23691
24128
  if (cont) units[k].blockOpen = true;
@@ -27189,14 +27626,14 @@ var REPORT_SCHEMA = {
27189
27626
  "additionalProperties": true
27190
27627
  },
27191
27628
  "Report": {
27192
- "description": "A ReportWright report definition (pagewright/report@1).",
27629
+ "description": "A ReportWright report definition (reportwright/report@1).",
27193
27630
  "type": "object",
27194
27631
  "properties": {
27195
27632
  "$schema": {
27196
- "description": "pagewright/report@1; reportwright/report@1 is the same format under the new name.",
27633
+ "description": "reportwright/report@1; pagewright/report@1 (deprecated, the name before the rename) is the same format.",
27197
27634
  "enum": [
27198
- "pagewright/report@1",
27199
- "reportwright/report@1"
27635
+ "reportwright/report@1",
27636
+ "pagewright/report@1"
27200
27637
  ]
27201
27638
  },
27202
27639
  "name": {
@@ -27314,7 +27751,7 @@ var REPORT_SCHEMA = {
27314
27751
  ],
27315
27752
  "examples": [
27316
27753
  {
27317
- "$schema": "pagewright/report@1",
27754
+ "$schema": "reportwright/report@1",
27318
27755
  "name": "Invoice",
27319
27756
  "page": {
27320
27757
  "size": "A4",
@@ -27432,11 +27869,11 @@ var REPORT_SCHEMA = {
27432
27869
  // src/engine/schema/validate.js
27433
27870
  init_format();
27434
27871
  init_units();
27435
- var SCHEMA_ID = "pagewright/report@1";
27436
- var SCHEMA_ALIAS = "reportwright/report@1";
27437
- var ITEM_KEYS = new Set("id type name x y w h style styleName items hidden layer locked label alt value dataSet canGrow canShrink action bookmark tooltip keepTogether pageBreakBefore pageBreakAfter pageBreakBetween newSection filters sort groups groupBy groupAdjacent inheritRows columns header detail footer repeatHeader widowControl noRowsText pageBreakEvery cells rows rowGroup rowGroups columnGro\
27438
- up columnGroups values value valueFormat rowSort columnSort rowTotals columnTotals cellStyle headerStyle totalStyle corner partProps library part properties overflow overflowTo src fit headingLevel rotate shrinkToFit minFontSize shrinkStep tocDots tocLink tocPage format chartType series seriesGroup category title legend palette stacked valueAxis xTitle maxCategories outliers categorySort categoryF\
27439
- ormat showValues labelPosition symbology quietZone report params text toggle initiallyCollapsed collapsible expandLevels repeatColumns columnGap rowHeaderWidth anim animation visual comment notes description".split(" "));
27872
+ var SCHEMA_ID = "reportwright/report@1";
27873
+ var SCHEMA_ALIAS = "pagewright/report@1";
27874
+ var ITEM_KEYS = new Set(("id type name x y w h style styleName items hidden layer locked label alt value dataSet canGrow canShrink action bookmark tooltip keepTogether pageBreakBefore pageBreakAfter pageBreakBetween newSection filters sort groups groupBy groupAdjacent inheritRows columns header detail footer repeatHeader widowControl noRowsText pageBreakEvery cells rows rowGroup rowGroups columnGro"+
27875
+ "up columnGroups values value valueFormat rowSort columnSort rowTotals columnTotals cellStyle headerStyle totalStyle corner partProps library part properties overflow overflowTo src fit headingLevel rotate shrinkToFit minFontSize shrinkStep tocDots tocLink tocPage format chartType series seriesGroup category title legend palette stacked valueAxis xTitle maxCategories outliers categorySort categoryF"+
27876
+ "ormat showValues labelPosition symbology quietZone report params text toggle initiallyCollapsed collapsible expandLevels repeatColumns columnGap rowHeaderWidth anim animation visual comment notes description").split(" "));
27440
27877
  var NO_SERIES_CHARTS = /* @__PURE__ */ new Set(["gantt"]);
27441
27878
  function looksLikeLink(it) {
27442
27879
  if (it.type !== "textbox" || it.action && it.action.type && it.action.type !== "none") return false;
@@ -27447,8 +27884,8 @@ function looksLikeLink(it) {
27447
27884
  const [r, g, b] = m.slice(1).map((h) => parseInt(h, 16));
27448
27885
  return b > 150 && b > r + 60 && b > g + 30;
27449
27886
  }
27450
- var DEF_KEYS = new Set("$schema name description locale currency timeZone page parameters dataSources dataSets styles sections functions layers images theme themeDef master nullPropagation caseSensitive naturalSort nullOrder collation arithmetic bandRows version id tags author folder stylesheet parts partProperties dashboard comment notes customCode libraries liveParameters parameterLayout drafts \
27451
- history nonFinite".split(" "));
27887
+ var DEF_KEYS = new Set(("$schema name description locale currency timeZone page parameters dataSources dataSets styles sections functions layers images theme themeDef master nullPropagation caseSensitive naturalSort nullOrder collation arithmetic bandRows version id tags author folder stylesheet parts partProperties dashboard comment notes customCode libraries liveParameters parameterLayout drafts "+
27888
+ "history nonFinite").split(" "));
27452
27889
  for (const k of Object.keys(REPORT_SCHEMA.$defs.Report.properties)) DEF_KEYS.add(k);
27453
27890
  var lev = (a, b) => {
27454
27891
  if (Math.abs(a.length - b.length) > 2) return 3;
@@ -27498,17 +27935,29 @@ function formatIssue(f4, label, out) {
27498
27935
  }
27499
27936
  function sortIssues(sort, label, out) {
27500
27937
  sort.forEach((s, i) => {
27501
- const at2 = `${label}, sort ${i + 1}`;
27938
+ const at3 = `${label}, sort ${i + 1}`;
27502
27939
  if (!s || typeof s !== "object" || Array.isArray(s) || !("by" in s)) {
27503
- out.push(`${at2}: a sort entry is {by, dir}, e.g. {"by": "=Fields.Name", "dir": "asc"}; this one has no "by" and is ignored`);
27940
+ out.push(`${at3}: a sort entry is {by, dir}, e.g. {"by": "=Fields.Name", "dir": "asc"}; this one has no "by" and is ignored`);
27504
27941
  return;
27505
27942
  }
27506
27943
  for (const k of Object.keys(s)) {
27507
27944
  if (k === "by" || k === "dir" || k.startsWith("_")) continue;
27508
27945
  const g = SORT_ALIAS[k] || didYouMean(k, ["by", "dir"]);
27509
- out.push(`${at2}: "${k}" is ignored; a sort entry is {by, dir}${g ? ` (did you mean "${g}"?)` : ""}`);
27946
+ out.push(`${at3}: "${k}" is ignored; a sort entry is {by, dir}${g ? ` (did you mean "${g}"?)` : ""}`);
27947
+ }
27948
+ if (s.dir != null && !["asc", "desc"].includes(s.dir)) out.push(`${at3}: "dir" is ${JSON.stringify(s.dir)}; expected "asc" or "desc"`);
27949
+ });
27950
+ }
27951
+ var FILTER_KEYS = ["expr", "op", "value", "value2", "skipBlank"];
27952
+ var FILTER_ALIAS = { expression: "expr", field: "expr", by: "expr", operator: "op", comparison: "op", values: "value", value1: "value" };
27953
+ function filterIssues(filters, label, out) {
27954
+ filters.forEach((f4, i) => {
27955
+ if (!f4 || typeof f4 !== "object" || Array.isArray(f4)) return;
27956
+ for (const k of Object.keys(f4)) {
27957
+ if (FILTER_KEYS.includes(k) || k.startsWith("_")) continue;
27958
+ const g = FILTER_ALIAS[k] || didYouMean(k, FILTER_KEYS);
27959
+ out.push(`${label}, filter ${i + 1}: "${k}" is ignored; a filter is {${FILTER_KEYS.join(", ")}}${g ? ` (did you mean "${g}"?)` : ""}`);
27510
27960
  }
27511
- if (s.dir != null && !["asc", "desc"].includes(s.dir)) out.push(`${at2}: "dir" is ${JSON.stringify(s.dir)}; expected "asc" or "desc"`);
27512
27961
  });
27513
27962
  }
27514
27963
  var SCHEMA_ITEMS = (() => {
@@ -27593,6 +28042,7 @@ function validate(def) {
27593
28042
  } else if (!srcNames.has(d.source)) errors.push(`Data set "${d.name}" uses the source "${d.source}", which does not exist`);
27594
28043
  dsNames.add(d.name);
27595
28044
  if (Array.isArray(d.sort)) sortIssues(d.sort, `Data set "${d.name}"`, warnings);
28045
+ if (Array.isArray(d.filters)) filterIssues(d.filters, `Data set "${d.name}"`, warnings);
27596
28046
  }
27597
28047
  const names = /* @__PURE__ */ new Set();
27598
28048
  const check = (where, v, label) => {
@@ -27655,6 +28105,7 @@ function validate(def) {
27655
28105
  warnings.push(`${label}: there is no named style "${it.styleName}"${g ? ` (did you mean "${g}"?)` : ""}; it is ignored`);
27656
28106
  }
27657
28107
  if (Array.isArray(it.sort)) sortIssues(it.sort, label, warnings);
28108
+ if (Array.isArray(it.filters)) filterIssues(it.filters, label, warnings);
27658
28109
  if (it.type === "chart" && it.legend != null && it.legend !== "bottom" && it.legend !== "none") {
27659
28110
  const shown2 = typeof it.legend === "object" ? `is an object (${JSON.stringify(it.legend).slice(0, 60)})` : `is ${JSON.stringify(it.legend)}`;
27660
28111
  warnings.push(`${label}: "legend" ${shown2}; only "bottom" (show the legend) or "none" (hide it) is supported, and the legend is drawn at the bottom`);
@@ -28054,15 +28505,15 @@ async function loadParts(def, get, warn, budget) {
28054
28505
  for (const q3 of Array.isArray(p.properties) ? p.properties : []) if (q3?.name) props[q3.name] = q3.default ?? null;
28055
28506
  const inner2 = [];
28056
28507
  let own = 0;
28057
- const walk = (list2) => {
28508
+ const walk2 = (list2) => {
28058
28509
  for (const x of list2 || []) {
28059
28510
  if (!x || typeof x !== "object") continue;
28060
28511
  own++;
28061
28512
  if (x.type === "part") inner2.push(x);
28062
- walk(x.items);
28513
+ walk2(x.items);
28063
28514
  }
28064
28515
  };
28065
- walk([item]);
28516
+ walk2([item]);
28066
28517
  parts.set(key, { item, props, own, inner: inner2.filter((x) => x !== item) });
28067
28518
  libs.set(lib, d);
28068
28519
  for (const x of inner2) {
@@ -28880,20 +29331,20 @@ async function encryptPdf(doc, opt) {
28880
29331
  return cat(iv, await aesCbc(fileKey, iv, bytes));
28881
29332
  };
28882
29333
  const seen = /* @__PURE__ */ new Set();
28883
- const walk = async (obj) => {
29334
+ const walk2 = async (obj) => {
28884
29335
  if (obj instanceof PDFString || obj instanceof PDFHexString) return PDFHexString.of(hex2(await enc(obj.asBytes())));
28885
29336
  if (obj instanceof PDFArray) {
28886
- for (let i = 0; i < obj.size(); i++) obj.set(i, await walk(obj.get(i)));
29337
+ for (let i = 0; i < obj.size(); i++) obj.set(i, await walk2(obj.get(i)));
28887
29338
  return obj;
28888
29339
  }
28889
29340
  if (obj instanceof PDFDict) {
28890
29341
  if (seen.has(obj)) return obj;
28891
29342
  seen.add(obj);
28892
- for (const [k, v] of obj.entries()) obj.set(k, await walk(v));
29343
+ for (const [k, v] of obj.entries()) obj.set(k, await walk2(v));
28893
29344
  return obj;
28894
29345
  }
28895
29346
  if (obj instanceof PDFStream) {
28896
- await walk(obj.dict);
29347
+ await walk2(obj.dict);
28897
29348
  const contents = obj instanceof PDFRawStream ? obj.contents : (
28898
29349
  /** @type {any} */
28899
29350
  obj.getContents()
@@ -28902,7 +29353,7 @@ async function encryptPdf(doc, opt) {
28902
29353
  }
28903
29354
  return obj;
28904
29355
  };
28905
- for (const [ref2, obj] of ctx.enumerateIndirectObjects()) ctx.assign(ref2, await walk(obj));
29356
+ for (const [ref2, obj] of ctx.enumerateIndirectObjects()) ctx.assign(ref2, await walk2(obj));
28906
29357
  const encrypt = ctx.obj({
28907
29358
  Filter: "Standard",
28908
29359
  V: 5,
@@ -28997,9 +29448,9 @@ ${pdfa ? `<rdf:Description rdf:about="" xmlns:pdfaid="http://www.aiim.org/pdfa/n
28997
29448
  </x:xmpmeta>
28998
29449
  <?xpacket end="w"?>`;
28999
29450
  }
29000
- var PDFUA_SCHEMA = `<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"><pdfaExtension:schemas><rdf:Bag><rdf:li rdf:parseType="Resource"><pdfaSchema:schema>PDF/UA identification schema</pdfaSchema:schema><pdfaSchema:namespaceURI>http://www.aiim.or\
29001
- g/pdfua/ns/id/</pdfaSchema:namespaceURI><pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix><pdfaSchema:property><rdf:Seq><rdf:li rdf:parseType="Resource"><pdfaProperty:name>part</pdfaProperty:name><pdfaProperty:valueType>Integer</pdfaProperty:valueType><pdfaProperty:category>internal</pdfaProperty:category><pdfaProperty:description>PDF/UA version identifier</pdfaProperty:description></rdf:li></rdf:Seq>\
29002
- </pdfaSchema:property></rdf:li></rdf:Bag></pdfaExtension:schemas></rdf:Description>
29451
+ var PDFUA_SCHEMA = `<rdf:Description rdf:about="" xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/" xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#" xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#"><pdfaExtension:schemas><rdf:Bag><rdf:li rdf:parseType="Resource"><pdfaSchema:schema>PDF/UA identification schema</pdfaSchema:schema><pdfaSchema:namespaceURI>http://www.aiim.or${
29452
+ ""}g/pdfua/ns/id/</pdfaSchema:namespaceURI><pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix><pdfaSchema:property><rdf:Seq><rdf:li rdf:parseType="Resource"><pdfaProperty:name>part</pdfaProperty:name><pdfaProperty:valueType>Integer</pdfaProperty:valueType><pdfaProperty:category>internal</pdfaProperty:category><pdfaProperty:description>PDF/UA version identifier</pdfaProperty:description></rdf:li></rdf:Seq>${
29453
+ ""}</pdfaSchema:property></rdf:li></rdf:Bag></pdfaExtension:schemas></rdf:Description>
29003
29454
  `;
29004
29455
  function setMetadata(doc, xmp) {
29005
29456
  const ctx = doc.context;
@@ -29176,8 +29627,8 @@ function parseSvg(text2) {
29176
29627
  }
29177
29628
  var clamp01 = (v) => Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : 1;
29178
29629
  var paint = (v) => v === "currentColor" ? "#000" : /^url\(/.test(String(v || "")) ? "none" : v;
29179
- function drawSvg(page, svg, at2) {
29180
- const place = [at2.sx, 0, 0, -at2.sy, at2.x, at2.y + svg.h * at2.sy];
29630
+ function drawSvg(page, svg, at3) {
29631
+ const place = [at3.sx, 0, 0, -at3.sy, at3.x, at3.y + svg.h * at3.sy];
29181
29632
  for (const s of svg.shapes) {
29182
29633
  if (!s.fill && !s.stroke) continue;
29183
29634
  const m = mul(mul(place, s.m), [1, 0, 0, -1, 0, 0]);
@@ -29220,8 +29671,8 @@ function imageHref(src, proxyBase = "") {
29220
29671
  return "";
29221
29672
  }
29222
29673
  var n = (v) => Math.round(v * 100) / 100;
29223
- var ANIM_CSS = "<style>@media (prefers-reduced-motion:no-preference){.pw-a{transform-box:fill-box;animation:pw-fade .55s ease-out both}.pw-a-growY{animation-name:pw-growY}.pw-a-growX{animation-name:pw-growX}.pw-a-scale{animation-name:pw-scale}@keyframes pw-fade{from{opacity:0}}@keyframes pw-growY{from{transform:scaleY(0)}}@keyframes pw-growX{from{transform:scaleX(0)}}@keyframes pw-scale{from{trans\
29224
- form:scale(0);opacity:0}}}</style>";
29674
+ var ANIM_CSS = ("<style>@media (prefers-reduced-motion:no-preference){.pw-a{transform-box:fill-box;animation:pw-fade .55s ease-out both}.pw-a-growY{animation-name:pw-growY}.pw-a-growX{animation-name:pw-growX}.pw-a-scale{animation-name:pw-scale}@keyframes pw-fade{from{opacity:0}}@keyframes pw-growY{from{transform:scaleY(0)}}@keyframes pw-growX{from{transform:scaleX(0)}}@keyframes pw-scale{from{trans"+
29675
+ "form:scale(0);opacity:0}}}</style>");
29225
29676
  var ANIM_KINDS = /* @__PURE__ */ new Set(["growY", "growX", "scale", "fade"]);
29226
29677
  var ANIM_ORIGIN = { bottom: "center bottom", top: "center top", left: "left center", right: "right center" };
29227
29678
  function pageToSvg(page, w, h, { background = true, animate = false, box = void 0, outline: outline2 = null, proxyBase = "" } = {}) {
@@ -29785,15 +30236,15 @@ function createTagger(model, doc) {
29785
30236
  const refOf = /* @__PURE__ */ new Map();
29786
30237
  const all = [];
29787
30238
  for (const t of root.tables?.values() || []) regular(t);
29788
- const walk = (n5) => {
30239
+ const walk2 = (n5) => {
29789
30240
  refOf.set(n5, ctx.nextRef());
29790
30241
  all.push(n5);
29791
30242
  for (const k of n5.kids) if (k.S) {
29792
30243
  k.parent ||= n5;
29793
- walk(k);
30244
+ walk2(k);
29794
30245
  }
29795
30246
  };
29796
- walk(root);
30247
+ walk2(root);
29797
30248
  const nums2 = [];
29798
30249
  let key = 0;
29799
30250
  pages.forEach((pg, pi) => {
@@ -30200,27 +30651,27 @@ async function* readerIter(rs) {
30200
30651
  r.releaseLock?.();
30201
30652
  }
30202
30653
  }
30203
- function splitPath(path2) {
30204
- if (!path2 || path2 === "$") return [];
30205
- const p = path2.startsWith("$") ? path2.slice(1) : "." + path2;
30654
+ function splitPath(path3) {
30655
+ if (!path3 || path3 === "$") return [];
30656
+ const p = path3.startsWith("$") ? path3.slice(1) : "." + path3;
30206
30657
  const re = /\.([A-Za-z_$][\w$]*)|\['([^']+)'\]|\["([^"]+)"\]|(\[\*\])$/y;
30207
30658
  const keys = [];
30208
- let at2 = 0;
30209
- while (at2 < p.length) {
30210
- re.lastIndex = at2;
30659
+ let at3 = 0;
30660
+ while (at3 < p.length) {
30661
+ re.lastIndex = at3;
30211
30662
  const m = re.exec(p);
30212
30663
  if (!m) return null;
30213
30664
  if (!m[4]) keys.push(m[1] ?? m[2] ?? m[3]);
30214
- at2 = re.lastIndex;
30665
+ at3 = re.lastIndex;
30215
30666
  }
30216
30667
  return keys;
30217
30668
  }
30218
- async function* jsonRows(body, path2, { maxElementBytes = 1048576, maxWholeBytes = 64 * 1048576, maxDepth = 512, batch = 1e3 } = {}) {
30219
- const keys = splitPath(path2);
30669
+ async function* jsonRows(body, path3, { maxElementBytes = 1048576, maxWholeBytes = 64 * 1048576, maxDepth = 512, batch = 1e3 } = {}) {
30670
+ const keys = splitPath(path3);
30220
30671
  let whole = keys == null ? "" : null;
30221
30672
  let buf = "", i = 0;
30222
30673
  const stack2 = [];
30223
- let inStr = false, esc8 = false, strStart = -1;
30674
+ let inStr = false, esc9 = false, strStart = -1;
30224
30675
  let target = -1;
30225
30676
  let elemStart = -1, done = false;
30226
30677
  let out = [], outLen = 0;
@@ -30246,8 +30697,8 @@ async function* jsonRows(body, path2, { maxElementBytes = 1048576, maxWholeBytes
30246
30697
  for (; i < buf.length; i++) {
30247
30698
  const c = buf.charCodeAt(i);
30248
30699
  if (inStr) {
30249
- if (esc8) esc8 = false;
30250
- else if (c === 92) esc8 = true;
30700
+ if (esc9) esc9 = false;
30701
+ else if (c === 92) esc9 = true;
30251
30702
  else if (c === 34) {
30252
30703
  inStr = false;
30253
30704
  const top = stack2[stack2.length - 1];
@@ -30329,7 +30780,7 @@ async function* jsonRows(body, path2, { maxElementBytes = 1048576, maxWholeBytes
30329
30780
  }
30330
30781
  if (whole != null) {
30331
30782
  const raw = whole === "" ? null : JSON.parse(whole);
30332
- let { rows } = jsonPathRows(raw, path2 || "$");
30783
+ let { rows } = jsonPathRows(raw, path3 || "$");
30333
30784
  if (rows == null) rows = [];
30334
30785
  else if (!Array.isArray(rows)) rows = [rows];
30335
30786
  for (let k = 0; k < rows.length; k += batch) yield rows.slice(k, k + batch);
@@ -30594,7 +31045,7 @@ async function planStream(def0, opts) {
30594
31045
  const setCtx = { ...baseCtx, ...ds.caseSensitive != null ? { caseSensitive: ds.caseSensitive === true } : {} };
30595
31046
  const tctx = { ...baseCtx };
30596
31047
  const cellsAt = /* @__PURE__ */ new WeakMap();
30597
- const at2 = (row) => {
31048
+ const at3 = (row) => {
30598
31049
  let a = cellsAt.get(row);
30599
31050
  if (!a) cellsAt.set(row, a = rowCells(row.cells, ncols).at);
30600
31051
  return a;
@@ -30603,7 +31054,7 @@ async function planStream(def0, opts) {
30603
31054
  if (row.hidden === true) return null;
30604
31055
  const rst = resolveStyle([base, named?.[item.styleName], item.style, named?.[row.styleName], row.style], ctx);
30605
31056
  const cells = [];
30606
- const a = at2(row);
31057
+ const a = at3(row);
30607
31058
  for (let ci = 0; ci < ncols; ci++) {
30608
31059
  const cell = a[ci];
30609
31060
  if (!cell) continue;
@@ -30709,11 +31160,11 @@ async function planStream(def0, opts) {
30709
31160
  }
30710
31161
  return out;
30711
31162
  };
30712
- const ready = (fs2) => {
30713
- fields = seen = fs2;
30714
- plain2 = plainOf(fs2);
30715
- calc = fs2.filter((fd) => fd.expr);
30716
- fopts = new Map(fs2.map((fd) => [fd, optFor(fd)]));
31163
+ const ready = (fs3) => {
31164
+ fields = seen = fs3;
31165
+ plain2 = plainOf(fs3);
31166
+ calc = fs3.filter((fd) => fd.expr);
31167
+ fopts = new Map(fs3.map((fd) => [fd, optFor(fd)]));
30717
31168
  cc = { ...baseCtx, dataSets: {}, fields: null };
30718
31169
  };
30719
31170
  if (fields) ready(fields);
@@ -30807,7 +31258,7 @@ async function planStream(def0, opts) {
30807
31258
  let seq = 0;
30808
31259
  for await (const r of inOrder(true)) {
30809
31260
  gc.fields = r;
30810
- let path2 = "";
31261
+ let path3 = "";
30811
31262
  const g = [];
30812
31263
  for (let l = 0; l < groups.length; l++) {
30813
31264
  let key;
@@ -30817,12 +31268,12 @@ async function planStream(def0, opts) {
30817
31268
  warn(`${item.name || item.type} group: ${e2.message}`);
30818
31269
  key = "#Error";
30819
31270
  }
30820
- path2 += `\0${groupKeyText(key, tctx)}`;
30821
- let p = paths[l].get(path2);
31271
+ path3 += `\0${groupKeyText(key, tctx)}`;
31272
+ let p = paths[l].get(path3);
30822
31273
  if (!p) {
30823
- keyText += path2.length;
31274
+ keyText += path3.length;
30824
31275
  if (ord > 1e6 || keyText > 64 * 1048576) throw Object.assign(new Error("Too many groups (or group keys too long) to stream: filter the data."), { status: 413, fallBack: true });
30825
- paths[l].set(path2, p = [ord++, key]);
31276
+ paths[l].set(path3, p = [ord++, key]);
30826
31277
  }
30827
31278
  g.push(p);
30828
31279
  }
@@ -30850,7 +31301,7 @@ async function planStream(def0, opts) {
30850
31301
  const foldCells = (rows2) => {
30851
31302
  const out = [];
30852
31303
  for (const row of rows2 || []) {
30853
- const a = at2(row);
31304
+ const a = at3(row);
30854
31305
  for (let ci = 0; ci < ncols; ci++) {
30855
31306
  const f4 = a[ci] && foldOf(a[ci].value);
30856
31307
  if (f4) out.push({ row, ci, ...f4 });
@@ -30972,8 +31423,8 @@ async function planStream(def0, opts) {
30972
31423
  }
30973
31424
  return { name: item.name, columns: cols.map((c) => c.width), title: def.name || "", timeZone: timeZone || null, locale: def.locale || null, currency: def.currency || null, warnings, rows, records: inOrder, grouped: displayOrder, fieldList, stats };
30974
31425
  }
30975
- function listAt(raw, path2) {
30976
- let { rows } = jsonPathRows(raw, path2 || "$");
31426
+ function listAt(raw, path3) {
31427
+ let { rows } = jsonPathRows(raw, path3 || "$");
30977
31428
  if (rows == null) rows = [];
30978
31429
  return Array.isArray(rows) ? rows : [rows];
30979
31430
  }
@@ -31059,7 +31510,7 @@ async function planPaged(def0, opts = {}) {
31059
31510
  if (!fields.length) return no2("undeclared fields (no rows to detect them from)");
31060
31511
  ds = { ...ds, fields };
31061
31512
  }
31062
- const strip = (fields) => fields.map(({ expr, path: path2, ...f4 }) => f4);
31513
+ const strip = (fields) => fields.map(({ expr, path: path3, ...f4 }) => f4);
31063
31514
  const windowDef = (first, last, done) => {
31064
31515
  const t = { ...gtable, sort: void 0, filters: void 0 };
31065
31516
  if (!last) delete t.footer;
@@ -31093,11 +31544,11 @@ async function planPaged(def0, opts = {}) {
31093
31544
  []
31094
31545
  ), pages: 0 };
31095
31546
  const L = groups.length;
31096
- const newAcc = (fs2) => fs2.map((f4) => f4.fn === "countrows" ? { n: 0 } : { agg: aggregator(f4.fn, fctx), err: null });
31547
+ const newAcc = (fs3) => fs3.map((f4) => f4.fn === "countrows" ? { n: 0 } : { agg: aggregator(f4.fn, fctx), err: null });
31097
31548
  const value = (a) => a.n ?? (a.err ? "#Error" : a.agg.value());
31098
- const addTo = (fs2, acc, r) => {
31549
+ const addTo = (fs3, acc, r) => {
31099
31550
  fctx.fields = r;
31100
- fs2.forEach((f4, i) => {
31551
+ fs3.forEach((f4, i) => {
31101
31552
  const a = acc[i];
31102
31553
  if (a.n != null) a.n++;
31103
31554
  else if (!a.err) {
@@ -31229,7 +31680,7 @@ async function planPaged(def0, opts = {}) {
31229
31680
  const m = await render(job.def, { ...opts, exportData: !!(opts.exportData || opts.tagged), sources: { __rows: { rows: job.rows } }, pageWindow: job.pageWindow });
31230
31681
  return { pages: m.pages, count: m.pages.length, nextFirst: m.pages[job.keep]?.firstRow, bookmarks: m.bookmarks, headings: m.headings, warnings: m.warnings };
31231
31682
  };
31232
- const run = o.run || local, at2 = o.run ? 2 * Math.max(1, Number(o.parallel) || 1) : 1;
31683
+ const run = o.run || local, at3 = o.run ? 2 * Math.max(1, Number(o.parallel) || 1) : 1;
31233
31684
  const queue = (
31234
31685
  /** @type {any[]} */
31235
31686
  []
@@ -31282,7 +31733,7 @@ async function planPaged(def0, opts = {}) {
31282
31733
  res.catch(() => {
31283
31734
  });
31284
31735
  queue.push({ job, res });
31285
- if (queue.length >= at2) {
31736
+ if (queue.length >= at3) {
31286
31737
  const q3 = queue.shift();
31287
31738
  yield* handOut(q3.job, await q3.res);
31288
31739
  }
@@ -32143,10 +32594,10 @@ function createPdfStream(sink, opt) {
32143
32594
  const flush = async () => {
32144
32595
  if (!size) return;
32145
32596
  const all = new Uint8Array(size);
32146
- let at2 = 0;
32597
+ let at3 = 0;
32147
32598
  for (const p of parts) {
32148
- all.set(p, at2);
32149
- at2 += p.length;
32599
+ all.set(p, at3);
32600
+ at3 += p.length;
32150
32601
  }
32151
32602
  parts = [];
32152
32603
  size = 0;
@@ -32446,10 +32897,10 @@ endobj
32446
32897
  row[6] = i & 255;
32447
32898
  }
32448
32899
  }
32449
- const at2 = (n5 - from) * 8;
32450
- rows[at2] = 2;
32900
+ const at3 = (n5 - from) * 8;
32901
+ rows[at3] = 2;
32451
32902
  for (let b = 0; b < 7; b++) {
32452
- rows[at2 + 1 + b] = row[b] - prev[b] & 255;
32903
+ rows[at3 + 1 + b] = row[b] - prev[b] & 255;
32453
32904
  prev[b] = row[b];
32454
32905
  }
32455
32906
  }
@@ -33427,10 +33878,10 @@ async function ownWriter(model, fontStore2, opt) {
33427
33878
  } }
33428
33879
  );
33429
33880
  const out = new Uint8Array(parts.reduce((n5, p) => n5 + p.length, 0));
33430
- let at2 = 0;
33881
+ let at3 = 0;
33431
33882
  for (const p of parts) {
33432
- out.set(p, at2);
33433
- at2 += p.length;
33883
+ out.set(p, at3);
33884
+ at3 += p.length;
33434
33885
  }
33435
33886
  return out;
33436
33887
  }
@@ -33486,7 +33937,7 @@ function plainEncoding(pf) {
33486
33937
  return w * size / f4.unitsPerEm;
33487
33938
  };
33488
33939
  const lit2 = /* @__PURE__ */ new Map();
33489
- const esc8 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
33940
+ const esc9 = (b) => b === 40 || b === 41 || b === 92 ? "\\" + String.fromCharCode(b) : b === 13 ? "\\r" : String.fromCharCode(b);
33490
33941
  e2.tjOf = (text2) => {
33491
33942
  let out = "", cur = "", any = false;
33492
33943
  for (const ch of text2) {
@@ -33515,7 +33966,7 @@ function plainEncoding(pf) {
33515
33966
  let b = lit2.get(cp);
33516
33967
  if (b === void 0) {
33517
33968
  const id = f4.glyphForCodePoint(cp).id;
33518
- lit2.set(cp, b = esc8(id >> 8) + esc8(id & 255));
33969
+ lit2.set(cp, b = esc9(id >> 8) + esc9(id & 255));
33519
33970
  }
33520
33971
  out += b;
33521
33972
  }
@@ -33624,24 +34075,24 @@ var usedKB = () => {
33624
34075
  var live = /* @__PURE__ */ new Set();
33625
34076
  var hooked = false;
33626
34077
  var sweep = () => {
33627
- const fs2 = node2("node:fs");
34078
+ const fs3 = node2("node:fs");
33628
34079
  for (const d of live) {
33629
34080
  try {
33630
- fs2.rmSync(d, { recursive: true, force: true });
34081
+ fs3.rmSync(d, { recursive: true, force: true });
33631
34082
  } catch {
33632
34083
  }
33633
34084
  }
33634
34085
  live.clear();
33635
34086
  };
33636
34087
  function sweepStale(root, staleMs) {
33637
- const fs2 = node2("node:fs"), path2 = node2("node:path");
34088
+ const fs3 = node2("node:fs"), path3 = node2("node:path");
33638
34089
  try {
33639
- for (const n5 of fs2.readdirSync(root)) {
34090
+ for (const n5 of fs3.readdirSync(root)) {
33640
34091
  if (!n5.startsWith("pw-spill-")) continue;
33641
- const d = path2.join(root, n5);
34092
+ const d = path3.join(root, n5);
33642
34093
  if (live.has(d)) continue;
33643
34094
  try {
33644
- if (Date.now() - fs2.statSync(d).mtimeMs > staleMs) fs2.rmSync(d, { recursive: true, force: true });
34095
+ if (Date.now() - fs3.statSync(d).mtimeMs > staleMs) fs3.rmSync(d, { recursive: true, force: true });
33645
34096
  } catch {
33646
34097
  }
33647
34098
  }
@@ -33650,9 +34101,9 @@ function sweepStale(root, staleMs) {
33650
34101
  }
33651
34102
  var MB = 1048576;
33652
34103
  function spillSorter({ runMB = 8, mergeMB = 4, run = 1e4, runBytes = runMB * MB, frame: frame3 = 200, maxMB = 2048, totalMB = 8192, dir: root = node2("node:os").tmpdir(), staleMs = 18e4 } = {}) {
33653
- const fs2 = node2("node:fs"), path2 = node2("node:path"), v8 = node2("node:v8"), { threadId } = node2("node:worker_threads");
34104
+ const fs3 = node2("node:fs"), path3 = node2("node:path"), v8 = node2("node:v8"), { threadId } = node2("node:worker_threads");
33654
34105
  try {
33655
- fs2.accessSync(root, fs2.constants.W_OK);
34106
+ fs3.accessSync(root, fs3.constants.W_OK);
33656
34107
  } catch {
33657
34108
  throw Object.assign(new Error(`spill.dir "${root}" does not exist or is not writable`), { status: 400 });
33658
34109
  }
@@ -33671,15 +34122,15 @@ function spillSorter({ runMB = 8, mergeMB = 4, run = 1e4, runBytes = runMB * MB,
33671
34122
  };
33672
34123
  const writeRun = async (batches) => {
33673
34124
  if (!dir) {
33674
- dir = fs2.mkdtempSync(path2.join(root, `pw-spill-${process.pid}-${threadId}-`));
34125
+ dir = fs3.mkdtempSync(path3.join(root, `pw-spill-${process.pid}-${threadId}-`));
33675
34126
  live.add(dir);
33676
34127
  if (!hooked) {
33677
34128
  hooked = true;
33678
34129
  process.once("exit", sweep);
33679
34130
  }
33680
34131
  }
33681
- const file = path2.join(dir, `run-${made++}`);
33682
- const fh = await fs2.promises.open(file, "wx", 384);
34132
+ const file = path3.join(dir, `run-${made++}`);
34133
+ const fh = await fs3.promises.open(file, "wx", 384);
33683
34134
  let size = 0;
33684
34135
  sizes.set(file, 0);
33685
34136
  try {
@@ -33808,7 +34259,7 @@ function spillSorter({ runMB = 8, mergeMB = 4, run = 1e4, runBytes = runMB * MB,
33808
34259
  for (const f4 of group2) {
33809
34260
  onDisk -= sizes.get(f4) || 0;
33810
34261
  sizes.delete(f4);
33811
- await fs2.promises.rm(f4, { force: true });
34262
+ await fs3.promises.rm(f4, { force: true });
33812
34263
  }
33813
34264
  account();
33814
34265
  passes++;
@@ -33826,7 +34277,7 @@ function spillSorter({ runMB = 8, mergeMB = 4, run = 1e4, runBytes = runMB * MB,
33826
34277
  const d = dir;
33827
34278
  dir = null;
33828
34279
  live.delete(d);
33829
- await fs2.promises.rm(d, { recursive: true, force: true }).catch(() => {
34280
+ await fs3.promises.rm(d, { recursive: true, force: true }).catch(() => {
33830
34281
  });
33831
34282
  }
33832
34283
  },
@@ -33848,8 +34299,8 @@ function approx(x, d = 0) {
33848
34299
  return n5;
33849
34300
  }
33850
34301
  async function openRun(file) {
33851
- const fs2 = node2("node:fs"), v8 = node2("node:v8");
33852
- const fh = await fs2.promises.open(file, "r");
34302
+ const fs3 = node2("node:fs"), v8 = node2("node:v8");
34303
+ const fh = await fs3.promises.open(file, "r");
33853
34304
  let pos = 0, batch = [], i = 0;
33854
34305
  const head = Buffer.alloc(4);
33855
34306
  return {
@@ -33954,7 +34405,7 @@ function setNameStrings(name, strings) {
33954
34405
  o.setUint16(0, 0);
33955
34406
  o.setUint16(2, count);
33956
34407
  o.setUint16(4, 6 + 12 * count);
33957
- let at2 = 6 + 12 * count;
34408
+ let at3 = 6 + 12 * count;
33958
34409
  recs.forEach((r, i) => {
33959
34410
  const p = 6 + 12 * i;
33960
34411
  o.setUint16(p, r.platform);
@@ -33962,9 +34413,9 @@ function setNameStrings(name, strings) {
33962
34413
  o.setUint16(p + 4, r.lang);
33963
34414
  o.setUint16(p + 6, r.id);
33964
34415
  o.setUint16(p + 8, r.raw.length);
33965
- o.setUint16(p + 10, at2 - (6 + 12 * count));
33966
- out.set(r.raw, at2);
33967
- at2 += r.raw.length;
34416
+ o.setUint16(p + 10, at3 - (6 + 12 * count));
34417
+ out.set(r.raw, at3);
34418
+ at3 += r.raw.length;
33968
34419
  });
33969
34420
  return out;
33970
34421
  }
@@ -34304,7 +34755,7 @@ async function htmlOf(model, fontStore2, opt) {
34304
34755
  }
34305
34756
  faces.push(`@font-face{font-family:"${fontFamilyCss(key)}";src:url(data:font/ttf;base64,${b642(bytes)}) format("truetype")}`);
34306
34757
  }
34307
- const esc8 = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;");
34758
+ const esc9 = (s) => String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;");
34308
34759
  const anchors = /* @__PURE__ */ new Map();
34309
34760
  const jumpTo = (a) => {
34310
34761
  const to = a.page ? a : model.bookmarks?.find((b) => b.label === a.target) || model.headings?.find((b) => b.label === a.target);
@@ -34337,7 +34788,7 @@ async function htmlOf(model, fontStore2, opt) {
34337
34788
  } catch {
34338
34789
  }
34339
34790
  if (t && "href" in t) return `<a href="${attr(t.href)}"${t.external ? ' target="_blank" rel="noopener"' : ""}><rect${a}/>${ttl}</a>`;
34340
- if (t && "off" in t) return `<g class="pw-off"><rect${a}/><title>${esc8(t.off)}</title></g>`;
34791
+ if (t && "off" in t) return `<g class="pw-off"><rect${a}/><title>${esc9(t.off)}</title></g>`;
34341
34792
  return `<rect${a}/>`;
34342
34793
  }));
34343
34794
  const pages = model.pages.map((p, i) => {
@@ -34353,7 +34804,7 @@ async function htmlOf(model, fontStore2, opt) {
34353
34804
  const lang = opt.lang && /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/.test(opt.lang) ? opt.lang : "en";
34354
34805
  return `<!doctype html>
34355
34806
  <html lang="${data ? lang : "en"}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
34356
- ${csp}<title>${esc8(opt.title || model.name || "Report")}</title>
34807
+ ${csp}<title>${esc9(opt.title || model.name || "Report")}</title>
34357
34808
  <style>
34358
34809
  ${faces.join("\n")}
34359
34810
  html{background:#e6eaee}body{margin:0;padding:24px 12px;display:flex;flex-direction:column;align-items:center;gap:18px;font-family:system-ui,sans-serif}
@@ -34362,7 +34813,7 @@ html{background:#e6eaee}body{margin:0;padding:24px 12px;display:flex;flex-direct
34362
34813
  .page svg{display:block;width:100%;height:auto}
34363
34814
  @media print{html{background:#fff}body{padding:0;gap:0}.page{box-shadow:none;width:100%;break-after:page}@page{size:${model.width}pt ${model.height}pt;margin:0}}
34364
34815
  ${data ? DATA_CSS + "\n" : ""}</style></head><body>
34365
- ${data ? `<nav class="pw-bar" id="pw-bar" hidden><button type="button" data-view="pages" aria-pressed="true">${esc8(S3.pages)}</button><button type="button" data-view="tables" aria-pressed="false">${esc8(S3.tables)}</button></nav>
34816
+ ${data ? `<nav class="pw-bar" id="pw-bar" hidden><button type="button" data-view="pages" aria-pressed="true">${esc9(S3.pages)}</button><button type="button" data-view="tables" aria-pressed="false">${esc9(S3.tables)}</button></nav>
34366
34817
  ` : ""}${pages}
34367
34818
  ${data ? `<div id="pw-tables" hidden></div>
34368
34819
  <script type="application/json" id="pw-data">${JSON.stringify({ tables: data, strings: S3 }).replace(/</g, "\\u003c")}</script>
@@ -34522,8 +34973,8 @@ function chartXml(spec, sheet) {
34522
34973
  const per = t === "bubble" ? 3 : 2;
34523
34974
  const body = spec.series.map((s, i) => {
34524
34975
  const c = 1 + i * per, n5 = s.x.length;
34525
- return `<c:ser><c:idx val="${i}"/><c:order val="${i}"/><c:tx><c:strRef><c:f>${ref(sheet, c + 1, 1, c + 1, 1)}</c:f>${strCache([s.name])}</c:strRef></c:tx>${t === "bubble" ? fill(s.color) : `<c:spPr><a:ln w="19050"><a:noFill/></a:ln></c:spPr><c:marker><c:symbol val="circle"/><c:size val="5"/>${fill(s.color)}</c:marker>`}<c:xVal><c:numRef><c:f>${ref(sheet, c, 2, c, n5 + 1)}</c:f>${numCache(s.x)}\
34526
- </c:numRef></c:xVal><c:yVal><c:numRef><c:f>${ref(sheet, c + 1, 2, c + 1, n5 + 1)}</c:f>${numCache(s.y, fmt2)}</c:numRef></c:yVal>` + (t === "bubble" ? `<c:bubbleSize><c:numRef><c:f>${ref(sheet, c + 2, 2, c + 2, n5 + 1)}</c:f>${numCache(s.size || [])}</c:numRef></c:bubbleSize><c:bubble3D val="0"/>` : '<c:smooth val="0"/>') + "</c:ser>";
34976
+ return `<c:ser><c:idx val="${i}"/><c:order val="${i}"/><c:tx><c:strRef><c:f>${ref(sheet, c + 1, 1, c + 1, 1)}</c:f>${strCache([s.name])}</c:strRef></c:tx>${t === "bubble" ? fill(s.color) : `<c:spPr><a:ln w="19050"><a:noFill/></a:ln></c:spPr><c:marker><c:symbol val="circle"/><c:size val="5"/>${fill(s.color)}</c:marker>`}<c:xVal><c:numRef><c:f>${ref(sheet, c, 2, c, n5 + 1)}</c:f>${numCache(s.x)}${
34977
+ ""}</c:numRef></c:xVal><c:yVal><c:numRef><c:f>${ref(sheet, c + 1, 2, c + 1, n5 + 1)}</c:f>${numCache(s.y, fmt2)}</c:numRef></c:yVal>` + (t === "bubble" ? `<c:bubbleSize><c:numRef><c:f>${ref(sheet, c + 2, 2, c + 2, n5 + 1)}</c:f>${numCache(s.size || [])}</c:numRef></c:bubbleSize><c:bubble3D val="0"/>` : '<c:smooth val="0"/>') + "</c:ser>";
34527
34978
  }).join("");
34528
34979
  plot = t === "bubble" ? `<c:bubbleChart><c:varyColors val="0"/>${body}<c:bubbleScale val="100"/>${axIds(false)}</c:bubbleChart>` : `<c:scatterChart><c:scatterStyle val="lineMarker"/><c:varyColors val="0"/>${body}${axIds(false)}</c:scatterChart>`;
34529
34980
  axes = valAx(AX.cat, AX.val, "b", false, "General", spec.xTitle) + valAx(AX.val, AX.cat, "l", false, fmt2, spec.yTitle);
@@ -34534,18 +34985,18 @@ function chartXml(spec, sheet) {
34534
34985
  }
34535
34986
  var axTitle = (t) => t ? title(t) : "";
34536
34987
  function catAx(id, cross, pos, second, t) {
34537
- return `<c:catAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="${second ? 1 : 0}"/><c:axPos val="${pos}"/>${axTitle(t)}<c:numFmt formatCode="General" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffs\
34538
- et val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>`;
34988
+ return `<c:catAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="${second ? 1 : 0}"/><c:axPos val="${pos}"/>${axTitle(t)}<c:numFmt formatCode="General" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="autoZero"/><c:auto val="1"/><c:lblAlgn val="ctr"/><c:lblOffs${
34989
+ ""}et val="100"/><c:noMultiLvlLbl val="0"/></c:catAx>`;
34539
34990
  }
34540
34991
  function valAx(id, cross, pos, second, fmt2, t) {
34541
- return `<c:valAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="${pos}"/>${second ? "" : "<c:majorGridlines/>"}${axTitle(t)}<c:numFmt formatCode="${esc4(fmt2)}" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="${second ? "max" : "autoZero"}"/\
34542
- ><c:crossBetween val="between"/></c:valAx>`;
34992
+ return `<c:valAx><c:axId val="${id}"/><c:scaling><c:orientation val="minMax"/></c:scaling><c:delete val="0"/><c:axPos val="${pos}"/>${second ? "" : "<c:majorGridlines/>"}${axTitle(t)}<c:numFmt formatCode="${esc4(fmt2)}" sourceLinked="0"/><c:majorTickMark val="out"/><c:minorTickMark val="none"/><c:tickLblPos val="nextTo"/><c:crossAx val="${cross}"/><c:crosses val="${second ? "max" : "autoZero"}"/${
34993
+ ""}><c:crossBetween val="between"/></c:valAx>`;
34543
34994
  }
34544
34995
  var PALETTE2 = ["#2563eb", "#16a34a", "#f59e0b", "#dc2626", "#7c3aed", "#0891b2", "#db2777", "#65a30d", "#ea580c", "#475569"];
34545
34996
  var drawingXml = (c0, r0, cols, rows) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
34546
- <xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><xdr:twoCellAnchor editAs="oneCell"><xdr:from><xdr:col>${c0}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:to><xdr:col>${c0 + cols}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0 + rows}</x\
34547
- dr:row><xdr:rowOff>0</xdr:rowOff></xdr:to><xdr:graphicFrame macro=""><xdr:nvGraphicFramePr><xdr:cNvPr id="2" name="Chart 1"/><xdr:cNvGraphicFramePr/></xdr:nvGraphicFramePr><xdr:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xdr:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmln\
34548
- s:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1"/></a:graphicData></a:graphic></xdr:graphicFrame><xdr:clientData/></xdr:twoCellAnchor></xdr:wsDr>`;
34997
+ <xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><xdr:twoCellAnchor editAs="oneCell"><xdr:from><xdr:col>${c0}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:to><xdr:col>${c0 + cols}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${r0 + rows}</x${
34998
+ ""}dr:row><xdr:rowOff>0</xdr:rowOff></xdr:to><xdr:graphicFrame macro=""><xdr:nvGraphicFramePr><xdr:cNvPr id="2" name="Chart 1"/><xdr:cNvGraphicFramePr/></xdr:nvGraphicFramePr><xdr:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xdr:xfrm><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmln${
34999
+ ""}s:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1"/></a:graphicData></a:graphic></xdr:graphicFrame><xdr:clientData/></xdr:twoCellAnchor></xdr:wsDr>`;
34549
35000
  var rels = (list2) => `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
34550
35001
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${list2.join("")}</Relationships>`;
34551
35002
  var rel = (id, type, target) => `<Relationship Id="${id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/${type}" Target="${target}"/>`;
@@ -34583,8 +35034,8 @@ function addCharts(bytes, charts) {
34583
35034
  let ws = read(sheetPath) || "";
34584
35035
  if (!/xmlns:r=/.test(ws.slice(0, 600))) ws = ws.replace("<worksheet ", '<worksheet xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" ');
34585
35036
  const before = ["<legacyDrawing", "<legacyDrawingHF", "<picture", "<oleObjects", "<controls", "<webPublishItems", "<tableParts", "<extLst", "</worksheet>"].map((t) => ws.indexOf(t)).filter((k) => k >= 0);
34586
- const at2 = Math.min(...before);
34587
- write(sheetPath, ws.slice(0, at2) + '<drawing r:id="rIdPW1"/>' + ws.slice(at2));
35037
+ const at3 = Math.min(...before);
35038
+ write(sheetPath, ws.slice(0, at3) + '<drawing r:id="rIdPW1"/>' + ws.slice(at3));
34588
35039
  types = types.replace("</Types>", `<Override PartName="/xl/charts/chartPW${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/><Override PartName="/xl/drawings/drawingPW${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.drawing+xml"/></Types>`);
34589
35040
  });
34590
35041
  write("[Content_Types].xml", types);
@@ -34697,9 +35148,9 @@ var Book = class {
34697
35148
  const [fmt2, bold, fill3] = k.split("|").map(Number);
34698
35149
  return `<xf numFmtId="${fmt2 || 0}" fontId="${bold ? 1 : 0}" fillId="${fill3 ? 2 : 0}" borderId="0" xfId="0"${fmt2 ? ' applyNumberFormat="1"' : ""}${bold ? ' applyFont="1"' : ""}${fill3 ? ' applyFill="1"' : ""}/>`;
34699
35150
  }).join("");
34700
- return `${XML}<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">${fmts ? `<numFmts count="${this.numFmts.size}">${fmts}</numFmts>` : ""}<fonts count="2"><font><sz val="11"/><name val="Calibri"/><family val="2"/></font><font><b/><sz val="11"/><name val="Calibri"/><family val="2"/></font></fonts><fills count="3"><fill><patternFill patternType="none"/></fill><fill><pat\
34701
- ternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="${HEADER_FILL}"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="${this.styles.size}">${xfs}</cellXfs><cellSt\
34702
- yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
35151
+ return `${XML}<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">${fmts ? `<numFmts count="${this.numFmts.size}">${fmts}</numFmts>` : ""}<fonts count="2"><font><sz val="11"/><name val="Calibri"/><family val="2"/></font><font><b/><sz val="11"/><name val="Calibri"/><family val="2"/></font></fonts><fills count="3"><fill><patternFill patternType="none"/></fill><fill><pat${
35152
+ ""}ternFill patternType="gray125"/></fill><fill><patternFill patternType="solid"><fgColor rgb="${HEADER_FILL}"/><bgColor indexed="64"/></patternFill></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="${this.styles.size}">${xfs}</cellXfs><cellSt${
35153
+ ""}yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
34703
35154
  }
34704
35155
  /** The .xlsx bytes. */
34705
35156
  write() {
@@ -34719,8 +35170,8 @@ yles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></s
34719
35170
  const anchors = sh.images.map((im, k) => {
34720
35171
  img++;
34721
35172
  put(`xl/media/image${img}.${im.ext}`, im.bytes);
34722
- return `<xdr:oneCellAnchor><xdr:from><xdr:col>${im.col}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${im.row}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/><xdr:pic><xdr:nvPicPr><xdr:cNvPr id="${k + 2}" name="Picture ${k + 1}"/><xdr:cNvPicPr><a:picLocks noChangeAspect="1"/></xdr:cNvPicPr></xdr:nvPicPr><xdr:blipFill><\
34723
- a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic><xdr:clientData/></xdr:oneCellAnchor>`;
35173
+ return `<xdr:oneCellAnchor><xdr:from><xdr:col>${im.col}</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>${im.row}</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/><xdr:pic><xdr:nvPicPr><xdr:cNvPr id="${k + 2}" name="Picture ${k + 1}"/><xdr:cNvPicPr><a:picLocks noChangeAspect="1"/></xdr:cNvPicPr></xdr:nvPicPr><xdr:blipFill><${
35174
+ ""}a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${Math.round(im.w * 9525)}" cy="${Math.round(im.h * 9525)}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic><xdr:clientData/></xdr:oneCellAnchor>`;
34724
35175
  });
34725
35176
  let first = img - sh.images.length;
34726
35177
  put(`xl/drawings/_rels/drawing${n5}.xml.rels`, rels2(sh.images.map((im, k) => [`rId${k + 1}`, "image", `../media/image${++first}.${im.ext}`])));
@@ -34741,12 +35192,12 @@ a:blip r:embed="rId${k + 1}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill
34741
35192
  put("xl/styles.xml", this.stylesXml());
34742
35193
  put("xl/workbook.xml", `${XML}<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="${R}"><bookViews><workbookView/></bookViews><sheets>${this.sheets.map((s, i) => `<sheet name="${esc4(s.name)}" sheetId="${i + 1}" r:id="rId${i + 1}"/>`).join("")}</sheets><calcPr calcId="171027"${this.fullCalcOnLoad ? ' fullCalcOnLoad="1"' : ""}/></workbook>`);
34743
35194
  put("xl/_rels/workbook.xml.rels", rels2([...this.sheets.map((s, i) => [`rId${i + 1}`, "worksheet", `worksheets/sheet${i + 1}.xml`]), [`rId${this.sheets.length + 1}`, "styles", "styles.xml"]]));
34744
- put("docProps/core.xml", `${XML}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc4(this.title)}</dc:title><dc:creator>${esc4(this.creator)}</dc:creator><dcterms:created xsi:type="dcterms:W\
34745
- 3CDTF">${(/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z")}</dcterms:created></cp:coreProperties>`);
35195
+ put("docProps/core.xml", `${XML}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc4(this.title)}</dc:title><dc:creator>${esc4(this.creator)}</dc:creator><dcterms:created xsi:type="dcterms:W${
35196
+ ""}3CDTF">${(/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z")}</dcterms:created></cp:coreProperties>`);
34746
35197
  put("_rels/.rels", rels2([["rId1", "officeDocument", "xl/workbook.xml"], ["rId2", "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties", "docProps/core.xml"]]));
34747
- put("[Content_Types].xml", `${XML}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Override PartName="/xl/workbo\
34748
- ok.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>${over.map(([p, t]) => `<Override PartName="${p}" ContentType="${t}\
34749
- "/>`).join("")}</Types>`);
35198
+ put("[Content_Types].xml", `${XML}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Override PartName="/xl/workbo${
35199
+ ""}ok.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>${over.map(([p, t]) => `<Override PartName="${p}" ContentType="${t}${
35200
+ ""}"/>`).join("")}</Types>`);
34750
35201
  return out;
34751
35202
  }
34752
35203
  };
@@ -34856,11 +35307,11 @@ function subtotalFn(c, st) {
34856
35307
  }
34857
35308
  return null;
34858
35309
  }
34859
- function totalFormula(rows, at2, c, made) {
34860
- const row = rows[at2];
35310
+ function totalFormula(rows, at3, c, made) {
35311
+ const row = rows[at3];
34861
35312
  if (typeof c.value !== "number" || !Number.isFinite(c.value)) return null;
34862
35313
  const covered = [];
34863
- for (let k = at2 - 1; k >= 0; k--) {
35314
+ for (let k = at3 - 1; k >= 0; k--) {
34864
35315
  const r = rows[k];
34865
35316
  if (r.kind === "header") break;
34866
35317
  if (row.kind === "groupFooter" && (r.kind === "groupFooter" || r.kind === "groupHeader") && r.level <= row.level) break;
@@ -35022,8 +35473,8 @@ init_fonts();
35022
35473
  var TW = 20;
35023
35474
  var EMU = 12700;
35024
35475
  var CONTENT_TYPES = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35025
- <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension="svg" ContentType="image/svg+xml"/><Override Part\
35026
- Name="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`;
35476
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension="svg" ContentType="image/svg+xml"/><Override Part${
35477
+ ""}Name="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`;
35027
35478
  var RELS = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35028
35479
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/></Relationships>`;
35029
35480
  var XML_CHUNK = 4 * 1024 * 1024;
@@ -35148,8 +35599,8 @@ function table(cells, indentPt, pics) {
35148
35599
  }
35149
35600
  return `<w:tr>${r.kind === "header" ? "<w:trPr><w:tblHeader/></w:trPr>" : ""}${tcs.join("")}</w:tr>`;
35150
35601
  }).join("");
35151
- return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${indentPt > 0 ? `<w:tblInd w:w="${Math.round(indentPt * TW)}" w:type="dxa"/>` : ""}<w:tblBorders>${tblB}</w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="60" w:type="dxa"/><w:right w:w="60" w:type="dxa"/></w:tblCellMar></w:tblPr><w:tblGrid>${grid}</w:tblGrid>${out}</w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="0"/\
35152
- ></w:pPr></w:p>`;
35602
+ return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${indentPt > 0 ? `<w:tblInd w:w="${Math.round(indentPt * TW)}" w:type="dxa"/>` : ""}<w:tblBorders>${tblB}</w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="60" w:type="dxa"/><w:right w:w="60" w:type="dxa"/></w:tblCellMar></w:tblPr><w:tblGrid>${grid}</w:tblGrid>${out}</w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="0"/${
35603
+ ""}></w:pPr></w:p>`;
35153
35604
  }
35154
35605
  function layoutRow(row, margin) {
35155
35606
  const cols = [], cells = [];
@@ -35167,8 +35618,8 @@ function layoutRow(row, margin) {
35167
35618
  x = c.x + c.w;
35168
35619
  }
35169
35620
  const ind = row[0].it.clip.x - margin;
35170
- return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${Math.abs(ind) > 0.5 ? `<w:tblInd w:w="${Math.round(ind * TW)}" w:type="dxa"/>` : ""}<w:tblBorders><w:top w:val="nil"/><w:left w:val="nil"/><w:bottom w:val="nil"/><w:right w:val="nil"/><w:insideH w:val="nil"/><w:insideV w:val="nil"/></w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="0" w:type="dxa"/><w:right w:w="0" w:ty\
35171
- pe="dxa"/></w:tblCellMar><w:tblLook w:val="0000"/></w:tblPr><w:tblGrid>${cols.map((w) => `<w:gridCol w:w="${Math.round(w * TW)}"/>`).join("")}</w:tblGrid><w:tr>${cells.join("")}</w:tr></w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="40"/><w:rPr><w:sz w:val="4"/></w:rPr></w:pPr></w:p>`;
35621
+ return `<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/>${Math.abs(ind) > 0.5 ? `<w:tblInd w:w="${Math.round(ind * TW)}" w:type="dxa"/>` : ""}<w:tblBorders><w:top w:val="nil"/><w:left w:val="nil"/><w:bottom w:val="nil"/><w:right w:val="nil"/><w:insideH w:val="nil"/><w:insideV w:val="nil"/></w:tblBorders><w:tblLayout w:type="fixed"/><w:tblCellMar><w:left w:w="0" w:type="dxa"/><w:right w:w="0" w:ty${
35622
+ ""}pe="dxa"/></w:tblCellMar><w:tblLook w:val="0000"/></w:tblPr><w:tblGrid>${cols.map((w) => `<w:gridCol w:w="${Math.round(w * TW)}"/>`).join("")}</w:tblGrid><w:tr>${cells.join("")}</w:tr></w:tbl><w:p><w:pPr><w:spacing w:before="0" w:after="40"/><w:rPr><w:sz w:val="4"/></w:rPr></w:pPr></w:p>`;
35172
35623
  }
35173
35624
  function exportDocx(model, opt = {}) {
35174
35625
  return withDeadline(
@@ -35184,10 +35635,10 @@ async function docxOf(model, opt) {
35184
35635
  chunks.push(u8);
35185
35636
  });
35186
35637
  const bytes = new Uint8Array(chunks.reduce((n5, c) => n5 + c.length, 0));
35187
- let at2 = 0;
35638
+ let at3 = 0;
35188
35639
  for (const c of chunks) {
35189
- bytes.set(c, at2);
35190
- at2 += c.length;
35640
+ bytes.set(c, at3);
35641
+ at3 += c.length;
35191
35642
  }
35192
35643
  return bytes;
35193
35644
  }
@@ -35207,8 +35658,8 @@ async function writeDocx(pages, model, opt, put) {
35207
35658
  const id = ++docPr, cx = Math.max(1, Math.round(pic.w * EMU)), cy = Math.max(1, Math.round(pic.h * EMU));
35208
35659
  const name = `Picture ${id}`, descr = alt ? ` descr="${esc5(alt)}"` : "";
35209
35660
  const ext = svg ? `<a:extLst><a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="${svg}"/></a:ext></a:extLst>` : "";
35210
- return `<w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${cx}" cy="${cy}"/><wp:docPr id="${id}" name="${name}"${descr}/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic><pic:nvPicPr><pic:cNvPr id="${id}" name="${name}"${descr}/\
35211
- ><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
35661
+ return `<w:r><w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="${cx}" cy="${cy}"/><wp:docPr id="${id}" name="${name}"${descr}/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic><pic:nvPicPr><pic:cNvPr id="${id}" name="${name}"${descr}/${
35662
+ ""}><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${cx}" cy="${cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>`;
35212
35663
  };
35213
35664
  const picOpt = { fontStore: opt.fontStore, fetchImage: opt.fetchImage, rasterize: opt.rasterize };
35214
35665
  const pageXml = async (pg) => {
@@ -35351,12 +35802,12 @@ async function writeDocx(pages, model, opt, put) {
35351
35802
  const lang = `<w:lang w:val="${esc5(opt.lang || model.locale || "en-US")}"/>`;
35352
35803
  const headings = [28, 24, 22, 20, 18, 18].map((sz, i) => `<w:style w:type="paragraph" w:styleId="Heading${i + 1}"><w:name w:val="heading ${i + 1}"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:qFormat/><w:pPr><w:keepNext/><w:outlineLvl w:val="${i}"/></w:pPr><w:rPr><w:b/><w:sz w:val="${sz}"/></w:rPr></w:style>`).join("");
35353
35804
  const styles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35354
- <w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Inter" w:hAnsi="Inter" w:cs="Inter"/><w:sz w:val="18"/>${lang}</w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:\
35355
- name w:val="Normal"/></w:style>${headings}</w:styles>`;
35805
+ <w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii="Inter" w:hAnsi="Inter" w:cs="Inter"/><w:sz w:val="18"/>${lang}</w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="0" w:line="240" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:${
35806
+ ""}name w:val="Normal"/></w:style>${headings}</w:styles>`;
35356
35807
  const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
35357
35808
  const core = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35358
- <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc5(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc5(opt.author)}</dc:creator>` : ""}<dcterms:created xsi:type=\
35359
- "dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`;
35809
+ <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc5(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc5(opt.author)}</dc:creator>` : ""}<dcterms:created xsi:type=${
35810
+ ""}"dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`;
35360
35811
  await file("word/_rels/document.xml.rels", strToU83(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
35361
35812
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>${media.map((m) => `<Relationship Id="${m.rid}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/${m.name}"/>`).join("")}</Relationships>`));
35362
35813
  await file("word/styles.xml", strToU83(styles));
@@ -35446,8 +35897,8 @@ async function pptxOf(model, opt) {
35446
35897
  const svg = pic.png && pic.svg ? media(strToU84(pic.svg), "svg") : null;
35447
35898
  const n5 = ++id;
35448
35899
  const ext = svg ? `<a:extLst><a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}"><asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="${svg}"/></a:ext></a:extLst>` : "";
35449
- return `<p:pic><p:nvPicPr><p:cNvPr id="${n5}" name="Picture ${n5}" descr="${esc6(alt)}"/><p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x="${e(pic.x)}" y="${e(pic.y)}"/><a:ext cx="${Math.max(1, e(pic.w))}" cy="${Math.max(1, e(pic.h))}"/><\
35450
- /a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>`;
35900
+ return `<p:pic><p:nvPicPr><p:cNvPr id="${n5}" name="Picture ${n5}" descr="${esc6(alt)}"/><p:cNvPicPr><a:picLocks noChangeAspect="1"/></p:cNvPicPr><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="${main}">${ext}</a:blip><a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr><a:xfrm><a:off x="${e(pic.x)}" y="${e(pic.y)}"/><a:ext cx="${Math.max(1, e(pic.w))}" cy="${Math.max(1, e(pic.h))}"/><${
35901
+ ""}/a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>`;
35451
35902
  };
35452
35903
  const sp = (name, x, y, w, h, geom, body, extra = "") => {
35453
35904
  const n5 = ++id;
@@ -35530,43 +35981,133 @@ async function pptxOf(model, opt) {
35530
35981
  slides.push(pi + 1);
35531
35982
  }
35532
35983
  const cx = Math.min(51206400, Math.max(914400, e(W2))), cy = Math.min(51206400, Math.max(914400, e(H)));
35533
- files["ppt/presentation.xml"] = strToU84(`${XML2}<p:presentation ${NS2} saveSubsetFonts="1"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst>${slides.map((n5, i) => `<p:sldId id="${256 + i}" r:id="rId${n5 + 2}"/>`).join("")}</p:sldIdLst><p:sldSz cx="${cx}" cy="${cy}"/><p:notesSz cx="${cy}" cy="${cx}"/><p:defaultTextStyle><a:defPPr><a:defRPr lang="${lang}\
35534
- "/></a:defPPr></p:defaultTextStyle></p:presentation>`);
35535
- files["ppt/_rels/presentation.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\
35536
- " Target="theme/theme1.xml"/>${slides.map((n5) => `<Relationship Id="rId${n5 + 2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slides/slide${n5}.xml"/>`).join("")}</Relationships>`);
35984
+ files["ppt/presentation.xml"] = strToU84(`${XML2}<p:presentation ${NS2} saveSubsetFonts="1"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst>${slides.map((n5, i) => `<p:sldId id="${256 + i}" r:id="rId${n5 + 2}"/>`).join("")}</p:sldIdLst><p:sldSz cx="${cx}" cy="${cy}"/><p:notesSz cx="${cy}" cy="${cx}"/><p:defaultTextStyle><a:defPPr><a:defRPr lang="${lang}${
35985
+ ""}"/></a:defPPr></p:defaultTextStyle></p:presentation>`);
35986
+ files["ppt/_rels/presentation.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme${
35987
+ ""}" Target="theme/theme1.xml"/>${slides.map((n5) => `<Relationship Id="rId${n5 + 2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" Target="slides/slide${n5}.xml"/>`).join("")}</Relationships>`);
35537
35988
  const emptyTree = '<p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/></p:spTree>';
35538
- files["ppt/slideMasters/slideMaster1.xml"] = strToU84(`${XML2}<p:sldMaster ${NS2}><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg>${emptyTree}</p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLay\
35539
- outId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst><p:txStyles><p:titleStyle><a:lvl1pPr><a:defRPr sz="2400"/></a:lvl1pPr></p:titleStyle><p:bodyStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:bodyStyle><p:otherStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:otherStyle></p:txStyles></p:sldMaster>`);
35540
- files["ppt/slideMasters/_rels/slideMaster1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/rel\
35541
- ationships/theme" Target="../theme/theme1.xml"/></Relationships>`);
35989
+ files["ppt/slideMasters/slideMaster1.xml"] = strToU84(`${XML2}<p:sldMaster ${NS2}><p:cSld><p:bg><p:bgRef idx="1001"><a:schemeClr val="bg1"/></p:bgRef></p:bg>${emptyTree}</p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLay${
35990
+ ""}outId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst><p:txStyles><p:titleStyle><a:lvl1pPr><a:defRPr sz="2400"/></a:lvl1pPr></p:titleStyle><p:bodyStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:bodyStyle><p:otherStyle><a:lvl1pPr><a:defRPr sz="1200"/></a:lvl1pPr></p:otherStyle></p:txStyles></p:sldMaster>`);
35991
+ files["ppt/slideMasters/_rels/slideMaster1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" Target="../slideLayouts/slideLayout1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/rel${
35992
+ ""}ationships/theme" Target="../theme/theme1.xml"/></Relationships>`);
35542
35993
  files["ppt/slideLayouts/slideLayout1.xml"] = strToU84(`${XML2}<p:sldLayout ${NS2} type="blank" preserve="1"><p:cSld name="Blank">${emptyTree}</p:cSld><p:clrMapOvr><a:masterClrMapping/></p:clrMapOvr></p:sldLayout>`);
35543
35994
  files["ppt/slideLayouts/_rels/slideLayout1.xml.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="../slideMasters/slideMaster1.xml"/></Relationships>`);
35544
35995
  files["ppt/theme/theme1.xml"] = strToU84(THEME);
35545
35996
  const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
35546
- files["docProps/core.xml"] = strToU84(`${XML2}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc6(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc6(opt.author)}\
35547
- </dc:creator>` : ""}<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`);
35548
- files["_rels/.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docP\
35549
- rops/core.xml"/></Relationships>`);
35550
- files["[Content_Types].xml"] = strToU84(`${XML2}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension\
35551
- ="svg" ContentType="image/svg+xml"/><Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/><Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/><Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="applic\
35552
- ation/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>${slides.map((n5) => `<Override PartName="/ppt/slides/slide${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>`).join("")}<Override PartName="/docProps/core.xml" Conte\
35553
- ntType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`);
35997
+ files["docProps/core.xml"] = strToU84(`${XML2}<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>${esc6(opt.title || model.name || "Report")}</dc:title>${opt.author ? `<dc:creator>${esc6(opt.author)}${
35998
+ ""}</dc:creator>` : ""}<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created></cp:coreProperties>`);
35999
+ files["_rels/.rels"] = strToU84(`${XML2}<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docP${
36000
+ ""}rops/core.xml"/></Relationships>`);
36001
+ files["[Content_Types].xml"] = strToU84(`${XML2}<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension${
36002
+ ""}="svg" ContentType="image/svg+xml"/><Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/><Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/><Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="applic${
36003
+ ""}ation/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>${slides.map((n5) => `<Override PartName="/ppt/slides/slide${n5}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>`).join("")}<Override PartName="/docProps/core.xml" Conte${
36004
+ ""}ntType="application/vnd.openxmlformats-package.core-properties+xml"/></Types>`);
35554
36005
  return zipSync3(files, { level: 6 });
35555
36006
  }
35556
- var THEME = `${XML2}<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="ReportWright"><a:themeElements><a:clrScheme name="ReportWright"><a:dk1><a:srgbClr val="000000"/></a:dk1><a:lt1><a:srgbClr val="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F2328"/></a:dk2><a:lt2><a:srgbClr val="E7E6E6"/></a:lt2><a:accent1><a:srgbClr val="2563EB"/></a:accent1><a:accent2><a:srgbClr val="F5\
35557
- 9E0B"/></a:accent2><a:accent3><a:srgbClr val="16A34A"/></a:accent3><a:accent4><a:srgbClr val="DC2626"/></a:accent4><a:accent5><a:srgbClr val="7C3AED"/></a:accent5><a:accent6><a:srgbClr val="0891B2"/></a:accent6><a:hlink><a:srgbClr val="0563C1"/></a:hlink><a:folHlink><a:srgbClr val="954F72"/></a:folHlink></a:clrScheme><a:fontScheme name="ReportWright"><a:majorFont><a:latin typeface="Inter"/><a:ea t\
35558
- ypeface=""/><a:cs typeface=""/></a:majorFont><a:minorFont><a:latin typeface="Inter"/><a:ea typeface=""/><a:cs typeface=""/></a:minorFont></a:fontScheme><a:fmtScheme name="ReportWright"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="\
35559
- 6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="12700"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="19050"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyl\
35560
- eLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>`;
36007
+ var THEME = `${XML2}<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="ReportWright"><a:themeElements><a:clrScheme name="ReportWright"><a:dk1><a:srgbClr val="000000"/></a:dk1><a:lt1><a:srgbClr val="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F2328"/></a:dk2><a:lt2><a:srgbClr val="E7E6E6"/></a:lt2><a:accent1><a:srgbClr val="2563EB"/></a:accent1><a:accent2><a:srgbClr val="F5${
36008
+ ""}9E0B"/></a:accent2><a:accent3><a:srgbClr val="16A34A"/></a:accent3><a:accent4><a:srgbClr val="DC2626"/></a:accent4><a:accent5><a:srgbClr val="7C3AED"/></a:accent5><a:accent6><a:srgbClr val="0891B2"/></a:accent6><a:hlink><a:srgbClr val="0563C1"/></a:hlink><a:folHlink><a:srgbClr val="954F72"/></a:folHlink></a:clrScheme><a:fontScheme name="ReportWright"><a:majorFont><a:latin typeface="Inter"/><a:ea t${
36009
+ ""}ypeface=""/><a:cs typeface=""/></a:majorFont><a:minorFont><a:latin typeface="Inter"/><a:ea typeface=""/><a:cs typeface=""/></a:minorFont></a:fontScheme><a:fmtScheme name="ReportWright"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:fillStyleLst><a:lnStyleLst><a:ln w="${
36010
+ ""}6350"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="12700"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln><a:ln w="19050"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle><a:effectStyle><a:effectLst/></a:effectStyle></a:effectStyl${
36011
+ ""}eLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:solidFill><a:schemeClr val="phClr"/></a:solidFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>`;
36012
+
36013
+ // package.json
36014
+ var package_default = {
36015
+ name: "reportwright",
36016
+ version: "0.13.2-rc.2",
36017
+ license: "MIT",
36018
+ private: true,
36019
+ engines: { node: "22.x" },
36020
+ type: "module",
36021
+ bin: {
36022
+ reportwright: "bin/pw.mjs",
36023
+ pw: "bin/pw.mjs"
36024
+ },
36025
+ scripts: {
36026
+ dev: "next dev -p 3000",
36027
+ build: "node scripts/build-embed.mjs && node scripts/build-worker.mjs && next build",
36028
+ start: "next start -p 3000",
36029
+ test: "vitest run",
36030
+ pw: "node bin/pw.mjs",
36031
+ "test:reports": "node bin/pw.mjs test reports",
36032
+ "test:diff": "vitest run tests/diff",
36033
+ "diff:engines": "node scripts/diff-engines.mjs",
36034
+ "fonts:cjk": "node scripts/fetch-fonts-cjk.mjs",
36035
+ "lint:engine": "node scripts/check-engine-boundary.mjs",
36036
+ typecheck: "node scripts/typecheck.mjs",
36037
+ "test:e2e": ("for t in build-from-scratch smoke expr-editor phase2 phase3 phase4 api progressive phase-bc data-setup galleries charts-p5 tablix ai designer-gaps reuse ssrs-import outline-charts layout-charts-b4 exports-b2 import-b6 data-xml gov-b5 ux-r1c r3b-conflict r4-fixes b2-ui b2-a11y b6j-viewer-handle b6k-designer-a11y b7a-axe b6k-designer-csp viewer-strict-csp viewer-font-errors viewer-e"+
36038
+ "xport-in-ready drilldown fonts standalone-viewer vite-build react-wrapper; do node tests/e2e/$t.mjs || exit 1; done"),
36039
+ sample: "node scripts/make-sample.mjs",
36040
+ "build:embed": "node scripts/build-embed.mjs",
36041
+ "build:packages": "node scripts/build-embed.mjs && node scripts/build-packages.mjs",
36042
+ "scan:packages": "node scripts/scan-packages.mjs",
36043
+ perf: "node scripts/perf.mjs",
36044
+ "build:site": "node scripts/build-site.mjs"
36045
+ },
36046
+ dependencies: {
36047
+ "@anthropic-ai/sdk": "^0.131.0",
36048
+ "@codemirror/autocomplete": "^6.20.3",
36049
+ "@codemirror/commands": "^6.11.1",
36050
+ "@codemirror/language": "^6.12.4",
36051
+ "@codemirror/state": "^6.7.6",
36052
+ "@codemirror/view": "^6.43.13",
36053
+ "@lezer/highlight": "^1.2.5",
36054
+ "@node-saml/node-saml": "^5.1.0",
36055
+ "@pdf-lib/fontkit": "^1.1.1",
36056
+ "@pdf-lib/standard-fonts": "^1.0.0",
36057
+ "@signpdf/placeholder-pdf-lib": "^3.3.0",
36058
+ "@signpdf/signer-p12": "^3.3.0",
36059
+ "@signpdf/signpdf": "^3.3.0",
36060
+ "bidi-js": "~1.0.3",
36061
+ "bwip-js": "^4.11.4",
36062
+ fflate: "^0.8.3",
36063
+ harfbuzzjs: "^1.6.2",
36064
+ immer: "^11.1.21",
36065
+ jose: "^6.2.12",
36066
+ next: "^16.3.8",
36067
+ "node-forge": "^1.4.0",
36068
+ nodemailer: "^10.0.14",
36069
+ "pdf-lib": "^1.17.1",
36070
+ react: "^19.3.0",
36071
+ "react-dom": "^19.3.0",
36072
+ zustand: "^5.0.15"
36073
+ },
36074
+ devDependencies: {
36075
+ "@expo-google-fonts/inter": "^0.4.2",
36076
+ "@expo-google-fonts/jetbrains-mono": "^0.4.1",
36077
+ "axe-core": "^4.14.0",
36078
+ esbuild: "^0.28.2",
36079
+ exceljs: "^4.4.0",
36080
+ playwright: "^1.56.0",
36081
+ typescript: "^5.9.3",
36082
+ vitest: "^5.0.3",
36083
+ "xml-crypto": "^6.3.2"
36084
+ },
36085
+ overrides: {
36086
+ uuid: "^11.1.1"
36087
+ },
36088
+ optionalDependencies: {
36089
+ "@google-cloud/bigquery": "^9.1.0",
36090
+ mssql: "^12.7.2",
36091
+ mysql2: "^3.24.5",
36092
+ oracledb: "^7.0.1",
36093
+ pg: "^8.23.1",
36094
+ "snowflake-sdk": "^3.4.0"
36095
+ }
36096
+ };
35561
36097
 
35562
36098
  // bin/pw.mjs
35563
- var ROOT2 = path.join(import.meta.dirname, "..");
35564
- var PUB = fs.existsSync(path.join(ROOT2, "public", "fonts")) ? path.join(ROOT2, "public") : path.join(path.dirname(createRequire(import.meta.url).resolve("@reportwright/fonts/package.json")), "public");
36099
+ var ROOT2 = path2.join(import.meta.dirname, "..");
36100
+ var PUB = fs2.existsSync(path2.join(ROOT2, "public", "fonts")) ? path2.join(ROOT2, "public") : path2.join(path2.dirname(createRequire(import.meta.url).resolve("@reportwright/fonts/package.json")), "public");
35565
36101
  var HELP = `pw render <report.pw.json> [-p name=value]… [-d source=data.json]… [-f pdf|xlsx|docx|pptx|html|csv|json|txt] [-o file|-] [--base URL [--allow-internal]] [--pdfa] [--ua]
35566
36102
  [--values] [--static] [--layout]
35567
36103
  [--password PW] [--owner-password PW] [--deny print|modify|copy|annotate|fillForms|accessibility|assemble|printHighQuality]…
35568
36104
  pw import <report.jrxml|.rdl|.rptdesign> [-o out.pw.json]
35569
36105
  convert a JasperReports, SSRS or BIRT report to a ReportWright definition
36106
+ pw import <folder> -o <outDir> [--recursive] [--force] [--verify] [--report path] [--max-files N] [--max-bytes N]
36107
+ bulk import (.rdl, .rdlc, .rds, .jrxml, .jrtx, .rptdesign, .rdlx-json and images) into
36108
+ outDir with import-report.json and .html; never overwrites an output edited since the
36109
+ last import (--force does); exit 0 all imported, 2 some failed, 1 none (see the CLI README)
36110
+ pw --version, pw -v the CLI and engine versions
35570
36111
  pw test [folder] [--update] [--layout]
35571
36112
  render every <folder>/__tests__/*.test.json case and compare it with its snapshot
35572
36113
  (the words; --layout: the layout, see the CLI README)
@@ -35593,9 +36134,9 @@ pw migrate-storage --to <url> [--from file|<url>] (SERVER ONLY, as above)
35593
36134
  jobs, fonts, settings, blobs, the audit log) from one storage to another, e.g. the
35594
36135
  files in this folder to sqlite:/srv/pw.db or postgres://…; stop the server first
35595
36136
  Exit codes: 0 ok, 1 a test failed, the pages differ or the audit log does not check, 2 bad usage.`;
35596
- var fontStore = new FontStore((k) => fs.readFileSync(path.join(PUB, "fonts", fontFile(k))));
35597
- var subset = createSubsetter(() => fs.promises.readFile(path.join(PUB, "harfbuzz-subset.wasm")));
35598
- var readJson = (f4) => JSON.parse(fs.readFileSync(f4, "utf8").replace(/^/, ""));
36137
+ var fontStore = new FontStore((k) => fs2.readFileSync(path2.join(PUB, "fonts", fontFile(k))));
36138
+ var subset = createSubsetter(() => fs2.promises.readFile(path2.join(PUB, "harfbuzz-subset.wasm")));
36139
+ var readJson = (f4) => JSON.parse(fs2.readFileSync(f4, "utf8").replace(/^/, ""));
35599
36140
  var pairs2 = (list2 = []) => Object.fromEntries(list2.map((s) => {
35600
36141
  const i = s.indexOf("=");
35601
36142
  if (i < 1) usage(`"${s}" should be name=value`);
@@ -35620,7 +36161,7 @@ function withData(def, data) {
35620
36161
  var siblingLoader = (file) => async (id) => {
35621
36162
  if (!/^[a-z0-9][a-z0-9-]{0,63}$/.test(id)) throw new Error(`Report "${id}" not found`);
35622
36163
  try {
35623
- return readJson(path.join(path.dirname(path.resolve(file)), `${id}.pw.json`));
36164
+ return readJson(path2.join(path2.dirname(path2.resolve(file)), `${id}.pw.json`));
35624
36165
  } catch {
35625
36166
  throw new Error(`Report "${id}" not found`);
35626
36167
  }
@@ -35652,10 +36193,10 @@ function renderFailed(e2, base) {
35652
36193
  async function writePdf(def, { parameters = {}, data, base, internal = false, file, exportData = false }, pdfOpts, out) {
35653
36194
  const d = withData(def, data);
35654
36195
  const tmp = `${out}.${process.pid}.part`;
35655
- const sink = fs.createWriteStream(tmp);
36196
+ const sink = fs2.createWriteStream(tmp);
35656
36197
  const stop = (sig, n5) => () => {
35657
36198
  sink.destroy();
35658
- fs.rmSync(tmp, { force: true });
36199
+ fs2.rmSync(tmp, { force: true });
35659
36200
  process.exit(128 + n5);
35660
36201
  };
35661
36202
  const sigs = [["SIGINT", 2], ["SIGTERM", 15], ["SIGHUP", 1]].map(([s, n5]) => [s, stop(s, n5)]);
@@ -35676,11 +36217,11 @@ async function writePdf(def, { parameters = {}, data, base, internal = false, fi
35676
36217
  sink.once("error", no2);
35677
36218
  sink.end(ok);
35678
36219
  });
35679
- fs.renameSync(tmp, out);
36220
+ fs2.renameSync(tmp, out);
35680
36221
  return { pages: r.pages, streamed: r.streamed, warnings: uniq2(r.streamed ? r.warnings : r.warnings.slice(1)) };
35681
36222
  } catch (e2) {
35682
36223
  sink.destroy();
35683
- fs.rmSync(tmp, { force: true });
36224
+ fs2.rmSync(tmp, { force: true });
35684
36225
  renderFailed(e2, base);
35685
36226
  } finally {
35686
36227
  for (const [s, f4] of sigs) process.off(s, f4);
@@ -35707,20 +36248,20 @@ function diffLines(a, b, context = 2) {
35707
36248
  const keep = ops.map((o, k) => o[0] !== " " || ops.slice(Math.max(0, k - context), k + context + 1).some((x) => x[0] !== " "));
35708
36249
  return ops.filter((_, k) => keep[k]).map(([op, line3]) => `${op} ${line3}`);
35709
36250
  }
35710
- function compare(label, before, after) {
36251
+ function compare(label, before, after, out = console.log) {
35711
36252
  const pa = pageTexts(before), pb = pageTexts(after);
35712
36253
  let changed = false;
35713
36254
  if (pa.length !== pb.length) {
35714
- console.log(`${label}: ${pa.length} pages → ${pb.length} pages`);
36255
+ out(`${label}: ${pa.length} pages → ${pb.length} pages`);
35715
36256
  changed = true;
35716
36257
  }
35717
36258
  for (let k = 0; k < Math.max(pa.length, pb.length); k++) {
35718
36259
  const d = diffLines(pa[k] || [], pb[k] || []);
35719
36260
  if (!d.some((l) => l[0] !== " ")) continue;
35720
36261
  changed = true;
35721
- console.log(`${label}: page ${k + 1} changed`);
35722
- for (const l of d.slice(0, 60)) console.log(l);
35723
- if (d.length > 60) console.log(` … ${d.length - 60} more lines`);
36262
+ out(`${label}: page ${k + 1} changed`);
36263
+ for (const l of d.slice(0, 60)) out(l);
36264
+ if (d.length > 60) out(` … ${d.length - 60} more lines`);
35724
36265
  }
35725
36266
  return changed;
35726
36267
  }
@@ -35741,8 +36282,8 @@ async function cmdRender(args) {
35741
36282
  if (encrypt && fmt2 !== "pdf") usage("--password, --owner-password and --deny apply to -f pdf only");
35742
36283
  if (encrypt && values.pdfa) usage("a PDF/A file cannot have a password");
35743
36284
  if (values.ua && fmt2 !== "pdf") usage("--ua applies to -f pdf only");
35744
- const out = values.o ?? `${path.basename(positionals[0]).replace(/\.pw\.json$|\.json$/, "")}.${fmt2}`;
35745
- const pdfOpts = () => ({ title: def.name, subset, encrypt, drillBase: values.base, pdfa: values.pdfa ? { icc: fs.readFileSync(path.join(PUB, "icc", "sRGB-v2-magic.icc")) } : void 0, tagged: values.ua ? { lang: def.locale || "en" } : void 0 });
36285
+ const out = values.o ?? `${path2.basename(positionals[0]).replace(/\.pw\.json$|\.json$/, "")}.${fmt2}`;
36286
+ const pdfOpts = () => ({ title: def.name, subset, encrypt, drillBase: values.base, pdfa: values.pdfa ? { icc: fs2.readFileSync(path2.join(PUB, "icc", "sRGB-v2-magic.icc")) } : void 0, tagged: values.ua ? { lang: def.locale || "en" } : void 0 });
35746
36287
  if (fmt2 === "pdf" && out !== "-") {
35747
36288
  const r = await writePdf(def, ro, pdfOpts(), out);
35748
36289
  console.error(`pw: wrote ${out} (${r.pages} pages${r.streamed ? ", streamed" : ""}${r.warnings.length ? `, ${r.warnings.length} warnings` : ""})`);
@@ -35762,7 +36303,7 @@ async function cmdRender(args) {
35762
36303
  else usage(`unknown format "${fmt2}"`);
35763
36304
  if (out === "-") process.stdout.write(typeof bytes === "string" ? bytes : Buffer.from(bytes));
35764
36305
  else {
35765
- fs.writeFileSync(out, typeof bytes === "string" ? bytes : Buffer.from(bytes));
36306
+ fs2.writeFileSync(out, typeof bytes === "string" ? bytes : Buffer.from(bytes));
35766
36307
  console.error(`pw: wrote ${out} (${model.pages.length} pages${model.warnings.length ? `, ${model.warnings.length} warnings` : ""})`);
35767
36308
  }
35768
36309
  }
@@ -35787,32 +36328,32 @@ function layoutLines(model) {
35787
36328
  async function cmdTest(args) {
35788
36329
  const { values, positionals } = parseArgs({ args, allowPositionals: true, options: { update: { type: "boolean" }, layout: { type: "boolean" } } });
35789
36330
  const dir = positionals[0] || "reports";
35790
- const testsDir = path.join(dir, "__tests__");
36331
+ const testsDir = path2.join(dir, "__tests__");
35791
36332
  let files = [];
35792
36333
  try {
35793
- files = fs.readdirSync(testsDir).filter((f4) => f4.endsWith(".test.json")).sort();
36334
+ files = fs2.readdirSync(testsDir).filter((f4) => f4.endsWith(".test.json")).sort();
35794
36335
  } catch {
35795
- fail(`no tests: add ${path.join(testsDir, "<report>.test.json")}`);
36336
+ fail(`no tests: add ${path2.join(testsDir, "<report>.test.json")}`);
35796
36337
  }
35797
36338
  let passed = 0, failed = 0, written2 = 0;
35798
36339
  for (const f4 of files) {
35799
- const spec = readJson(path.join(testsDir, f4));
36340
+ const spec = readJson(path2.join(testsDir, f4));
35800
36341
  const id = f4.replace(/\.test\.json$/, "");
35801
- const def = readJson(path.resolve(testsDir, spec.report));
36342
+ const def = readJson(path2.resolve(testsDir, spec.report));
35802
36343
  for (const c of spec.cases || [{ name: "default" }]) {
35803
- const data = Object.fromEntries(Object.entries(c.data || {}).map(([k, v]) => [k, typeof v === "string" ? readJson(path.resolve(testsDir, v)) : v]));
35804
- const model = await renderModel(def, { parameters: c.parameters, data, now: c.now || "2026-01-01T09:00:00", state: c.state, file: path.resolve(testsDir, spec.report) });
36344
+ const data = Object.fromEntries(Object.entries(c.data || {}).map(([k, v]) => [k, typeof v === "string" ? readJson(path2.resolve(testsDir, v)) : v]));
36345
+ const model = await renderModel(def, { parameters: c.parameters, data, now: c.now || "2026-01-01T09:00:00", state: c.state, file: path2.resolve(testsDir, spec.report) });
35805
36346
  const label = `${id} › ${c.name}`;
35806
36347
  const layout = !!values.layout || c.layout === true;
35807
- const snapFile = path.join(testsDir, `${id}.${c.name}.${layout ? "layout." : ""}snap.txt`);
36348
+ const snapFile = path2.join(testsDir, `${id}.${c.name}.${layout ? "layout." : ""}snap.txt`);
35808
36349
  const text2 = layout ? layoutLines(model).join("\n") + "\n" : snapshotText(label, model);
35809
- if (values.update || !fs.existsSync(snapFile)) {
35810
- fs.writeFileSync(snapFile, text2);
36350
+ if (values.update || !fs2.existsSync(snapFile)) {
36351
+ fs2.writeFileSync(snapFile, text2);
35811
36352
  written2++;
35812
36353
  passed++;
35813
36354
  continue;
35814
36355
  }
35815
- const old = fs.readFileSync(snapFile, "utf8");
36356
+ const old = fs2.readFileSync(snapFile, "utf8");
35816
36357
  if (old === text2) {
35817
36358
  passed++;
35818
36359
  continue;
@@ -35841,7 +36382,7 @@ async function cmdDiff(args) {
35841
36382
  const data = Object.fromEntries(Object.entries(pairs2(values.d)).map(([k, f4]) => [k, readJson(f4)]));
35842
36383
  const opts = { parameters: pairs2(values.p), data, base: values.base, internal: !!values["allow-internal"], now: "2026-01-01T09:00:00" };
35843
36384
  const [a, b] = await Promise.all(positionals.map((f4) => renderModel(readJson(f4), { ...opts, file: f4 })));
35844
- if (!compare(path.basename(positionals[1]), a, b)) {
36385
+ if (!compare(path2.basename(positionals[1]), a, b)) {
35845
36386
  console.log("No differences.");
35846
36387
  return;
35847
36388
  }
@@ -35852,7 +36393,7 @@ async function cmdAudit(args) {
35852
36393
  const audit = await Promise.resolve().then(() => __toESM(require_audit(), 1));
35853
36394
  if (positionals[0] === "rekey") {
35854
36395
  const { createPrivateKey } = await import("node:crypto");
35855
- const old = values["old-key"] ? createPrivateKey(fs.readFileSync(values["old-key"], "utf8")) : values["old-secret"] ? audit.keyFromSecret(values["old-secret"]) : usage("give --old-secret or --old-key");
36396
+ const old = values["old-key"] ? createPrivateKey(fs2.readFileSync(values["old-key"], "utf8")) : values["old-secret"] ? audit.keyFromSecret(values["old-secret"]) : usage("give --old-secret or --old-key");
35856
36397
  const e2 = await audit.rekey(old);
35857
36398
  console.log(`re-keyed: ${e2.detail.oldFingerprint} -> ${e2.detail.newFingerprint} (${e2.id})`);
35858
36399
  return;
@@ -35864,7 +36405,7 @@ async function cmdAudit(args) {
35864
36405
  }
35865
36406
  if (positionals[0] !== "verify") usage("pw audit verify | pw audit checkpoint | pw audit rekey");
35866
36407
  for (const k of ["from", "to"]) if (values[k] && !/^\d{4}-\d{2}-\d{2}$/.test(values[k])) usage(`--${k} is a date, YYYY-MM-DD`);
35867
- if (values["public-key"]) process.env.PW_AUDIT_PUBLIC_KEY = fs.readFileSync(values["public-key"], "utf8");
36408
+ if (values["public-key"]) process.env.PW_AUDIT_PUBLIC_KEY = fs2.readFileSync(values["public-key"], "utf8");
35868
36409
  const r = await audit.verifyAudit({ from: values.from, to: values.to, onProgress: values.json ? void 0 : (n5) => process.stderr.write(`\r${n5} events checked`) });
35869
36410
  if (values.json) console.log(JSON.stringify(r, null, 2));
35870
36411
  else {
@@ -35887,20 +36428,73 @@ async function cmdMigrateStorage(args) {
35887
36428
  console.log(`copied ${n5.records} records, ${n5.versions} versions and ${n5.audit} audit events to ${values.to.replace(/\/\/[^@/]*@/, "//***@")}`);
35888
36429
  }
35889
36430
  async function cmdImport(args) {
35890
- const { values, positionals } = parseArgs({ args, allowPositionals: true, options: { o: { type: "string" } } });
35891
- if (positionals.length !== 1) usage("give one .jrxml, .rdl or .rptdesign file");
35892
- const { importXmlReport: importXmlReport2 } = await Promise.resolve().then(() => (init_importers(), importers_exports));
36431
+ const { values, positionals } = parseArgs({ args, allowPositionals: true, options: { o: { type: "string" }, recursive: { type: "boolean" }, force: { type: "boolean" }, verify: { type: "boolean" }, report: { type: "string" }, "max-files": { type: "string" }, "max-bytes": { type: "string" } } });
36432
+ if (positionals.length !== 1) usage("give one .jrxml, .rdl or .rptdesign file, or a folder");
35893
36433
  const file = positionals[0];
35894
- const r = importXmlReport2(fs.readFileSync(file, "utf8"), { name: path.basename(file).replace(/\.[^.]+$/, "") });
36434
+ if (fs2.statSync(file, { throwIfNoEntry: false })?.isDirectory()) return importFolderCmd(file, values);
36435
+ if (values.recursive || values.force || values.verify || values.report) usage("--recursive, --force, --verify and --report are for a folder");
36436
+ const { importXmlReport: importXmlReport2, decodeXml: decodeXml2 } = await Promise.resolve().then(() => (init_importers(), importers_exports));
36437
+ const r = importXmlReport2(decodeXml2(fs2.readFileSync(file)), { name: path2.basename(file).replace(/\.[^.]+$/, "") });
35895
36438
  for (const w of r.warnings) console.error(`pw: ${w}`);
35896
- if (r.error) fail(r.error);
36439
+ if (r.error) {
36440
+ if (r.warnings.some((w) => w.startsWith(r.error))) process.exit(1);
36441
+ fail(r.error);
36442
+ }
35897
36443
  const out = values.o || file.replace(/\.[^.]+$/, ".pw.json");
35898
36444
  const json = JSON.stringify(r.definition, null, 2) + "\n";
35899
36445
  if (out === "-") process.stdout.write(json);
35900
- else fs.writeFileSync(out, json);
36446
+ else fs2.writeFileSync(out, json);
35901
36447
  if (out !== "-") console.error(`${out}: ${r.stats.items} items (${r.stats.mapped} mapped, ${r.stats.approximated} approximated, ${r.stats.dropped} dropped)`);
35902
36448
  }
36449
+ async function importFolderCmd(dir, values) {
36450
+ if (!values.o || values.o === "-") usage("pw import <folder> needs -o <outDir>");
36451
+ const num6 = (k) => {
36452
+ const v = values[k];
36453
+ if (v == null) return void 0;
36454
+ if (!/^\d+$/.test(v) || !(Number(v) > 0)) usage(`--${k} is a positive whole number`);
36455
+ return Number(v);
36456
+ };
36457
+ const { importFolder: importFolder2, reportHtml: reportHtml2, exitCode: exitCode2 } = await Promise.resolve().then(() => (init_batch(), batch_exports));
36458
+ const report = await importFolder2(dir, values.o, {
36459
+ recursive: !!values.recursive,
36460
+ force: !!values.force,
36461
+ maxFiles: num6("max-files"),
36462
+ maxBytes: num6("max-bytes"),
36463
+ verify: values.verify ? verifyImported : void 0,
36464
+ log: (m) => console.error(`pw: ${m}`)
36465
+ });
36466
+ const json = values.report && /\.json$/i.test(values.report) ? values.report : path2.join(values.report || values.o, "import-report.json");
36467
+ const html = json.replace(/\.json$/i, ".html");
36468
+ fs2.mkdirSync(path2.dirname(json), { recursive: true });
36469
+ fs2.writeFileSync(json, JSON.stringify(report, null, 2) + "\n");
36470
+ fs2.writeFileSync(html, reportHtml2(report));
36471
+ const s = report.summary;
36472
+ console.error(`pw: ${s.imported} of ${s.reports} reports imported${s.failed ? `, ${s.failed} failed` : ""}${s.skippedEdited ? `, ${s.skippedEdited} edited outputs kept` : ""}${s.unresolved ? `, ${s.unresolved} unresolved references` : ""}${s.refused ? `, ${s.refused} files refused` : ""}; report: ${html}`);
36473
+ process.exitCode = exitCode2(report);
36474
+ }
36475
+ async function verifyImported({ file, definition, baseline }) {
36476
+ const sample = file.replace(/\.pw\.json$/, ".data.json");
36477
+ let data = {};
36478
+ if (fs2.existsSync(sample)) data = readJson(sample);
36479
+ const embedded = (s) => s.type === "json" && s.data != null || (s.type === "csv" || s.type === "xml") && !!s.data;
36480
+ const missing2 = (definition.dataSources || []).filter((s) => !embedded(s) && !Object.hasOwn(data, s.name)).map((s) => `"${s.name}"`);
36481
+ if (missing2.length) return { status: "skipped", note: `no data for ${missing2.join(", ")}: it is not embedded, and there is no ${path2.basename(sample)}` };
36482
+ const go = (def) => render(
36483
+ { ...def, dataSources: (def.dataSources || []).map((s) => Object.hasOwn(data, s.name) ? { name: s.name, type: "json", data: data[s.name] } : s) },
36484
+ { fontStore, parameters: {}, now: /* @__PURE__ */ new Date("2026-01-01T09:00:00"), loadReport: siblingLoader(file), fetch: () => Promise.reject(new Error("pw import --verify makes no network requests")) }
36485
+ );
36486
+ const model = await go(definition);
36487
+ if (!baseline) return { status: "ok", pages: model.pages.length, warnings: model.warnings.length, note: "renders (no earlier output to compare with)" };
36488
+ const diff = [];
36489
+ const changed = compare(path2.basename(file), await go(baseline), model, (l) => diff.push(l));
36490
+ return { status: changed ? "changed" : "ok", pages: model.pages.length, warnings: model.warnings.length, note: changed ? "renders differently from the output it replaced" : "renders the same as the output it replaced", diff };
36491
+ }
35903
36492
  var commands = { render: cmdRender, import: cmdImport, test: cmdTest, diff: cmdDiff, audit: cmdAudit, "migrate-storage": cmdMigrateStorage };
36493
+ if (cmd === "--version" || cmd === "-v") {
36494
+ const cli = JSON.parse(fs2.readFileSync(path2.join(ROOT2, "package.json"), "utf8"));
36495
+ console.log(`pw ${cli.version} (${cli.name}), engine ${package_default.version}`);
36496
+ process.exit(0);
36497
+ }
35904
36498
  if (!commands[cmd]) usage(cmd && cmd !== "help" && cmd !== "--help" ? `unknown command "${cmd}"` : "");
35905
36499
  try {
35906
36500
  await commands[cmd](rest);