@reportwright/viewer 0.13.0 → 0.13.2-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +150 -7
  3. package/THIRD-PARTY-NOTICES.md +1 -1
  4. package/dist/{chunk-L6YEIVVD.js → chunk-2KNQVFKW.js} +82 -55
  5. package/dist/{chunk-L6YEIVVD.js.map → chunk-2KNQVFKW.js.map} +2 -2
  6. package/dist/{chunk-DXHLIJEY.js → chunk-47ZAKRVN.js} +6 -6
  7. package/dist/chunk-CCH7CFU5.js +5026 -0
  8. package/dist/chunk-CCH7CFU5.js.map +6 -0
  9. package/dist/{chunk-YIX3OJXU.js → chunk-D7S5DL46.js} +4 -4
  10. package/dist/{chunk-CNDUJ7IV.js → chunk-DVJYE7HZ.js} +9 -6
  11. package/dist/chunk-DVJYE7HZ.js.map +6 -0
  12. package/dist/{chunk-BF7GCWZY.js → chunk-GOCWG6FG.js} +15 -15
  13. package/dist/{chunk-IFYCJZNS.js → chunk-GRYITZPG.js} +30 -30
  14. package/dist/{chunk-F5EPQTPF.js → chunk-H422SRD3.js} +29 -29
  15. package/dist/{chunk-FEM2QVOO.js → chunk-JD6EJ3LI.js} +4 -4
  16. package/dist/{chunk-QFLVVM3H.js → chunk-MS2LQC2O.js} +38 -28
  17. package/dist/chunk-MS2LQC2O.js.map +6 -0
  18. package/dist/{chunk-UHHURTSV.js → chunk-NARXO3DB.js} +7 -7
  19. package/dist/{chunk-TZXEEVKE.js → chunk-OED3YZYP.js} +90 -45
  20. package/dist/chunk-OED3YZYP.js.map +6 -0
  21. package/dist/{chunk-EK5CJY22.js → chunk-OMCWZYRI.js} +69 -39
  22. package/dist/chunk-OMCWZYRI.js.map +6 -0
  23. package/dist/{chunk-UJL7C2AS.js → chunk-U2ZY2NPQ.js} +4 -4
  24. package/dist/{chunk-PQNM6ET7.js → chunk-WOBRKNIA.js} +12 -12
  25. package/dist/designer.js +349 -147
  26. package/dist/designer.js.map +3 -3
  27. package/dist/engine.worker.bwip.js +4781 -0
  28. package/dist/engine.worker.bwip.js.map +6 -0
  29. package/dist/engine.worker.js +5675 -16781
  30. package/dist/engine.worker.js.map +3 -3
  31. package/dist/peer/{chunk-2CD5COHN.js → chunk-6KUUNDNN.js} +57 -30
  32. package/dist/peer/{chunk-2CD5COHN.js.map → chunk-6KUUNDNN.js.map} +1 -1
  33. package/dist/peer/{chunk-LWXQX3NJ.js → chunk-A6UXBSTP.js} +29 -29
  34. package/dist/peer/{chunk-V42KN7HD.js → chunk-CFTFTV2O.js} +6 -6
  35. package/dist/peer/{chunk-45GVDKP5.js → chunk-FN3FXACD.js} +7 -7
  36. package/dist/peer/chunk-ILBTPBOA.js +14226 -0
  37. package/dist/peer/chunk-ILBTPBOA.js.map +6 -0
  38. package/dist/peer/{chunk-VZHHNQYB.js → chunk-JQDW5OR3.js} +90 -45
  39. package/dist/peer/chunk-JQDW5OR3.js.map +6 -0
  40. package/dist/peer/chunk-JQTRDHQP.js +866 -0
  41. package/dist/peer/chunk-JQTRDHQP.js.map +6 -0
  42. package/dist/peer/chunk-KD6CDYGE.js +5024 -0
  43. package/dist/peer/chunk-KD6CDYGE.js.map +6 -0
  44. package/dist/peer/chunk-MXR6JBMP.js +546 -0
  45. package/dist/peer/chunk-MXR6JBMP.js.map +6 -0
  46. package/dist/peer/chunk-N42DCZZA.js +378 -0
  47. package/dist/peer/chunk-N42DCZZA.js.map +6 -0
  48. package/dist/peer/{chunk-MKY3SDXU.js → chunk-OUTKMWFM.js} +9 -6
  49. package/dist/peer/chunk-OUTKMWFM.js.map +6 -0
  50. package/dist/peer/{chunk-Z5II55QT.js → chunk-VJLMUGUI.js} +4 -4
  51. package/dist/peer/{chunk-3CBV5SAI.js → chunk-WABYQWMT.js} +12 -12
  52. package/dist/peer/{chunk-S6LSPHSU.js → chunk-XHCRHVRK.js} +4 -4
  53. package/dist/peer/{chunk-YITWGAR4.js → chunk-ZS3J4WBH.js} +30 -30
  54. package/dist/peer/designer.js +335 -134
  55. package/dist/peer/designer.js.map +3 -3
  56. package/dist/peer/engine.worker.bwip.js +4781 -0
  57. package/dist/peer/engine.worker.bwip.js.map +6 -0
  58. package/dist/peer/engine.worker.js +5675 -16781
  59. package/dist/peer/engine.worker.js.map +3 -3
  60. package/dist/peer/viewer.js +44 -12
  61. package/dist/peer/viewer.js.map +1 -1
  62. package/dist/viewer.d.ts +2 -0
  63. package/dist/viewer.js +44 -12
  64. package/dist/viewer.js.map +1 -1
  65. package/package.json +1 -2
  66. package/dist/chunk-CNDUJ7IV.js.map +0 -6
  67. package/dist/chunk-EK5CJY22.js.map +0 -6
  68. package/dist/chunk-QFLVVM3H.js.map +0 -6
  69. package/dist/chunk-TZXEEVKE.js.map +0 -6
  70. package/dist/peer/chunk-MKY3SDXU.js.map +0 -6
  71. package/dist/peer/chunk-VZHHNQYB.js.map +0 -6
  72. /package/dist/{chunk-DXHLIJEY.js.map → chunk-47ZAKRVN.js.map} +0 -0
  73. /package/dist/{chunk-FEM2QVOO.js.map → chunk-D7S5DL46.js.map} +0 -0
  74. /package/dist/{chunk-BF7GCWZY.js.map → chunk-GOCWG6FG.js.map} +0 -0
  75. /package/dist/{chunk-IFYCJZNS.js.map → chunk-GRYITZPG.js.map} +0 -0
  76. /package/dist/{chunk-F5EPQTPF.js.map → chunk-H422SRD3.js.map} +0 -0
  77. /package/dist/{chunk-YIX3OJXU.js.map → chunk-JD6EJ3LI.js.map} +0 -0
  78. /package/dist/{chunk-UHHURTSV.js.map → chunk-NARXO3DB.js.map} +0 -0
  79. /package/dist/{chunk-UJL7C2AS.js.map → chunk-U2ZY2NPQ.js.map} +0 -0
  80. /package/dist/{chunk-PQNM6ET7.js.map → chunk-WOBRKNIA.js.map} +0 -0
  81. /package/dist/peer/{chunk-LWXQX3NJ.js.map → chunk-A6UXBSTP.js.map} +0 -0
  82. /package/dist/peer/{chunk-V42KN7HD.js.map → chunk-CFTFTV2O.js.map} +0 -0
  83. /package/dist/peer/{chunk-45GVDKP5.js.map → chunk-FN3FXACD.js.map} +0 -0
  84. /package/dist/peer/{chunk-S6LSPHSU.js.map → chunk-VJLMUGUI.js.map} +0 -0
  85. /package/dist/peer/{chunk-3CBV5SAI.js.map → chunk-WABYQWMT.js.map} +0 -0
  86. /package/dist/peer/{chunk-Z5II55QT.js.map → chunk-XHCRHVRK.js.map} +0 -0
  87. /package/dist/peer/{chunk-YITWGAR4.js.map → chunk-ZS3J4WBH.js.map} +0 -0
package/dist/designer.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  setShadowStyles,
14
14
  t,
15
15
  uiFontCss
16
- } from "./chunk-L6YEIVVD.js";
16
+ } from "./chunk-2KNQVFKW.js";
17
17
  import {
18
18
  customFonts,
19
19
  fontsBase,
@@ -24,7 +24,7 @@ import {
24
24
  setAssetBase,
25
25
  setFetchPolicy,
26
26
  setStandalone
27
- } from "./chunk-CNDUJ7IV.js";
27
+ } from "./chunk-DVJYE7HZ.js";
28
28
  import {
29
29
  BASE_STYLE,
30
30
  DEFAULT_THEME,
@@ -69,7 +69,7 @@ import {
69
69
  validate,
70
70
  withPartProps,
71
71
  xmlRowPaths
72
- } from "./chunk-EK5CJY22.js";
72
+ } from "./chunk-OMCWZYRI.js";
73
73
  import {
74
74
  PAGE_SIZES,
75
75
  fromPt,
@@ -77,23 +77,23 @@ import {
77
77
  resolvePage,
78
78
  toPt
79
79
  } from "./chunk-BR5K6SBL.js";
80
- import "./chunk-72S6DETS.js";
81
- import {
82
- currencyOf
83
- } from "./chunk-GJS242RR.js";
84
80
  import "./chunk-F6RMRXIN.js";
85
81
  import {
86
82
  fontFaceCss,
87
83
  fontFamilyCss,
88
84
  pageToSvg
89
- } from "./chunk-UJL7C2AS.js";
85
+ } from "./chunk-U2ZY2NPQ.js";
86
+ import "./chunk-72S6DETS.js";
90
87
  import {
91
88
  BUNDLED_FAMILIES,
92
89
  FONT_FAMILIES,
93
90
  allFontKeys,
94
91
  fallbackKeys,
95
92
  resolveFontKey
96
- } from "./chunk-QFLVVM3H.js";
93
+ } from "./chunk-MS2LQC2O.js";
94
+ import {
95
+ currencyOf
96
+ } from "./chunk-GJS242RR.js";
97
97
  import {
98
98
  __toESM
99
99
  } from "./chunk-OLLMACWA.js";
@@ -113,13 +113,13 @@ function toPt2(v, fallback = 0) {
113
113
  (m[2] || "pt").toLowerCase()
114
114
  ]) : fallback;
115
115
  }
116
- var NAMED = 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,dark\
117
- goldenrod: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,fi\
118
- rebrick: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:e0fff\
119
- f,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,med\
120
- iumseagreen: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:ffefd\
121
- 5,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:008080\
122
- ,thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32".split(",").map((p) => p.split(":")));
116
+ var NAMED = 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,dark"+
117
+ "goldenrod: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,fi"+
118
+ "rebrick: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:e0fff"+
119
+ "f,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,med"+
120
+ "iumseagreen: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:ffefd"+
121
+ "5,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:008080"+
122
+ ",thistle:d8bfd8,tomato:ff6347,turquoise:40e0d0,violet:ee82ee,wheat:f5deb3,white:ffffff,whitesmoke:f5f5f5,yellow:ffff00,yellowgreen:9acd32").split(",").map((p) => p.split(":")));
123
123
  function hexColor(c) {
124
124
  if (c == null || c === "") return void 0;
125
125
  const s = String(c).trim().toLowerCase();
@@ -996,6 +996,8 @@ function newContext() {
996
996
  /** @type {Set<string>} part libraries referenced (report ids) */
997
997
  libraries: /* @__PURE__ */ new Set(),
998
998
  cells: 0,
999
+ /** @type {any[]} every item tracked, with what happened to it (see items() in importRdlx's result) */
1000
+ items: [],
999
1001
  warn(msg) {
1000
1002
  if (!cx.warnings.includes(msg)) cx.warnings.push(msg);
1001
1003
  }
@@ -1005,24 +1007,35 @@ function newContext() {
1005
1007
  function track(cx, ar, label) {
1006
1008
  cx.stats.items++;
1007
1009
  const name2 = String(ar?.Name || label || ar?.Type || "item");
1010
+ const say = (kind, msg) => {
1011
+ if (!t3.notes.some((n) => n.message === msg)) t3.notes.push({ kind, message: msg });
1012
+ cx.warn(`${name2}: ${msg}`);
1013
+ };
1008
1014
  const t3 = {
1009
1015
  name: name2,
1010
1016
  state: "mapped",
1017
+ pos: typeof ar?.__pos === "number" ? ar.__pos : void 0,
1018
+ /** @type {{ kind: string, message: string }[]} */
1019
+ notes: [],
1020
+ /** @type {string[]} expressions that could not be translated */
1021
+ exprs: [],
1011
1022
  /** in the report, with something lost or changed */
1012
1023
  approx(msg) {
1013
1024
  if (t3.state === "mapped") t3.state = "approximated";
1014
- cx.warn(`${name2}: ${msg}`);
1025
+ say("approximated", msg);
1015
1026
  },
1016
1027
  /** for information only */
1017
1028
  note(msg) {
1018
- cx.warn(`${name2}: ${msg}`);
1029
+ say("info", msg);
1019
1030
  },
1020
1031
  /** not in the report */
1021
1032
  drop(msg) {
1022
1033
  t3.state = "dropped";
1023
- cx.warn(`${name2}: ${msg}`);
1034
+ say("dropped", msg);
1024
1035
  }
1025
1036
  };
1037
+ cx.items.push(t3);
1038
+ for (const x of Array.isArray(ar?.__exprs) ? ar.__exprs : []) if (typeof x === "string" && !t3.exprs.includes(x)) t3.exprs.push(x);
1026
1039
  for (const n of Array.isArray(ar?.__notes) ? ar.__notes : []) t3.approx(n);
1027
1040
  for (const n of Array.isArray(ar?.__info) ? ar.__info : []) t3.note(n);
1028
1041
  return t3;
@@ -1040,6 +1053,7 @@ function uniq(cx, base2, generated = false) {
1040
1053
  }
1041
1054
  function ex(cx, t3, v, ctx, opt = {}) {
1042
1055
  const r = translateExpression(v, { text: opt.text, fields: opt.fields, lit: opt.lit, region: ctx.region, scopes: cx.scopes, runScopes: cx.runScopes });
1056
+ if (!r.ok && typeof v === "string" && !t3.exprs.includes(v)) t3.exprs.push(v);
1043
1057
  if (!r.ok) t3.approx(`${r.notes.join("; ")}; ${opt.text ? "the expression is shown as text" : `${opt.what || "that setting"} is left out`}.`);
1044
1058
  else for (const n of r.notes) t3.approx(`${n}.`);
1045
1059
  return r.value;
@@ -1276,12 +1290,13 @@ function convertItem(ar, cx, ctx) {
1276
1290
  dropInside(ar, cx);
1277
1291
  return finish(cx, t3, null);
1278
1292
  }
1279
- const snap = { ...cx.stats };
1293
+ const snap = { ...cx.stats }, tracked = cx.items.length;
1280
1294
  try {
1281
1295
  return conv(ar, cx, ctx);
1282
1296
  } catch (e) {
1283
1297
  if (e instanceof ImportBudgetError) throw e;
1284
1298
  Object.assign(cx.stats, snap);
1299
+ cx.items.length = tracked;
1285
1300
  const t3 = track(cx, ar);
1286
1301
  t3.drop(`it could not be converted (${e instanceof Error ? e.message : e}), so it was left out.`);
1287
1302
  dropInside(ar, cx);
@@ -3313,7 +3328,7 @@ function convertReport(ar, cx, opts) {
3313
3328
  if (cx.columns) body.columns = cx.columns;
3314
3329
  if (more.length) body.name = sec0?.Name || "Section1";
3315
3330
  return {
3316
- $schema: "pagewright/report@1",
3331
+ $schema: "reportwright/report@1",
3317
3332
  name: name2,
3318
3333
  locale: lang2,
3319
3334
  ...currencyOf(lang2) ? { currency: currencyOf(lang2) } : {},
@@ -3354,13 +3369,15 @@ function importRdlx(input, opts = {}) {
3354
3369
  } catch (e) {
3355
3370
  if (e instanceof ImportBudgetError) {
3356
3371
  const error = `The report is too large to import: ${e.message}`;
3357
- return { definition: convertReport({}, newContext(), opts), warnings: [`${error}.`], stats: { items: 0, mapped: 0, approximated: 0, dropped: 0 }, error };
3372
+ return { definition: convertReport({}, newContext(), opts), warnings: [`${error}.`], stats: { items: 0, mapped: 0, approximated: 0, dropped: 0 }, items: [], error };
3358
3373
  }
3359
3374
  cx.warn(`The import stopped early (${e instanceof Error ? e.message : e}), so parts of the report are missing.`);
3360
3375
  definition = convertReport({}, newContext(), opts);
3361
3376
  }
3362
- return { definition, warnings: cx.warnings, stats: cx.stats };
3377
+ return { definition, warnings: cx.warnings, stats: cx.stats, items: importedItems(cx.items) };
3363
3378
  }
3379
+ var importedItems = (items) => items.filter((t3) => t3.state !== "mapped" || t3.notes.length || t3.exprs.length).map((t3) => ({ name: t3.name, state: t3.state, ...t3.pos != null ? { pos: t3.pos } : {}, notes: t3.notes, exprs: t3.exprs }));
3380
+ var rewordItems = (items, f) => (items || []).map((i2) => ({ ...i2, notes: i2.notes.map((n) => ({ ...n, message: f(n.message) })) }));
3364
3381
 
3365
3382
  // src/importers/rdl.js
3366
3383
  var RDL_NS = /^http:\/\/schemas\.microsoft\.com\/sqlserver\/reporting\/(\d{4})\/\d{2}\/reportdefinition$/i;
@@ -3388,7 +3405,7 @@ function importRdl(input, opts = {}) {
3388
3405
  const notes = [];
3389
3406
  let ar;
3390
3407
  try {
3391
- ar = toRdlx(root, notes, m ? Number(m[1]) : 2016);
3408
+ ar = toRdlx(root, notes, m ? Number(m[1]) : 2016, opts.resolve);
3392
3409
  } catch (e) {
3393
3410
  if (e instanceof ImportBudgetError) {
3394
3411
  const error = `The report is too large to import: ${e.message}`;
@@ -3402,10 +3419,12 @@ function importRdl(input, opts = {}) {
3402
3419
  const def = r.definition;
3403
3420
  for (const p of def.parameters || []) if (ar.__hidden?.has(p.name)) p.hidden = true;
3404
3421
  if (ar.__code) def.customCode = ar.__code;
3405
- const warnings = [...notes, ...r.warnings.filter((w) => !/is hidden in ActiveReports; ReportWright shows it/.test(w))].map((w) => w.replace(/ActiveReports/g, "SSRS"));
3406
- return { definition: def, warnings: [...new Set(warnings)], stats: r.stats };
3422
+ const hiddenNote = /is hidden in ActiveReports; ReportWright shows it/;
3423
+ const warnings = [...notes, ...r.warnings.filter((w) => !hiddenNote.test(w))].map((w) => w.replace(/ActiveReports/g, "SSRS"));
3424
+ const items = rewordItems(r.items.map((i2) => ({ ...i2, notes: i2.notes.filter((n) => !hiddenNote.test(n.message)) })), (w) => w.replace(/ActiveReports/g, "SSRS"));
3425
+ return { definition: def, warnings: [...new Set(warnings)], stats: r.stats, items };
3407
3426
  }
3408
- function toRdlx(root, notes, year) {
3427
+ function toRdlx(root, notes, year, resolve2) {
3409
3428
  const NS = root.ns;
3410
3429
  const kids = (e, name2) => e ? e.children.filter((c) => c.ns === NS && (name2 == null || c.name === name2)) : [];
3411
3430
  const kid = (e, name2) => e?.children.find((c) => c.ns === NS && c.name === name2);
@@ -3572,6 +3591,7 @@ function toRdlx(root, notes, year) {
3572
3591
  Name: e.attrs.Name,
3573
3592
  __notes: itemNotes,
3574
3593
  __info: itemInfo,
3594
+ __pos: e.pos,
3575
3595
  Left: raw(e, "Left"),
3576
3596
  Top: raw(e, "Top"),
3577
3597
  Width: raw(e, "Width"),
@@ -4107,17 +4127,46 @@ function toRdlx(root, notes, year) {
4107
4127
  const r = e.name === "Tablix" || e.name === "Chart" ? e.attrs.Name || reg : reg;
4108
4128
  for (const c of e.children) prepass(c, r);
4109
4129
  })(root, null);
4130
+ function sharedSource(ref) {
4131
+ let text;
4132
+ try {
4133
+ text = resolve2?.("datasource", ref);
4134
+ } catch {
4135
+ text = null;
4136
+ }
4137
+ if (typeof text !== "string") return null;
4138
+ let doc2;
4139
+ try {
4140
+ doc2 = parseXml(text);
4141
+ } catch (e) {
4142
+ notes.push(`The shared data source "${ref}" could not be read (${e instanceof Error ? e.message : e}); it is treated as SQL Server.`);
4143
+ return null;
4144
+ }
4145
+ const sub = (e, n) => e?.children.find((c) => c.name === n);
4146
+ const props = doc2.name === "RptDataSource" ? sub(doc2, "ConnectionProperties") : doc2.name === "DataSourceDefinition" ? doc2 : null;
4147
+ if (!props) {
4148
+ notes.push(`The shared data source "${ref}" is not an SSRS data source (its root is <${doc2.name}>); it is treated as SQL Server.`);
4149
+ return null;
4150
+ }
4151
+ return { provider: (sub(props, "Extension")?.text || "SQL").trim(), connect: (sub(props, "ConnectString")?.text ?? "").trim() };
4152
+ }
4110
4153
  const TYPE_OF = (t3) => /datetime|date$/i.test(t3) ? "date" : /int|decimal|double|single|byte|float/i.test(t3) ? "number" : /boolean/i.test(t3) ? "boolean" : null;
4111
4154
  const DataSources = list2(root, "DataSources", "DataSource").map((d) => {
4112
4155
  const name2 = d.attrs.Name;
4113
4156
  const cp = kid(d, "ConnectionProperties");
4114
4157
  let provider = raw(cp, "DataProvider") || "";
4158
+ let connect = raw(cp, "ConnectString") ?? "";
4115
4159
  if (!cp && kid(d, "DataSourceReference")) {
4116
- provider = "SQL";
4117
- notes.push(`Data source "${name2}" is the shared data source "${raw(d, "DataSourceReference")}", whose connection is not in the file; it is treated as SQL Server.`);
4160
+ const ref = raw(d, "DataSourceReference") ?? "";
4161
+ const shared = sharedSource(ref);
4162
+ if (shared) ({ provider, connect } = shared);
4163
+ else {
4164
+ provider = "SQL";
4165
+ notes.push(`Data source "${name2}" is the shared data source "${ref}", whose connection is not in the file; it is treated as SQL Server.`);
4166
+ }
4118
4167
  }
4119
4168
  if (/^(OLEDB-MD|ESSBASE|SAPBW|SQLAS|HYPERION)/i.test(provider)) provider = `${provider} (MDX)`;
4120
- return { Name: name2, ConnectionProperties: { DataProvider: provider, ConnectString: raw(cp, "ConnectString") ?? "" } };
4169
+ return { Name: name2, ConnectionProperties: { DataProvider: provider, ConnectString: connect } };
4121
4170
  });
4122
4171
  const entered = /* @__PURE__ */ new Map();
4123
4172
  const providers = new Map(DataSources.map((d) => [d.Name, String(d.ConnectionProperties.DataProvider).toUpperCase()]));
@@ -4958,7 +5007,7 @@ function importJrxml(input, opts = {}) {
4958
5007
  const charts = /* @__PURE__ */ new Map();
4959
5008
  let ar;
4960
5009
  try {
4961
- ar = toRdlx2(root, notes, charts, opts.name || root.attrs.name);
5010
+ ar = toRdlx2(root, notes, charts, opts.name || root.attrs.name, opts.resolve);
4962
5011
  } catch (e) {
4963
5012
  if (e instanceof ImportBudgetError) {
4964
5013
  const error = `The report is too large to import: ${e.message}`;
@@ -4984,7 +5033,7 @@ function importJrxml(input, opts = {}) {
4984
5033
  r.definition.arithmetic = "double";
4985
5034
  placeCharts(r.definition, charts);
4986
5035
  const warnings = [...notes, ...r.warnings].map((w) => w.replace(/ActiveReports/g, "JasperReports"));
4987
- return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats };
5036
+ return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats, items: rewordItems(r.items, (w) => w.replace(/ActiveReports/g, "JasperReports")) };
4988
5037
  }
4989
5038
  function stripJasperDoctype(s) {
4990
5039
  const i2 = s.indexOf("<!DOCTYPE");
@@ -4993,9 +5042,9 @@ function stripJasperDoctype(s) {
4993
5042
  if (e < 0) return s;
4994
5043
  const decl = s.slice(i2, e + 1);
4995
5044
  if (decl.includes("[") || !/^<!DOCTYPE\s+jasperReport\s/.test(decl)) return s;
4996
- return s.slice(0, i2) + s.slice(e + 1);
5045
+ return s.slice(0, i2) + decl.replace(/[^\n]/g, " ") + s.slice(e + 1);
4997
5046
  }
4998
- function toRdlx2(root, notes, charts, reportName) {
5047
+ function toRdlx2(root, notes, charts, reportName, resolve2) {
4999
5048
  const kid = (e, n) => e?.children.find((c) => c.name === n);
5000
5049
  const kids = (e, n) => e ? e.children.filter((c) => n == null || c.name === n) : [];
5001
5050
  const txt = (e, n) => {
@@ -5179,6 +5228,7 @@ function toRdlx2(root, notes, charts, reportName) {
5179
5228
  return "=" + v.s;
5180
5229
  } catch (e) {
5181
5230
  if (!(e instanceof Untranslatable2)) throw e;
5231
+ (item2.__exprs || (item2.__exprs = [])).push(s);
5182
5232
  (item2.__notes || (item2.__notes = [])).push(`${e.message} has no ReportWright equivalent, so the expression ${s.length > 200 ? s.slice(0, 200) + "…" : s} is shown as text.`);
5183
5233
  return s.startsWith("=") ? `="${s.replace(/"/g, '""')}"` : s;
5184
5234
  }
@@ -5188,12 +5238,50 @@ function toRdlx2(root, notes, charts, reportName) {
5188
5238
  return "=" + vb2(String(src).trim(), c);
5189
5239
  } catch (e) {
5190
5240
  if (!(e instanceof Untranslatable2)) throw e;
5241
+ (item2.__exprs || (item2.__exprs = [])).push(String(src).trim());
5191
5242
  (item2.__notes || (item2.__notes = [])).push(`${what} uses ${e.message}, which has no ReportWright equivalent, so it is left out.`);
5192
5243
  return void 0;
5193
5244
  }
5194
5245
  }
5195
5246
  const styles = new Map(kids(root, "style").map((s) => [s.attrs.name, s]));
5196
- const defStyle = kids(root, "style").find((s) => s.attrs.isDefault === "true" || s.attrs.default === "true");
5247
+ const seenTemplates = /* @__PURE__ */ new Set();
5248
+ (function templates(el, depth) {
5249
+ for (const t3 of kids(el, "template")) {
5250
+ const src = (kid(t3, "expression")?.text ?? t3.text).trim();
5251
+ const lit2 = /^"([^"]+)"$/.exec(src);
5252
+ const ref = lit2 ? lit2[1] : depth > 0 && !/["$(){}+]/.test(src) ? src : null;
5253
+ if (!ref) {
5254
+ if (src) note(`A style template is chosen by an expression (${src.slice(0, 120)}), so its styles are missing.`);
5255
+ continue;
5256
+ }
5257
+ if (seenTemplates.has(ref) || seenTemplates.size >= 32) continue;
5258
+ seenTemplates.add(ref);
5259
+ let text;
5260
+ try {
5261
+ text = resolve2?.("template", ref);
5262
+ } catch {
5263
+ text = null;
5264
+ }
5265
+ if (typeof text !== "string") {
5266
+ note(`The style template "${ref}" is not in the file, so items that use its styles have the default style.`);
5267
+ continue;
5268
+ }
5269
+ let doc2;
5270
+ try {
5271
+ doc2 = parseXml(text);
5272
+ } catch (e) {
5273
+ note(`The style template "${ref}" could not be read (${e instanceof Error ? e.message : e}), so its styles are missing.`);
5274
+ continue;
5275
+ }
5276
+ if (doc2.name !== "jasperTemplate") {
5277
+ note(`The style template "${ref}" is not a JasperReports template (its root is <${doc2.name}>), so its styles are missing.`);
5278
+ continue;
5279
+ }
5280
+ for (const s of kids(doc2, "style")) if (s.attrs.name && !styles.has(s.attrs.name)) styles.set(s.attrs.name, s);
5281
+ if (depth < 8) templates(doc2, depth + 1);
5282
+ }
5283
+ })(root, 0);
5284
+ const defStyle = [...styles.values()].find((s) => s.attrs.isDefault === "true" || s.attrs.default === "true");
5197
5285
  function styleAttrs(name2, seen = 0) {
5198
5286
  const s = styles.get(name2);
5199
5287
  if (!s || seen > 10) return {};
@@ -5348,7 +5436,7 @@ function toRdlx2(root, notes, charts, reportName) {
5348
5436
  }
5349
5437
  function item(n, c) {
5350
5438
  const a = n.a, re = n.re, e = n.el;
5351
- const base2 = { Name: nameFor(n, n.kind), Left: pt(a.x), Top: pt(a.y), Width: pt(a.width), Height: pt(a.height) };
5439
+ const base2 = { __pos: e.pos, Name: nameFor(n, n.kind), Left: pt(a.x), Top: pt(a.y), Width: pt(a.width), Height: pt(a.height) };
5352
5440
  const it = { ...base2 };
5353
5441
  const st = { ...defStyle ? styleAttrs(defStyle.attrs.name) : {}, ...a.style ? styleAttrs(a.style) : {}, ...stripUndef(normAttrs(re.attrs === e.attrs ? e.attrs : { ...re.attrs, ...e.attrs, ...n.te?.attrs || {}, ...kid(n.te, "font")?.attrs || {} })), ...boxAttrs(kid(e, "box")) };
5354
5442
  if (a.style && !styles.has(a.style)) (it.__notes || (it.__notes = [])).push(`its style "${a.style}" is not in the file (a style template?), so it has the default style.`);
@@ -5954,7 +6042,7 @@ function importBirt(input, opts = {}) {
5954
6042
  r.definition.nullOrder = "low";
5955
6043
  r.definition.arithmetic = "double";
5956
6044
  r.definition.bandRows = "first-last";
5957
- return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats };
6045
+ return { definition: r.definition, warnings: [...new Set(warnings)], stats: r.stats, items: rewordItems(r.items, (w) => w.replace(/ActiveReports/g, "BIRT")) };
5958
6046
  }
5959
6047
  var PROPS = /* @__PURE__ */ new Set(["property", "text-property", "expression", "xml-property", "html-property", "encrypted-property"]);
5960
6048
  var prop = (e, name2) => e?.children.find((c) => PROPS.has(c.name) && c.attrs.name === name2)?.text;
@@ -6177,6 +6265,7 @@ function toRdlx3(root, notes, reportName) {
6177
6265
  return "=" + vb2(s, c);
6178
6266
  } catch (e) {
6179
6267
  if (!(e instanceof Untranslatable2)) throw e;
6268
+ (item2.__exprs || (item2.__exprs = [])).push(s);
6180
6269
  (item2.__notes || (item2.__notes = [])).push(`${e.message} has no ReportWright equivalent, so the expression ${s.length > 200 ? s.slice(0, 200) + "…" : s} is shown as text.`);
6181
6270
  return s.startsWith("=") ? `="${s.replace(/"/g, '""')}"` : s;
6182
6271
  }
@@ -6186,6 +6275,7 @@ function toRdlx3(root, notes, reportName) {
6186
6275
  return "=" + vb2(src, c);
6187
6276
  } catch (e) {
6188
6277
  if (!(e instanceof Untranslatable2)) throw e;
6278
+ (item2.__exprs || (item2.__exprs = [])).push(String(src));
6189
6279
  (item2.__notes || (item2.__notes = [])).push(`${what} uses ${e.message}, which has no ReportWright equivalent, so it is left out.`);
6190
6280
  return void 0;
6191
6281
  }
@@ -6366,7 +6456,7 @@ function toRdlx3(root, notes, reportName) {
6366
6456
  const w = Math.min(W, len(prop(e, "width"), W, W)) || W;
6367
6457
  const given = len(prop(e, "height"), 0, 0);
6368
6458
  const x = len(prop(e, "x"), W, 0);
6369
- const it = { Name: nameFor(e, e.name.replace(/(^|-)(\w)/g, (_, __, ch) => ch.toUpperCase())), Left: pt(x), Width: pt(w) };
6459
+ const it = { __pos: e.pos, Name: nameFor(e, e.name.replace(/(^|-)(\w)/g, (_, __, ch) => ch.toUpperCase())), Left: pt(x), Width: pt(w) };
6370
6460
  const vis = listProp(e, "visibility")[0];
6371
6461
  if (vis) {
6372
6462
  const ve = prop(vis, "valueExpr");
@@ -6424,6 +6514,7 @@ function toRdlx3(root, notes, reportName) {
6424
6514
  v = "=" + binding(b, c, 0);
6425
6515
  } catch (er) {
6426
6516
  if (!(er instanceof Untranslatable2)) throw er;
6517
+ (it.__exprs || (it.__exprs = [])).push(String(prop(b, "expression") ?? col));
6427
6518
  (it.__notes || (it.__notes = [])).push(`its column "${col}" uses ${er.message}, so it is shown as text.`);
6428
6519
  v = col;
6429
6520
  }
@@ -6452,6 +6543,7 @@ function toRdlx3(root, notes, reportName) {
6452
6543
  pieces.push(`(${vb2(decodeHtml(p.e), c)})`);
6453
6544
  } catch (er) {
6454
6545
  if (!(er instanceof Untranslatable2)) throw er;
6546
+ (it.__exprs || (it.__exprs = [])).push(decodeHtml(p.e));
6455
6547
  (it.__notes || (it.__notes = [])).push(`a <value-of> uses ${er.message}, so it is left out.`);
6456
6548
  }
6457
6549
  }
@@ -6968,7 +7060,7 @@ function nestedFields(rows) {
6968
7060
  return [...top2].filter(([, m]) => m.size).map(([name2, m]) => ({ name: name2, type: "object", fields: [...m].map(([n, t3]) => ({ name: n, type: t3 === "null" ? "string" : t3 })) }));
6969
7061
  }
6970
7062
 
6971
- // node_modules/zustand/esm/vanilla.mjs
7063
+ // ../reportwright/node_modules/zustand/esm/vanilla.mjs
6972
7064
  var createStoreImpl = (createState) => {
6973
7065
  let state;
6974
7066
  const listeners = /* @__PURE__ */ new Set();
@@ -6992,7 +7084,7 @@ var createStoreImpl = (createState) => {
6992
7084
  };
6993
7085
  var createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);
6994
7086
 
6995
- // node_modules/zustand/esm/react.mjs
7087
+ // ../reportwright/node_modules/zustand/esm/react.mjs
6996
7088
  var import_react = __toESM(require_react(), 1);
6997
7089
  var identity = (arg) => arg;
6998
7090
  function useStore(api, selector = identity) {
@@ -7008,7 +7100,7 @@ function useStore(api, selector = identity) {
7008
7100
  // src/designer/store.js
7009
7101
  var import_react2 = __toESM(require_react(), 1);
7010
7102
 
7011
- // node_modules/immer/dist/immer.mjs
7103
+ // ../reportwright/node_modules/immer/dist/immer.mjs
7012
7104
  var NOTHING = /* @__PURE__ */ Symbol.for("immer-nothing");
7013
7105
  var DRAFTABLE = /* @__PURE__ */ Symbol.for("immer-draftable");
7014
7106
  var DRAFT_STATE = /* @__PURE__ */ Symbol.for("immer-state");
@@ -8284,8 +8376,7 @@ function duplicateSelection() {
8284
8376
  const f = findItem(d, id);
8285
8377
  if (!f) continue;
8286
8378
  const copy = cloneWithIds(f.item, used);
8287
- copy.x += PASTE_OFFSET;
8288
- copy.y += PASTE_OFFSET;
8379
+ offsetCopy(f.list, copy);
8289
8380
  growToFit(d, { ...f, item: copy });
8290
8381
  f.list.push(copy);
8291
8382
  newIds.push(copy.id);
@@ -8294,6 +8385,14 @@ function duplicateSelection() {
8294
8385
  if (newIds.length) S().select({ kind: "items", ids: newIds });
8295
8386
  }
8296
8387
  var PASTE_OFFSET = 12;
8388
+ function offsetCopy(list2, c) {
8389
+ for (const k of ["x", "y"]) if (!Number.isFinite(c[k])) c[k] = 0;
8390
+ for (let n = 0; n <= list2.length; n++) {
8391
+ c.x += PASTE_OFFSET;
8392
+ c.y += PASTE_OFFSET;
8393
+ if (!list2.some((i2) => i2 !== c && i2.x === c.x && i2.y === c.y)) return;
8394
+ }
8395
+ }
8297
8396
  var CLIP = "pagewright/items@1";
8298
8397
  async function copySelection() {
8299
8398
  const { sel, def } = S();
@@ -8325,9 +8424,8 @@ function pasteItems(section = "body", text = null) {
8325
8424
  const used = allNames(d);
8326
8425
  for (const it of data.items) {
8327
8426
  const c = cloneWithIds(it, used);
8328
- c.x += PASTE_OFFSET;
8329
- c.y += PASTE_OFFSET;
8330
8427
  if (c.type === "table" && !isBodyKey(section)) continue;
8428
+ offsetCopy(secOf(d, section).items, c);
8331
8429
  secOf(d, section).items.push(c);
8332
8430
  growToFit(d, { section, parent: null, item: c });
8333
8431
  ids.push(c.id);
@@ -8610,6 +8708,7 @@ function alignItems(ids, how, toPage = false) {
8610
8708
  });
8611
8709
  }
8612
8710
  var round = (v) => Math.round(v * 100) / 100;
8711
+ var nudgeStep = ({ snap, grid, cells, cellSize }, shift2) => (cells ? cellSize : snap ? grid : 1) * (shift2 ? 10 : 1);
8613
8712
  var clamp = (v, a, b) => Math.max(a, Math.min(b, v));
8614
8713
  var CELL_TAKEN = () => t(S().lang, "cellTaken");
8615
8714
  var overlap = (a, b) => a.x < b.x + Math.max(b.w, 1) - 0.01 && b.x < a.x + Math.max(a.w, 1) - 0.01 && a.y < b.y + Math.max(b.h, 1) - 0.01 && b.y < a.y + Math.max(a.h, 1) - 0.01;
@@ -8700,7 +8799,47 @@ function ExprInput({ value, onChange, onOpen, placeholder: placeholder2 }) {
8700
8799
  issues.map((i2, k) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "warn", "data-testid": "field-warning", children: issueText(T, i2) }, k))
8701
8800
  ] });
8702
8801
  }
8802
+ function InfoTip({ text, id }) {
8803
+ const T = useT();
8804
+ const own = (0, import_react3.useId)();
8805
+ const tipId = id || `tip${own.replace(/:/g, "")}`;
8806
+ const [open, setOpen] = (0, import_react3.useState)(false);
8807
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "infotip", onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false), children: [
8808
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
8809
+ "button",
8810
+ {
8811
+ type: "button",
8812
+ className: "infotip-btn",
8813
+ "aria-label": T("c132_moreInfo"),
8814
+ "aria-describedby": tipId,
8815
+ "aria-expanded": open,
8816
+ onClick: () => setOpen((v) => !v),
8817
+ onFocus: () => setOpen(true),
8818
+ onBlur: () => setOpen(false),
8819
+ onKeyDown: (e) => {
8820
+ if (e.key === "Escape" && open) {
8821
+ e.preventDefault();
8822
+ e.stopPropagation();
8823
+ setOpen(false);
8824
+ }
8825
+ },
8826
+ children: "ⓘ"
8827
+ }
8828
+ ),
8829
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { role: "tooltip", id: tipId, className: "infotip-text", hidden: !open, children: text })
8830
+ ] });
8831
+ }
8832
+ var LONG_HINT = 90;
8703
8833
  function Field({ label, children, hint }) {
8834
+ if (typeof hint === "string" && hint.length > LONG_HINT) {
8835
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "field-tip", children: [
8836
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "field", children: [
8837
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: label }),
8838
+ children
8839
+ ] }),
8840
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InfoTip, { text: hint })
8841
+ ] });
8842
+ }
8704
8843
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "field", children: [
8705
8844
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: label }),
8706
8845
  children,
@@ -9131,8 +9270,8 @@ function ThemeSection() {
9131
9270
  }
9132
9271
  ) }),
9133
9272
  mode === "report" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: T("themeReportPick"), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ReportSelect, { value: src, exclude: id, onChange: setSrc, "data-testid": "theme-picker", "aria-label": T("themeReportPick") }) }),
9134
- mode === "expr" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: T("themeExprLabel"), hint: T("themeExprHint"), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TextInput, { mono: true, value: src || "", onChange: (v) => setSrc(v ? v.startsWith("=") ? v : `=${v}` : void 0), placeholder: '=IIf(Parameters.Dark, "dark-theme", "light-theme")', "data-testid": "theme-expr", "ari\
9135
- a-label": T("themeExprLabel") }) }),
9273
+ mode === "expr" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: T("themeExprLabel"), hint: T("themeExprHint"), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TextInput, { mono: true, value: src || "", onChange: (v) => setSrc(v ? v.startsWith("=") ? v : `=${v}` : void 0), placeholder: '=IIf(Parameters.Dark, "dark-theme", "light-theme")', "data-testid": "theme-expr", [("ari"+
9274
+ "a-label")]: T("themeExprLabel") }) }),
9136
9275
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hint", children: mode === "own" ? T("themeOwnHint") : T("themeFallbackHint") }),
9137
9276
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "grid2", "data-testid": "theme-colors", children: THEME_COLORS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Field, { label: k, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ColorInput, { value: td.colors?.[k] ?? DEFAULT_THEME.colors[k], onChange: (v) => setTd((x) => {
9138
9277
  x.colors || (x.colors = {});
@@ -9196,7 +9335,11 @@ function LayersPanel() {
9196
9335
  });
9197
9336
  });
9198
9337
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pane", "data-testid": "layers", children: [
9199
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", { children: T("layers") }),
9338
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
9339
+ T("layers"),
9340
+ " ",
9341
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InfoTip, { text: T("layersHint") })
9342
+ ] }) }),
9200
9343
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pane-body", children: [
9201
9344
  layers.map((l, i2) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "layer-row", "data-layer": l.name, children: [
9202
9345
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TextInput, { value: l.name, onChange: (v) => rename(i2, v.replace(/[^\w -]/g, "")), "aria-label": T("layerName"), readOnly: readOnly2 }),
@@ -9241,8 +9384,7 @@ function LayersPanel() {
9241
9384
  children: T("layerAdd")
9242
9385
  }
9243
9386
  )
9244
- ] }),
9245
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hint", children: T("layersHint") })
9387
+ ] })
9246
9388
  ] })
9247
9389
  ] });
9248
9390
  }
@@ -9332,7 +9474,11 @@ function PartsPanel() {
9332
9474
  const [pick, setPick] = (0, import_react7.useState)("");
9333
9475
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pane", "data-testid": "parts-panel", children: [
9334
9476
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("h4", { children: [
9335
- T("parts"),
9477
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
9478
+ T("parts"),
9479
+ " ",
9480
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InfoTip, { text: T("partsHint") })
9481
+ ] }),
9336
9482
  libs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "btn sm ghost", onClick: () => libs.forEach((l) => fetchReused(l, true)), title: T("partsReloadHint"), children: T("partsReload") })
9337
9483
  ] }),
9338
9484
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pane-body", children: [
@@ -9355,8 +9501,7 @@ function PartsPanel() {
9355
9501
  children: T("libraryAdd")
9356
9502
  }
9357
9503
  )
9358
- ] }),
9359
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hint", children: T("partsHint") })
9504
+ ] })
9360
9505
  ] })
9361
9506
  ] });
9362
9507
  }
@@ -9907,8 +10052,8 @@ function Band({ section, label, scale, bw: bandW, drag, setDrag, phBox = null })
9907
10052
  (mb.extras || []).map((p) => {
9908
10053
  const i2 = (contentList || []).findIndex((e) => e?.placeholder === p.name);
9909
10054
  if (i2 >= 0) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Band, { section: `content:${i2}`, scale, bw: p.w, drag, setDrag, phBox: p }, p.name);
9910
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "band master-content", style: { position: "absolute", left: p.x * scale, top: p.y * scale, width: p.w * scale, height: p.h * scale, display: "flex", alignItems: "center", justifyContent: "center" }, "data-placeholder": p.name, children: !readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "\
9911
- btn sm", onClick: () => fillPlaceholder(p), "data-testid": `fill-placeholder-${p.name}`, children: T("fillPlaceholder", { name: p.name }) }) }, p.name);
10055
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "band master-content", style: { position: "absolute", left: p.x * scale, top: p.y * scale, width: p.w * scale, height: p.h * scale, display: "flex", alignItems: "center", justifyContent: "center" }, "data-placeholder": p.name, children: !readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: (""+
10056
+ "btn sm"), onClick: () => fillPlaceholder(p), "data-testid": `fill-placeholder-${p.name}`, children: T("fillPlaceholder", { name: p.name }) }) }, p.name);
9912
10057
  })
9913
10058
  ] }) : surface
9914
10059
  ] });
@@ -10280,6 +10425,13 @@ function PartPreview({ item, scale }) {
10280
10425
  tag
10281
10426
  ] });
10282
10427
  }
10428
+ function checkedOnCanvas(v) {
10429
+ if (v == null || typeof v === "boolean" || typeof v === "number") return v === true || v === 1;
10430
+ const s = String(v).trim();
10431
+ if (!isDynamic(s)) return ["true", "yes", "y", "1"].includes(s.toLowerCase());
10432
+ const lit2 = /^=\s*(true|false|1|0)\s*$/i.exec(s)?.[1]?.toLowerCase();
10433
+ return lit2 ? lit2 === "true" || lit2 === "1" : null;
10434
+ }
10283
10435
  function ItemBody({ item, scale }) {
10284
10436
  const base2 = useDesigner((s) => s.def.styles?.base);
10285
10437
  const images = useDesigner((s) => s.def.images);
@@ -10342,8 +10494,9 @@ function ItemBody({ item, scale }) {
10342
10494
  if (item.type === "checkbox") {
10343
10495
  const c = textCss([base2, item.style], scale, false);
10344
10496
  const size = Math.min(item.h, (Number(item.style?.fontSize) || Number(base2?.fontSize) || 9) + 2) * scale;
10497
+ const on = checkedOnCanvas(item.value);
10345
10498
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "box", style: { ...c.box, alignItems: "center", gap: 4 * scale, padding: 0 }, children: [
10346
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { width: size, height: size, border: "1px solid #1f2328", borderRadius: 2, flex: "none", display: "grid", placeItems: "center", fontSize: size * 0.8 }, children: "✓" }),
10499
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "data-checked": String(on), style: { width: size, height: size, border: "1px solid #1f2328", borderRadius: 2, flex: "none", display: "grid", placeItems: "center", fontSize: size * 0.8, opacity: on == null ? 0.4 : 1 }, children: on !== false ? "✓" : "" }),
10347
10500
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `tx${isDynamic(item.text) ? " dyn" : ""}`, style: c.text, children: shown(item.text) })
10348
10501
  ] });
10349
10502
  }
@@ -10607,14 +10760,14 @@ var import_react10 = __toESM(require_react(), 1);
10607
10760
  // src/designer/ExprCode.jsx
10608
10761
  var import_react9 = __toESM(require_react(), 1);
10609
10762
 
10610
- // node_modules/@marijn/find-cluster-break/src/index.js
10763
+ // ../reportwright/node_modules/@marijn/find-cluster-break/src/index.js
10611
10764
  var rangeFrom = [];
10612
10765
  var rangeTo = [];
10613
10766
  (() => {
10614
- let numbers = "lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,1n,9,16,o,,x,1i,3,,i,,7,a,2,t,3,1k,,,7,2,2,2,3,9,,a,2,q,,2,3,1k,,,5,4,2,2,3,3,,u,2,3,,b,3,1k,,,8,,3,,3,k,2,m,6,,3,1k,,,7,2,2,2,3,7,3,a,2,u,,1n,5,3,3,,4,9,,14,5,1j,,,7,,3,,4,7,2,b,2,t,3,1k,,,7,,3,,4,7,2,b,2,f,,c,4,1j,2,,7,,3,,4,9,,a,2,t,3,1y,,4,6,,,,8,i,2,1p,,,8,c,8,2q,,,a,b,7,21,2,r,,,,,,\
10615
- 4,2,1d,k,,2,5,b,,10,9,,2u,b,,6,n,4,4,3,g,4,d,,,3,6,,f,,jj,3,qa,4,s,3,t,2,u,2,1s,w,9,,19,3,,,39,2,y,,3a,c,4,c,63,5,1l,a,,,,,2,o,2,,1c,1a,2,c,k,5,1b,h,12,9,c,3,u,d,1k,e,1c,k,48,3,,l,4,,6,,2,3,5i,1s,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,n,5,4,,2b,2,1e,i,q,i,d,,12,8,p,d,18,4,1b,e,10,,1v,e,c,,8,2,1a,,1f,,,3,2,2,5,2,,,15,5,5,2,6k,8,,2,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,\
10616
- 14,3,4,,4l,2,fx,4,1t,5,8t,2,25,6,1y,b,1d,4,3e,3,1h,f,15,,2,2,a,4,19,b,7,,1p,3,10,e,g,2,18,,c,3,1c,e,8,4,,2,2k,c,6,,2,,4d,c,l,4,1j,2,,7,2,2,2,3,9,,a,2,2,7,3,5,1v,9,,,2,,,4,,5,,,e,2,2a,i,n,,29,k,6j,7,2,9,r,2,2a,h,2y,d,2t,3,2,a,74,f,6t,6,,2,2,4,,,,2,3x,7,2,7,3,,s,a,14,7,,4,8,,9,b,1a,g,5i,8,5j,8,,8,2a,m,,e,3e,6,3,,,2,,7,,,1u,5,,2,,5,9n,4,9,2,,,1c,7,3,5,n,,44l,,6,f,8ug,i,1xc,5,1n,7,t4,,,1j,7,4,29,,b,2,\
10617
- f57,2,3mp,1a,2,n,f2,5,3,6,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,2s,,4g,7,af,,1p,4,e4,4,72,2,6r,,2,,7,2,5,,d6,7,31,7,240,5".split(",").map((s) => s ? parseInt(s, 36) : 1);
10767
+ let numbers = ("lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,1n,9,16,o,,x,1i,3,,i,,7,a,2,t,3,1k,,,7,2,2,2,3,9,,a,2,q,,2,3,1k,,,5,4,2,2,3,3,,u,2,3,,b,3,1k,,,8,,3,,3,k,2,m,6,,3,1k,,,7,2,2,2,3,7,3,a,2,u,,1n,5,3,3,,4,9,,14,5,1j,,,7,,3,,4,7,2,b,2,t,3,1k,,,7,,3,,4,7,2,b,2,f,,c,4,1j,2,,7,,3,,4,9,,a,2,t,3,1y,,4,6,,,,8,i,2,1p,,,8,c,8,2q,,,a,b,7,21,2,r,,,,,,"+
10768
+ "4,2,1d,k,,2,5,b,,10,9,,2u,b,,6,n,4,4,3,g,4,d,,,3,6,,f,,jj,3,qa,4,s,3,t,2,u,2,1s,w,9,,19,3,,,39,2,y,,3a,c,4,c,63,5,1l,a,,,,,2,o,2,,1c,1a,2,c,k,5,1b,h,12,9,c,3,u,d,1k,e,1c,k,48,3,,l,4,,6,,2,3,5i,1s,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,n,5,4,,2b,2,1e,i,q,i,d,,12,8,p,d,18,4,1b,e,10,,1v,e,c,,8,2,1a,,1f,,,3,2,2,5,2,,,15,5,5,2,6k,8,,2,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,"+
10769
+ "14,3,4,,4l,2,fx,4,1t,5,8t,2,25,6,1y,b,1d,4,3e,3,1h,f,15,,2,2,a,4,19,b,7,,1p,3,10,e,g,2,18,,c,3,1c,e,8,4,,2,2k,c,6,,2,,4d,c,l,4,1j,2,,7,2,2,2,3,9,,a,2,2,7,3,5,1v,9,,,2,,,4,,5,,,e,2,2a,i,n,,29,k,6j,7,2,9,r,2,2a,h,2y,d,2t,3,2,a,74,f,6t,6,,2,2,4,,,,2,3x,7,2,7,3,,s,a,14,7,,4,8,,9,b,1a,g,5i,8,5j,8,,8,2a,m,,e,3e,6,3,,,2,,7,,,1u,5,,2,,5,9n,4,9,2,,,1c,7,3,5,n,,44l,,6,f,8ug,i,1xc,5,1n,7,t4,,,1j,7,4,29,,b,2,"+
10770
+ "f57,2,3mp,1a,2,n,f2,5,3,6,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,2s,,4g,7,af,,1p,4,e4,4,72,2,6r,,2,,7,2,5,,d6,7,31,7,240,5").split(",").map((s) => s ? parseInt(s, 36) : 1);
10618
10771
  for (let i2 = 0, n = 0; i2 < numbers.length; i2++)
10619
10772
  (i2 % 2 ? rangeTo : rangeFrom).push(n = n + numbers[i2]);
10620
10773
  })();
@@ -10684,7 +10837,7 @@ function codePointSize(code2) {
10684
10837
  return code2 < 65536 ? 1 : 2;
10685
10838
  }
10686
10839
 
10687
- // node_modules/@codemirror/state/dist/index.js
10840
+ // ../reportwright/node_modules/@codemirror/state/dist/index.js
10688
10841
  var Text = class _Text {
10689
10842
  /**
10690
10843
  Get the line description around the given position.
@@ -14096,7 +14249,7 @@ function findColumn(string2, col, tabSize, strict) {
14096
14249
  return strict === true ? -1 : string2.length;
14097
14250
  }
14098
14251
 
14099
- // node_modules/style-mod/src/style-mod.js
14252
+ // ../reportwright/node_modules/style-mod/src/style-mod.js
14100
14253
  var C = "ͼ";
14101
14254
  var COUNT = typeof Symbol == "undefined" ? "__" + C : Symbol.for(C);
14102
14255
  var SET = typeof Symbol == "undefined" ? "__styleSet" + Math.floor(Math.random() * 1e8) : /* @__PURE__ */ Symbol("styleSet");
@@ -14232,7 +14385,7 @@ var StyleSet = class {
14232
14385
  }
14233
14386
  };
14234
14387
 
14235
- // node_modules/w3c-keyname/index.js
14388
+ // ../reportwright/node_modules/w3c-keyname/index.js
14236
14389
  var base = {
14237
14390
  8: "Backspace",
14238
14391
  9: "Tab",
@@ -14338,7 +14491,7 @@ function keyName(event) {
14338
14491
  return name2;
14339
14492
  }
14340
14493
 
14341
- // node_modules/@codemirror/view/dist/index.js
14494
+ // ../reportwright/node_modules/@codemirror/view/dist/index.js
14342
14495
  var nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
14343
14496
  var doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
14344
14497
  var ie_edge = /* @__PURE__ */ /Edge\/(\d+)/.exec(nav.userAgent);
@@ -23214,7 +23367,7 @@ GutterMarker.prototype.mapMode = MapMode.TrackBefore;
23214
23367
  GutterMarker.prototype.startSide = GutterMarker.prototype.endSide = -1;
23215
23368
  GutterMarker.prototype.point = true;
23216
23369
 
23217
- // node_modules/@lezer/common/dist/index.js
23370
+ // ../reportwright/node_modules/@lezer/common/dist/index.js
23218
23371
  var DefaultBufferLength = 1024;
23219
23372
  var nextPropID = 0;
23220
23373
  var Range2 = class {
@@ -24838,7 +24991,7 @@ var StringInput = class {
24838
24991
  };
24839
24992
  var stoppedInner = new NodeProp({ perNode: true });
24840
24993
 
24841
- // node_modules/@lezer/highlight/dist/index.js
24994
+ // ../reportwright/node_modules/@lezer/highlight/dist/index.js
24842
24995
  var nextTagID = 0;
24843
24996
  var Tag = class _Tag {
24844
24997
  /**
@@ -25562,7 +25715,7 @@ var classHighlighter = tagHighlighter([
25562
25715
  { tag: tags.punctuation, class: "tok-punctuation" }
25563
25716
  ]);
25564
25717
 
25565
- // node_modules/@codemirror/language/dist/index.js
25718
+ // ../reportwright/node_modules/@codemirror/language/dist/index.js
25566
25719
  var _a;
25567
25720
  var languageDataProp = /* @__PURE__ */ new NodeProp();
25568
25721
  function defineLanguageFacet(baseData) {
@@ -27189,7 +27342,7 @@ var marks = {
27189
27342
  auto: /* @__PURE__ */ Decoration.mark({ class: "cm-iso", inclusive: true, attributes: { dir: "auto" }, bidiIsolate: null })
27190
27343
  };
27191
27344
 
27192
- // node_modules/@codemirror/commands/dist/index.js
27345
+ // ../reportwright/node_modules/@codemirror/commands/dist/index.js
27193
27346
  var toggleComment = (target) => {
27194
27347
  let { state } = target, line2 = state.doc.lineAt(state.selection.main.from), config2 = getConfig(target.state, line2.from);
27195
27348
  return config2.line ? toggleLineComment(target) : config2.block ? toggleBlockCommentByLine(target) : false;
@@ -28283,7 +28436,7 @@ var defaultKeymap = /* @__PURE__ */ [
28283
28436
  { key: "Ctrl-m", mac: "Shift-Alt-m", run: toggleTabFocusMode }
28284
28437
  ].concat(standardKeymap);
28285
28438
 
28286
- // node_modules/@codemirror/autocomplete/dist/index.js
28439
+ // ../reportwright/node_modules/@codemirror/autocomplete/dist/index.js
28287
28440
  var CompletionContext = class {
28288
28441
  /**
28289
28442
  Create a new completion context. (Mostly useful for testing
@@ -30845,8 +30998,8 @@ function GroupsEditor({ table: table2, openExpr }) {
30845
30998
  }
30846
30999
  }, `${table2.id}.g${i2}.collapsible`) }),
30847
31000
  g.collapsible && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("i_startCollapsed"), checked: g.initiallyCollapsed, onChange: (v) => setG(i2, "initiallyCollapsed", v) }),
30848
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("groupParent"), hint: T("groupParentHint"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExprInput, { value: g.parent || "", onChange: (v) => setG(i2, "parent", v), onOpen: () => openExpr({ value: g.parent || "", dataSet: table2.dataSet, onSave: (v) => setG(i2, "parent", v), title: T("groupParent") }), placeholder: "=\
30849
- Fields.managerId" }) }),
31001
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("groupParent"), hint: T("groupParentHint"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExprInput, { value: g.parent || "", onChange: (v) => setG(i2, "parent", v), onOpen: () => openExpr({ value: g.parent || "", dataSet: table2.dataSet, onSave: (v) => setG(i2, "parent", v), title: T("groupParent") }), placeholder: ("="+
31002
+ "Fields.managerId") }) }),
30850
31003
  g.parent && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid2", children: [
30851
31004
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("groupIndent"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NumberInput, { value: g.indent || 0, step: 1, onChange: (v) => setG(i2, "indent", Math.max(0, v) || void 0) }) }),
30852
31005
  g.collapsible && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("groupExpandLevels"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NumberInput, { value: g.expandLevels ?? "", step: 1, onChange: (v) => setG(i2, "expandLevels", Number.isFinite(v) && v >= 0 ? Math.round(v) : void 0) }) })
@@ -31039,8 +31192,8 @@ function OverlaysEditor({ value, onChange, openExpr, dataSet, chartType }) {
31039
31192
  numOrExpr(o, i2, "from", T("i_from")),
31040
31193
  numOrExpr(o, i2, "to", T("i_to"))
31041
31194
  ] }),
31042
- (o.type === "line" || o.type === "band") && chartType !== "gauge" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("overlayAxis"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: o.axis || "primary", options: [{ value: "primary", label: T("axisPrimary") }, { value: "secondary", label: T("axisSecondary") }], onChange: (v) => set2(i2, "axis", v === "p\
31043
- rimary" ? void 0 : v), "aria-label": `${T("overlayAxis")} ${i2 + 1}` }) }),
31195
+ (o.type === "line" || o.type === "band") && chartType !== "gauge" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("overlayAxis"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: o.axis || "primary", options: [{ value: "primary", label: T("axisPrimary") }, { value: "secondary", label: T("axisSecondary") }], onChange: (v) => set2(i2, "axis", v === ("p"+
31196
+ "rimary") ? void 0 : v), "aria-label": `${T("overlayAxis")} ${i2 + 1}` }) }),
31044
31197
  o.type === "line" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("overlayShowValue"), checked: o.showValue !== false, onChange: (v) => set2(i2, "showValue", v ? void 0 : false) }),
31045
31198
  chartType !== "gauge" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("overlayInLegend"), checked: o.legend !== false, onChange: (v) => set2(i2, "legend", v ? void 0 : false) }),
31046
31199
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("i_label"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TextInput, { value: o.label, onChange: (v) => set2(i2, "label", v), "aria-label": T("i_overlayLabel") }) })
@@ -31202,8 +31355,8 @@ function ActionEditor({ value, onChange, openExpr, dataSet, label }) {
31202
31355
  const target = useReportParams(a.type === "report" ? a.report : null);
31203
31356
  const own = (def.parameters || []).map((p) => ({ name: p.name, prompt: p.prompt }));
31204
31357
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "grid", gap: 6 }, children: [
31205
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: label || T("i_actionOnClick"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: a.type, options: [{ value: "none", label: T("i_actNone") }, { value: "url", label: T("i_actUrl") }, { value: "report", label: T("i_actReport") }, { value: "params", label: T("i_actParams") }, { value: "bookmark", label: T("i_actBo\
31206
- okmark") }, { value: "toggleItem", label: T("actionToggleItem") }], onChange: (v) => set2({ type: v || "none" }) }) }),
31358
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: label || T("i_actionOnClick"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: a.type, options: [{ value: "none", label: T("i_actNone") }, { value: "url", label: T("i_actUrl") }, { value: "report", label: T("i_actReport") }, { value: "params", label: T("i_actParams") }, { value: "bookmark", label: T(("i_actBo"+
31359
+ "okmark")) }, { value: "toggleItem", label: T("actionToggleItem") }], onChange: (v) => set2({ type: v || "none" }) }) }),
31207
31360
  a.type === "toggleItem" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("actionToggleTarget"), hint: T("actionToggleHint"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: a.target, allowEmpty: true, options: itemNames, onChange: (v) => set2({ target: v }), "data-testid": "toggle-target" }) }),
31208
31361
  a.type === "url" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("i_url"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExprInput, { value: a.url, onChange: (v) => set2({ url: v }), onOpen: () => openExpr({ value: a.url, dataSet, onSave: (v) => set2({ url: v }), title: T("i_url") }) }) }),
31209
31362
  a.type === "bookmark" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("jumpToBookmark"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExprInput, { value: a.target, onChange: (v) => set2({ target: v }), onOpen: () => openExpr({ value: a.target, dataSet, onSave: (v) => set2({ target: v }), title: T("jumpToBookmark") }) }) }),
@@ -31337,8 +31490,8 @@ function CellProps({ table: table2, sel, openExpr }) {
31337
31490
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("i_heightPt"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(NumberInput, { value: row.height || 18, step: 1, onChange: (v) => setRow("height", Math.max(6, v)) }) }),
31338
31491
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Check, { label: T("rowCanGrow"), checked: row.canGrow !== false, onChange: (v) => setRow("canGrow", v ? void 0 : false) })
31339
31492
  ] }),
31340
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("rowHidden"), hint: T("rowHiddenHint"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExprInput, { value: row.hidden, onChange: (v) => setRow("hidden", v || void 0), onOpen: () => openExpr({ value: row.hidden, dataSet: table2.dataSet, onSave: (v) => setRow("hidden", v || void 0), title: T("rowHidden") }), placeholder: "\
31341
- =Fields.amount = 0" }) }),
31493
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("rowHidden"), hint: T("rowHiddenHint"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ExprInput, { value: row.hidden, onChange: (v) => setRow("hidden", v || void 0), onOpen: () => openExpr({ value: row.hidden, dataSet: table2.dataSet, onSave: (v) => setRow("hidden", v || void 0), title: T("rowHidden") }), placeholder: (""+
31494
+ "=Fields.amount = 0") }) }),
31342
31495
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "grid2", children: ROW_STYLE.map((p) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: p.type === "color" || p.type === "text" ? { gridColumn: "1 / -1" } : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PropEditor, { p, value: row.style?.[p.key], onChange: (v) => setRowStyle(p.key, v), openExpr,
31343
31496
  dataSet: table2.dataSet }) }, p.key)) }),
31344
31497
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "hint", children: T("rowStyleHint") }),
@@ -31611,9 +31764,10 @@ function ReportProps() {
31611
31764
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("i_currency"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TextInput, { value: def.currency, onChange: (v) => set2((d) => {
31612
31765
  d.currency = v.toUpperCase() || void 0;
31613
31766
  }, "currency"), placeholder: "USD" }) }),
31614
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("i_nonFinite"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: def.nonFinite || "", options: [{ value: "", label: T("i_nonFiniteSsrs") }, { value: "blank", label: T("i_nonFiniteBlank") }, { value: "error", label: "#Error" }], onChange: (v) => set2((d) => {
31767
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { gridColumn: "1 / -1" }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Field, { label: T("i_nonFinite"), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Select, { value: def.nonFinite || "", options: [{ value: "", label: T("i_nonFiniteSsrs") }, { value: "blank", label: T("i_nonFiniteBlank") }, { value: "error",
31768
+ label: "#Error" }], onChange: (v) => set2((d) => {
31615
31769
  d.nonFinite = v || void 0;
31616
- }, "nonFinite") }) })
31770
+ }, "nonFinite") }) }) })
31617
31771
  ] })
31618
31772
  ] }),
31619
31773
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cat", children: [
@@ -32284,6 +32438,19 @@ async function loadSample(store) {
32284
32438
  api.setState({ sample: { error: e.message } });
32285
32439
  }
32286
32440
  }
32441
+ function detectedFields(ds, def, sampleRows) {
32442
+ if ((ds?.fields || []).length) return null;
32443
+ let rows = Array.isArray(sampleRows) ? sampleRows : null;
32444
+ if (!rows) {
32445
+ const src = (def?.dataSources || []).find((x) => x.name === ds?.source);
32446
+ try {
32447
+ rows = src?.type === "json" && src.data != null ? sourceRows(src.data, ds.path) : null;
32448
+ } catch {
32449
+ rows = null;
32450
+ }
32451
+ }
32452
+ return rows?.length ? detectFields(rows.slice(0, 50), { dates: ds.detectDates !== false }) : null;
32453
+ }
32287
32454
  function DataPanel() {
32288
32455
  const def = useDesigner((s) => s.def);
32289
32456
  const lang2 = useDesigner((s) => s.lang);
@@ -32385,32 +32552,41 @@ function DataPanel() {
32385
32552
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "btn sm ghost", onClick: () => useDesigner.getState().setUi({ instantVisuals: { dataSet: d.name } }), "data-testid": `instant-${d.name}`, children: T("instantVisuals") }),
32386
32553
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "btn sm ghost", onClick: () => useDesigner.getState().setUi({ pivotWizard: { dataSet: d.name } }), "data-testid": `pivot-wizard-${d.name}`, children: T("pivotWizard") })
32387
32554
  ] }),
32388
- open.has(d.name) && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("ul", { className: "tree", style: { paddingLeft: 18 }, children: [
32389
- (d.fields || []).flatMap((f) => f.type === "object" ? (f.fields || []).map((c) => ({ name: `${f.name}.${c.name}`, type: c.type, nested: true })) : [f]).map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
32390
- "li",
32391
- {
32392
- className: `trow field-chip${f.nested ? " nested" : ""}`,
32393
- draggable: true,
32394
- title: "Drag onto the page or a table cell",
32395
- "data-field": f.name,
32396
- onDragStart: (e) => {
32397
- e.dataTransfer.setData(MIME_FIELD, JSON.stringify({ dataSet: d.name, field: f.name, type: f.type }));
32398
- e.dataTransfer.effectAllowed = "copy";
32555
+ open.has(d.name) && (() => {
32556
+ const found = detectedFields(d, def, sample?.dataSets?.[d.name]);
32557
+ const list2 = (d.fields || []).length ? d.fields : found || [];
32558
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("ul", { className: "tree", style: { paddingLeft: 18 }, "data-testid": `fields-${d.name}`, children: [
32559
+ found && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("li", { className: "subtle", "data-testid": `detected-${d.name}`, children: T("c132_detectedHint") }),
32560
+ list2.flatMap((f) => f.type === "object" ? (f.fields || []).map((c) => ({ name: `${f.name}.${c.name}`, type: c.type, nested: true })) : [f]).map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
32561
+ "li",
32562
+ {
32563
+ className: `trow field-chip${f.nested ? " nested" : ""}`,
32564
+ draggable: true,
32565
+ title: "Drag onto the page or a table cell",
32566
+ "data-field": f.name,
32567
+ "data-detected": found ? "" : void 0,
32568
+ onDragStart: (e) => {
32569
+ e.dataTransfer.setData(MIME_FIELD, JSON.stringify({ dataSet: d.name, field: f.name, type: f.type }));
32570
+ e.dataTransfer.effectAllowed = "copy";
32571
+ },
32572
+ children: [
32573
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "nm", children: f.name }),
32574
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "ty", children: [
32575
+ f.type,
32576
+ found ? ` · ${T("c132_detected")}` : ""
32577
+ ] })
32578
+ ]
32399
32579
  },
32400
- children: [
32401
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "nm", children: f.name }),
32402
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ty", children: f.type })
32403
- ]
32404
- },
32405
- f.name
32406
- )),
32407
- !(d.fields || []).length && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("li", { className: "subtle", children: "No fields. Edit the data set and detect them." })
32408
- ] })
32580
+ f.name
32581
+ )),
32582
+ !list2.length && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("li", { className: "subtle", children: "No fields. Edit the data set and detect them." })
32583
+ ] });
32584
+ })()
32409
32585
  ] }, d.name)),
32410
32586
  !(def.dataSets || []).length && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("li", { className: "subtle", children: "None" })
32411
32587
  ] }),
32412
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "btnrow", style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { className: "btn sm", onClick: loadSample, disabled: sample?.loading || !!noSourceKey(def), title: noSourceKey(def) ? T(noSourceKey(def)) : void 0, "data-testid": "load-sample", children: sample?.loading ? "Loading…" : "Lo\
32413
- ad sample data" }) }),
32588
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "btnrow", style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { className: "btn sm", onClick: loadSample, disabled: sample?.loading || !!noSourceKey(def), title: noSourceKey(def) ? T(noSourceKey(def)) : void 0, "data-testid": "load-sample", children: sample?.loading ? "Loading…" : ("Lo"+
32589
+ "ad sample data") }) }),
32414
32590
  noSourceKey(def) && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "hint", role: "status", style: { marginTop: 6 }, "data-testid": "no-source", children: T(noSourceKey(def)) }),
32415
32591
  sample?.error && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "err", style: { marginTop: 6 }, children: sample.error })
32416
32592
  ] })
@@ -32544,18 +32720,17 @@ function ParamDialog({ index, onClose }) {
32544
32720
  }
32545
32721
  ) }),
32546
32722
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid2", children: [
32547
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("choicesFrom"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: p.optionsFrom?.dataSet, options: (def.dataSets || []).map((d) => d.name), allowEmpty: true, onChange: pickChoiceSet, "data-testid": "param-choices-from" }) }),
32548
- p.optionsFrom && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("valueField"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: fieldOf(p.optionsFrom.value) || "", options: [{ value: "", label: T("ux_choose") }, ...fromFields], onChange: (v) => setP({ ...p, optionsFrom: { ...p.optionsFrom, value: v ? `=Fields.${v}` : "" } }), "data-testid": "param\
32549
- -value-field", "aria-invalid": !p.optionsFrom.value || void 0 }) }),
32723
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("choicesFrom"), hint: T("cascadeHint"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: p.optionsFrom?.dataSet, options: (def.dataSets || []).map((d) => d.name), allowEmpty: true, onChange: pickChoiceSet, "data-testid": "param-choices-from" }) }),
32724
+ p.optionsFrom && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("valueField"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: fieldOf(p.optionsFrom.value) || "", options: [{ value: "", label: T("ux_choose") }, ...fromFields], onChange: (v) => setP({ ...p, optionsFrom: { ...p.optionsFrom, value: v ? `=Fields.${v}` : "" } }), "data-testid": ("param"+
32725
+ "-value-field"), "aria-invalid": !p.optionsFrom.value || void 0 }) }),
32550
32726
  p.optionsFrom && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("labelField"), hint: T("labelFieldHint"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: p.optionsFrom.label, options: labelOpts, allowEmpty: true, onChange: (v) => setP({ ...p, optionsFrom: { ...p.optionsFrom, label: v || void 0 } }), "data-testid": "param-label-field" }) })
32551
32727
  ] }),
32552
32728
  p.optionsFrom && choicePreview && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "hint", "data-testid": "param-choice-preview", children: T("ux_choicePreview", { n: choicePreview.length, list: choicePreview.slice(0, 5).join(", ") + (choicePreview.length > 5 ? ", …" : "") }) }),
32553
- p.optionsFrom && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "hint", children: T("cascadeHint") }),
32554
32729
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid2", children: [
32555
32730
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("editor"), hint: T(`editorHint_${p.editor || "auto"}`), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: p.editor, allowEmpty: true, onChange: setEditor, options: EDITORS.map((e) => ({ value: e, label: T(`editor_${e}`) })) }) }),
32556
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("panelColumns"), hint: T("panelColumnsHint"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: columns, onChange: (v) => setColumns(v || "1"), options: ["1", "2", "3", "4"] }) })
32731
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("panelColumns"), hint: T("c132_panelColumnsHint"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: columns, onChange: (v) => setColumns(v || "1"), options: ["1", "2", "3", "4"] }) })
32557
32732
  ] }),
32558
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Check, { label: T("liveParams"), checked: live, onChange: setLive }),
32733
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Check, { label: T("c132_liveParams"), checked: live, onChange: setLive }),
32559
32734
  limits && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid3", children: [
32560
32735
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("minimum"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TextInput, { value: p.min ?? "", onChange: (v) => setP({ ...p, min: limit(v) }), mono: true, type: p.type === "date" ? "date" : "text" }) }),
32561
32736
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("maximum"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TextInput, { value: p.max ?? "", onChange: (v) => setP({ ...p, max: limit(v) }), mono: true, type: p.type === "date" ? "date" : "text" }) }),
@@ -32769,8 +32944,8 @@ function SourceDialog({ index, onClose }) {
32769
32944
  fetched && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
32770
32945
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: "grid", gridTemplateColumns: s.type === "soap" || s.type === "odata" ? "1fr" : "110px 1fr", gap: 8 }, children: [
32771
32946
  s.type !== "soap" && s.type !== "odata" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: "Method", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: s.method, options: ["GET", "POST"], onChange: (v) => setS({ ...s, method: v }) }) }),
32772
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: "URL", hint: s.type === "odata" ? T("odServiceHint") : s.type === "xml" ? T("srcXmlUrlHint") : "Use {Parameters.x} for values. A relative URL calls this app.", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TextInput, { value: s.url, onChange: (v) => setS({ ...s, url: v }), mono: true, placeholder: "/api/... or http\
32773
- s://..." }) })
32947
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: "URL", hint: s.type === "odata" ? T("odServiceHint") : s.type === "xml" ? T("srcXmlUrlHint") : "Use {Parameters.x} for values. A relative URL calls this app.", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TextInput, { value: s.url, onChange: (v) => setS({ ...s, url: v }), mono: true, placeholder: ("/api/... or http"+
32948
+ "s://...") }) })
32774
32949
  ] }),
32775
32950
  s.type === "soap" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { style: { display: "grid", gridTemplateColumns: "1fr 140px", gap: 8 }, children: [
32776
32951
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: T("srcSoapAction"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TextInput, { value: s.soapAction || "", onChange: (v) => setS({ ...s, soapAction: v }), mono: true, placeholder: "http://tempuri.org/GetOrders" }) }),
@@ -32804,8 +32979,8 @@ s://..." }) })
32804
32979
  label: "Stored procedure" }], onChange: (v) => setS({ ...s, procedure: v === "proc" ? s.procedure ?? procs[0] ?? "" : void 0 }) }) }),
32805
32980
  s.procedure != null ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
32806
32981
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: "Stored procedure", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Select, { value: s.procedure, allowEmpty: true, options: procs.map((p) => ({ value: p, label: p })), onChange: (v) => setS({ ...s, procedure: v }) }) }),
32807
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: "Arguments", hint: "One per line: procedure argument = report parameter (bound, never pasted into SQL). The first result set is the data.", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("textarea", { className: "textarea", rows: 3, value: s.argsText ?? "", onChange: (e) => setS({ ...s, argsText: e.target.value }), placeholder: "\
32808
- region = region\nyear = year", style: { fontFamily: "var(--mono)" } }) })
32982
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: "Arguments", hint: "One per line: procedure argument = report parameter (bound, never pasted into SQL). The first result set is the data.", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("textarea", { className: "textarea", rows: 3, value: s.argsText ?? "", onChange: (e) => setS({ ...s, argsText: e.target.value }), placeholder: (""+
32983
+ "region = region\nyear = year"), style: { fontFamily: "var(--mono)" } }) })
32809
32984
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
32810
32985
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "seg", role: "group", "aria-label": T("qb_mode"), children: [
32811
32986
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-pressed": !!s.builder, onClick: () => {
@@ -32820,8 +32995,8 @@ region = region\nyear = year", style: { fontFamily: "var(--mono)" } }) })
32820
32995
  s.builder ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SqlBuilder, { s, setS, T, kind: sqlKind, onManual: () => {
32821
32996
  const { builder: _b, ...rest } = s;
32822
32997
  setS({ ...rest, query: s.builder ? buildSql(s.builder, sqlKind) : s.query });
32823
- } }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: "Query", hint: "SELECT only. @name uses the report parameter name (bound, never pasted into the SQL). Lists work with in (@name).", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("textarea", { className: "textarea", rows: 6, value: s.query || "", onChange: (e) => setS({ ...s, query: e.target.value }), placeholder: "\
32824
- select region, month, sum(amount) as amount from sales where year = @year group by region, month", style: { fontFamily: "var(--mono)" } }) })
32998
+ } }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Field, { label: "Query", hint: "SELECT only. @name uses the report parameter name (bound, never pasted into the SQL). Lists work with in (@name).", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("textarea", { className: "textarea", rows: 6, value: s.query || "", onChange: (e) => setS({ ...s, query: e.target.value }), placeholder: (""+
32999
+ "select region, month, sum(amount) as amount from sales where year = @year group by region, month"), style: { fontFamily: "var(--mono)" } }) })
32825
33000
  ] })
32826
33001
  ] }),
32827
33002
  s.type === "csv" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid2", children: [
@@ -33133,8 +33308,8 @@ function Outline() {
33133
33308
  const stop = keys.includes(cur2) ? cur2 : keys.find((k) => chosen.has(k) || sel.kind === "section" && k === `band:${sel.section}`) || keys[0];
33134
33309
  const roving = (k) => ({ tabIndex: k === stop ? 0 : -1, onFocus: () => setCur(k) });
33135
33310
  const nav2 = (e) => {
33136
- if (e.defaultPrevented || e.altKey || e.metaKey || e.ctrlKey || e.target.getAttribute("role") !== "option") return;
33137
- const all = [...e.currentTarget.querySelectorAll("[role=option]")];
33311
+ if (e.defaultPrevented || e.altKey || e.metaKey || e.ctrlKey || !e.target.hasAttribute("data-opt")) return;
33312
+ const all = [...e.currentTarget.querySelectorAll("[data-opt]")];
33138
33313
  const i2 = all.indexOf(e.target);
33139
33314
  const j = e.key === "ArrowDown" ? i2 + 1 : e.key === "ArrowUp" ? i2 - 1 : e.key === "Home" ? 0 : e.key === "End" ? all.length - 1 : null;
33140
33315
  if (j == null) return;
@@ -33255,31 +33430,36 @@ function Outline() {
33255
33430
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { role: "none", children: [
33256
33431
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `trow outline-row${chosen.has(it.id) ? " sel" : ""}${mark}`, style: { paddingInlineStart: depth * 14 }, "data-outline": it.name, "data-outline-id": it.id, ...dragProps(it, i2, parent, section), children: [
33257
33432
  !readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "grip", "aria-hidden": "true", children: "⠿" }),
33258
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", role: "option", className: "linklike nm", onClick: (e) => pick(e, it.id), onKeyDown: (e) => onKey(e, it, list2, i2, parent), "aria-selected": chosen.has(it.id), "aria-describedby": readOnly2 ? "outline-nav" : "outline-nav outline-keys", ...roving(it.id), children: it.name }),
33259
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ty", children: T(`item_${it.type}`) === `item_${it.type}` ? ITEMS[it.type]?.label || it.type : T(`item_${it.type}`) }),
33260
- !readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "act", style: { display: "inline-flex", gap: 2 }, children: [
33261
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, disabled: i2 === 0, onClick: () => reorderItem(it.id, -1), title: T("outlineBackward"), "aria-label": `${T("outlineBackward")}: ${it.name}`, children: "↑" }),
33262
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, disabled: i2 === list2.length - 1, onClick: () => reorderItem(it.id, 1), title: T("outlineForward"), "aria-label": `${T("outlineForward")}: ${it.name}`, children: "↓" }),
33263
- parent && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, onClick: () => moveOutOfParent(it.id), title: T("outlineMoveOut", { name: parent.name }), "aria-label": `${T("outlineMoveOut", { name: parent.name })}: ${it.name}`, children: "⇱" })
33433
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", "data-opt": "", className: "linklike nm", onClick: (e) => pick(e, it.id), onKeyDown: (e) => onKey(e, it, list2, i2, parent), "aria-pressed": chosen.has(it.id), "aria-describedby": readOnly2 ? "outline-nav" : "outline-nav outline-keys", title: it.name, ...roving(it.id), children: it.name }),
33434
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "outline-meta", children: [
33435
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ty", children: T(`item_${it.type}`) === `item_${it.type}` ? ITEMS[it.type]?.label || it.type : T(`item_${it.type}`) }),
33436
+ !readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "act", style: { display: "inline-flex", gap: 2 }, children: [
33437
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, disabled: i2 === 0, onClick: () => reorderItem(it.id, -1), title: T("outlineBackward"), "aria-label": `${T("outlineBackward")}: ${it.name}`, children: "↑" }),
33438
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, disabled: i2 === list2.length - 1, onClick: () => reorderItem(it.id, 1), title: T("outlineForward"), "aria-label": `${T("outlineForward")}: ${it.name}`, children: "↓" }),
33439
+ parent && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "btn sm ghost icon", tabIndex: -1, onClick: () => moveOutOfParent(it.id), title: T("outlineMoveOut", { name: parent.name }), "aria-label": `${T("outlineMoveOut", { name: parent.name })}: ${it.name}`, children: "⇱" })
33440
+ ] })
33264
33441
  ] })
33265
33442
  ] }),
33266
33443
  NESTING.has(it.type) && (it.items || []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { className: "tree", role: "none", children: rows(it.items, it, depth + 1, section) })
33267
33444
  ] }, it.id);
33268
33445
  });
33269
33446
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pane", "data-testid": "outline", children: [
33270
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h4", { children: T("outline") }),
33447
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h4", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
33448
+ T("outline"),
33449
+ " ",
33450
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(InfoTip, { text: readOnly2 ? T("outlineHint") : `${T("outlineHint")} ${T("outlineKeys")}` })
33451
+ ] }) }),
33271
33452
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pane-body", ref: body, children: [
33272
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { role: "listbox", "aria-label": T("outline"), "aria-multiselectable": "true", onKeyDown: nav2, children: sectionList(def).map(({ key: key2, label }) => {
33453
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { role: "group", "aria-label": T("outline"), onKeyDown: nav2, children: sectionList(def).map(({ key: key2, label }) => {
33273
33454
  const items = secOf(def, key2)?.items || [];
33274
33455
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { role: "group", "aria-label": label, className: `outline-sec${drop?.band === key2 ? " drop-band" : ""}`, "data-outline-band": key2, ...bandDrop(key2), children: [
33275
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", role: "option", "aria-selected": sel.kind === "section" && sel.section === key2, "aria-describedby": "outline-nav", className: `linklike outline-band${sel.kind === "section" && sel.section === key2 ? " sel" : ""}`, onClick: () => useDesigner.getState().select({ kind: "section", section: key2 }), ...roving(`band:${key2}`),
33456
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", "data-opt": "", "aria-pressed": sel.kind === "section" && sel.section === key2, "aria-describedby": "outline-nav", className: `linklike outline-band${sel.kind === "section" && sel.section === key2 ? " sel" : ""}`, onClick: () => useDesigner.getState().select({ kind: "section", section: key2 }), ...roving(`band:${key2}`),
33276
33457
  children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("b", { children: label }) }),
33277
33458
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { className: "tree", role: "none", children: items.length ? rows(items, null, 1, key2) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("li", { className: "subtle", role: "none", children: T("outlineEmpty") }) })
33278
33459
  ] }, key2);
33279
33460
  }) }),
33280
33461
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "sr-only", id: "outline-nav", children: T("b9_outlineKeys") }),
33281
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "hint", children: T("outlineHint") }),
33282
- !readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "hint", id: "outline-keys", children: T("outlineKeys") }),
33462
+ !readOnly2 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "sr-only", id: "outline-keys", children: T("outlineKeys") }),
33283
33463
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "sr-only", role: "status", "aria-live": "polite", children: said })
33284
33464
  ] })
33285
33465
  ] });
@@ -33586,8 +33766,8 @@ function ChartWizard() {
33586
33766
  c.chartType === "gantt" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "grid2", children: [
33587
33767
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Field, { label: tr("start"), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Select, { value: c.start, allowEmpty: true, options: fields.map((f) => ({ value: f.name, label: `${f.name} · ${f.type}` })), onChange: (v) => set2({ start: v || "" }), "data-testid": "cw-gantt-start" }) }),
33588
33768
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Field, { label: tr("end"), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Select, { value: c.end, allowEmpty: true, options: fields.map((f) => ({ value: f.name, label: `${f.name} · ${f.type}` })), onChange: (v) => set2({ end: v || "" }), "data-testid": "cw-gantt-end" }) })
33589
- ] }) : RAW.has(c.chartType) ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Field, { label: tr("rowValue"), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Select, { value: c.value, allowEmpty: true, options: (numFields.length ? numFields : fields).map((f) => f.name), onChange: (v) => set2({ value: v || "" }) }) }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "\
33590
- grid2", children: [
33769
+ ] }) : RAW.has(c.chartType) ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Field, { label: tr("rowValue"), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Select, { value: c.value, allowEmpty: true, options: (numFields.length ? numFields : fields).map((f) => f.name), onChange: (v) => set2({ value: v || "" }) }) }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: (""+
33770
+ "grid2"), children: [
33591
33771
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Field, { label: tr("value"), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Select, { value: c.agg, options: AGGS.map((a) => ({ value: a.value, label: tr(`agg_${a.value}`) })), onChange: (v) => set2({ agg: v }) }) }),
33592
33772
  c.agg !== "Count" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Field, { label: tr("ofField"), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Select, { value: c.value, allowEmpty: true, options: (numFields.length ? numFields : fields).map((f) => f.name), onChange: (v) => set2({ value: v || "" }) }) })
33593
33773
  ] }),
@@ -33620,8 +33800,8 @@ grid2", children: [
33620
33800
  onClick: () => set2({ chartType: type }),
33621
33801
  "data-chart-type": type,
33622
33802
  children: [
33623
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "cw-thumb", children: !sample?.dataSets ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "hint", children: loading ? tr("calling") : tr("noData") }) : PER_ROW.has(type) && fields.find((f) => f.name === c.category)?.type !== "number" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "\
33624
- hint", children: tr("pickNumber") }) : th?.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "err", children: th.error }) : th ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SvgHtml, { html: th.html }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "hint", children: tr("drawing") }) }),
33803
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "cw-thumb", children: !sample?.dataSets ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "hint", children: loading ? tr("calling") : tr("noData") }) : PER_ROW.has(type) && fields.find((f) => f.name === c.category)?.type !== "number" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: (""+
33804
+ "hint"), children: tr("pickNumber") }) : th?.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "err", children: th.error }) : th ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SvgHtml, { html: th.html }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "hint", children: tr("drawing") }) }),
33625
33805
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "cw-name", children: [
33626
33806
  tr(`t_${type}`),
33627
33807
  good.includes(type) && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("em", { children: tr("suggested") })
@@ -33635,8 +33815,8 @@ hint", children: tr("pickNumber") }) : th?.error ? /* @__PURE__ */ (0, import_js
33635
33815
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "cw-preview", children: [
33636
33816
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "cw-big", children: [
33637
33817
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h5", { children: tr("preview", { type: tr(`t_${c.chartType}`) }) }),
33638
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "cw-paper", children: big?.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "err", children: big.error }) : big ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SvgHtml, { as: "div", html: big.html }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "hint", children: tr("dra\
33639
- wing") }) })
33818
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "cw-paper", children: big?.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "err", children: big.error }) : big ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SvgHtml, { as: "div", html: big.html }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "hint", children: tr(("dra"+
33819
+ "wing")) }) })
33640
33820
  ] }),
33641
33821
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "cw-data", children: [
33642
33822
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h5", { children: tr(ds?.filters?.length ? "apiDataFiltered" : "apiData", { n: rows.length }) }),
@@ -34102,8 +34282,8 @@ function suggestions(ds, picked, width, rows, currency) {
34102
34282
  const text = fields.filter((f) => f.type !== "number"), nums = fields.filter((f) => f.type === "number");
34103
34283
  const out = [];
34104
34284
  if (text.length && nums.length) {
34105
- out.push({ kind: "chart", item: { type: "chart", dataSet: ds.name, w: Math.min(width, 420), h: 200, chartType: text.length > 1 ? "column" : nums.length > 1 ? "line" : "column", category: `=Fields.${text[0].name}`, ...text[1] ? { seriesGroup: `=Fields.${text[1].name}` } : {}, series: nums.slice(0, 3).map((n) => ({ name: labelOf(n.name), value: `=Sum(Fields.${n.name})` })), legend: "bottom", valueFormat: "\
34106
- N0", title: `${nums.map((n) => labelOf(n.name)).join(", ")} by ${labelOf(text[0].name)}` } });
34285
+ out.push({ kind: "chart", item: { type: "chart", dataSet: ds.name, w: Math.min(width, 420), h: 200, chartType: text.length > 1 ? "column" : nums.length > 1 ? "line" : "column", category: `=Fields.${text[0].name}`, ...text[1] ? { seriesGroup: `=Fields.${text[1].name}` } : {}, series: nums.slice(0, 3).map((n) => ({ name: labelOf(n.name), value: `=Sum(Fields.${n.name})` })), legend: "bottom", valueFormat: (""+
34286
+ "N0"), title: `${nums.map((n) => labelOf(n.name)).join(", ")} by ${labelOf(text[0].name)}` } });
34107
34287
  }
34108
34288
  if (fields.length) out.push({ kind: "table", item: tableFor(ds, { layout: text.length && nums.length ? "summary" : "list", groupBy: text[0]?.name, width, rows, currency, fields: fields.map((f) => f.name) }) });
34109
34289
  if (text.length) out.push({ kind: "pivot", item: pivotFor(ds, { rows: [text[0].name], columns: text[1] ? [text[1].name] : [], values: nums.slice(0, 2).map((n) => ({ field: n.name, agg: "Sum" })), width, sample: rows, currency }) });
@@ -34378,7 +34558,7 @@ function LeftRail({ T, readOnly: readOnly2, embed }) {
34378
34558
  const el = body.current?.querySelector(`[data-rail="${id}"]`);
34379
34559
  if (el) {
34380
34560
  body.current.scrollTo({ top: el.offsetTop - body.current.offsetTop, behavior: "smooth" });
34381
- (el.querySelector('[role=listbox] [tabindex="0"]') || el.querySelector("button, input, select, textarea"))?.focus({ preventScroll: true });
34561
+ (el.querySelector('[data-opt][tabindex="0"]') || el.querySelector("button, input, select, textarea"))?.focus({ preventScroll: true });
34382
34562
  }
34383
34563
  setAt(id);
34384
34564
  };
@@ -34453,6 +34633,7 @@ function StatusBar({ T, zoom, setZoom }) {
34453
34633
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("i", { "aria-hidden": "true" }),
34454
34634
  what
34455
34635
  ] }),
34636
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "hint dstatus-hint", title: T("canvasHint"), children: T("canvasHint") }),
34456
34637
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "dstatus-page", children: page })
34457
34638
  ] });
34458
34639
  }
@@ -34646,8 +34827,8 @@ var SHORTCUTS = [
34646
34827
  ["⌘/Ctrl C / V", "sc_copy"],
34647
34828
  ["⌘/Ctrl D", "sc_duplicate"],
34648
34829
  ["Delete / Backspace", "sc_delete"],
34649
- ["← ↑ → ↓", "sc_nudge"],
34650
- ["⇧ ← ↑ → ↓", "sc_nudge4"],
34830
+ ["← ↑ → ↓", "c132_nudge1"],
34831
+ ["⇧ ← ↑ → ↓", "c132_nudge10"],
34651
34832
  ["⇧ Click", "sc_toggle"],
34652
34833
  ["Drag", "sc_marquee"],
34653
34834
  ["Alt + Drag", "sc_guides"],
@@ -34838,7 +35019,7 @@ function DesignerIn({ id, initial, rev = null, lang: langIn, embed = null, user
34838
35019
  const arrows = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1] };
34839
35020
  if (arrows[e.key] && st().sel.kind === "items") {
34840
35021
  e.preventDefault();
34841
- const step = st().cells ? st().cellSize : e.shiftKey ? st().grid * 4 : 1;
35022
+ const step = nudgeStep(st(), e.shiftKey);
34842
35023
  const [dx, dy] = arrows[e.key];
34843
35024
  const s = st();
34844
35025
  s.lastKey = null;
@@ -35028,7 +35209,7 @@ function DesignerIn({ id, initial, rev = null, lang: langIn, embed = null, user
35028
35209
  tableWizard && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TableWizard, {}),
35029
35210
  pivotWizard && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PivotWizard, {}),
35030
35211
  instantVisuals && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InstantVisuals, {}),
35031
- tab === "preview" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("main", { className: "dpreview", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ReportViewer, { definition: def, reportId: id, compact: true, lang: lang2 }) }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
35212
+ tab === "preview" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("main", { className: "dpreview", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ReportViewer, { definition: def, reportId: id, compact: true, lang: lang2, showWarnings: true }) }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
35032
35213
  "div",
35033
35214
  {
35034
35215
  className: "dmain",
@@ -35059,8 +35240,7 @@ function DesignerIn({ id, initial, rev = null, lang: langIn, embed = null, user
35059
35240
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("select", { className: "select", style: { width: 72 }, value: unit, onChange: (e) => st().setUi({ unit: e.target.value }), children: ["pt", "mm", "cm", "in"].map((u) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("option", { children: u }, u)) })
35060
35241
  ] }),
35061
35242
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AlignBar, { T }),
35062
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(IssuesButton, { T }),
35063
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "hint cbar-hint", children: T("canvasHint") })
35243
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(IssuesButton, { T })
35064
35244
  ] }),
35065
35245
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Canvas, {}),
35066
35246
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StatusBar, { T, zoom, setZoom: (z) => {
@@ -35204,6 +35384,19 @@ button, input, select, textarea { font: inherit; color: inherit; }
35204
35384
  .input.invalid, .textarea.invalid { border-color: var(--danger); background: var(--danger-soft); }
35205
35385
  .err { color: var(--danger); font-size: var(--fs-xs); }
35206
35386
  .hint { color: var(--faint); font-size: var(--fs-xs); }
35387
+ /* ⓘ help (InfoTip): the text opens on hover, focus or click, over the content; Esc closes it */
35388
+ .infotip { position: relative; display: inline-flex; vertical-align: middle; text-transform: none; letter-spacing: normal; font-weight: normal; }
35389
+ .infotip-btn { border: 0; background: none; padding: 0 2px; margin: 0; font: inherit; font-size: 13px; line-height: 1; color: var(--muted); cursor: help; border-radius: 3px; }
35390
+ .infotip-btn:hover, .infotip-btn[aria-expanded=true] { color: var(--accent); }
35391
+ .infotip-text { position: absolute; z-index: 30; top: calc(100% + 4px); inset-inline-end: -4px; width: max-content; max-width: min(280px, 70vw); padding: 8px 10px; border: 1px solid var(--line-strong); border-radius: 6px; background: var(--panel); color: var(--ink); box-shadow: 0 4px 14px rgb(0 0 0 / .14); font-size: var(--fs-xs); line-height: 1.45; white-space: normal; text-align: start; }
35392
+ .infotip-text[hidden] { display: none; }
35393
+ .field-tip { position: relative; min-width: 0; }
35394
+ .field-tip > .field > span:first-child { padding-inline-end: 18px; }
35395
+ .field-tip > .infotip { position: absolute; top: 0; inset-inline-end: 0; }
35396
+ /* in a panel heading the text spans the panel (the heading is its containing block: sticky) */
35397
+ .pane > h4 { position: relative; }
35398
+ .pane > h4 .infotip { position: static; }
35399
+ .pane > h4 .infotip-text { top: 100%; inset-inline: 8px; width: auto; max-width: none; z-index: 5; }
35207
35400
  .check { display: flex; align-items: center; gap: 7px; cursor: pointer; }
35208
35401
  .kbd { font-family: var(--mono); font-size: var(--fs-2xs); padding: 1px 4px; border: 1px solid var(--line); border-radius: 3px; background: var(--panel-2); color: var(--muted); }
35209
35402
 
@@ -35451,7 +35644,14 @@ a.cell-name:hover { color: var(--accent); }
35451
35644
  .trow:hover .act, .trow:focus-within .act { opacity: 1; }
35452
35645
  .outline-row.sel { background: var(--accent-soft); }
35453
35646
  .outline-row .linklike.nm, .outline-band { text-decoration: none; color: var(--ink); text-align: start; }
35647
+ /* a long name wraps inside the panel's width (no cut-off text); the type and the buttons keep their size */
35648
+ /* (the type and the buttons, together, go under a name too long to share the line) */
35649
+ .outline-row { flex-wrap: wrap; }
35650
+ .outline-row .linklike.nm { flex: 1 1 auto; white-space: normal; overflow-wrap: anywhere; }
35651
+ .outline-meta { display: inline-flex; align-items: center; gap: 6px; flex: none; margin-inline-start: auto; }
35652
+ .outline-meta .btn.icon { width: 22px; }
35454
35653
  .outline-row.sel .linklike.nm, .outline-band.sel { color: var(--accent); }
35654
+ .outline-row.sel .ty { color: var(--muted); } /* --faint is 4.38:1 on --accent-soft; --muted passes in both themes */
35455
35655
  .outline-row.sel .act, .outline-row:focus-within .act { opacity: 1; }
35456
35656
  .outline-row[draggable="true"] { cursor: grab; }
35457
35657
  .outline-row .grip { color: var(--faint); font-size: 10px; line-height: 1; margin-inline-start: -2px; opacity: .55; }
@@ -35966,19 +36166,21 @@ a.cell-name:hover { color: var(--accent); }
35966
36166
  .dleft .tool svg { width: 16px; height: 16px; }
35967
36167
  /* canvas: the page centred on the desk, rulers along the top and beside each band */
35968
36168
  .dcenter { grid-template-rows: auto minmax(0, 1fr) auto; background: var(--desk); }
35969
- .cbar { gap: 8px 16px; padding: 6px 16px; min-height: 40px; background: var(--panel); }
36169
+ /* one row of a fixed height: the align buttons that come with a selection never push the canvas down (c132) */
36170
+ .cbar { gap: 8px 16px; padding: 6px 16px; height: 40px; box-sizing: border-box; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; background: var(--panel); }
36171
+ .cbar > * { flex: none; white-space: nowrap; }
35970
36172
  .cbar .select { height: 28px; }
35971
- .cbar-hint { margin-inline-start: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1 1 120px; text-align: end; }
35972
36173
  .cscroll { padding: 24px 40px 80px 56px; }
35973
36174
  .paper { border-radius: 2px; }
35974
36175
  .ruler.v { position: absolute; left: -44px; top: 0; pointer-events: none; overflow: visible; }
35975
- .dstatus { display: flex; align-items: center; gap: 16px; min-height: 32px; padding: 2px 12px; border-top: 1px solid var(--line); background: var(--panel); font-size: var(--fs-xs); color: var(--muted); }
36176
+ .dstatus { display: flex; align-items: center; gap: 16px; height: 32px; box-sizing: border-box; white-space: nowrap; padding: 2px 12px; border-top: 1px solid var(--line); background: var(--panel); font-size: var(--fs-xs); color: var(--muted); }
35976
36177
  .dstatus-zoom { display: inline-flex; align-items: center; gap: 2px; }
35977
36178
  .dstatus-zoom .select { height: 26px; width: 92px; border-color: var(--line); font-size: var(--fs-xs); }
35978
36179
  .dstatus-zoom .btn.icon { width: 26px; height: 26px; }
35979
36180
  .dstatus-sel { display: inline-flex; align-items: center; gap: 8px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); font-family: var(--mono); }
35980
36181
  .dstatus-sel i { flex: none; width: 8px; height: 8px; border-radius: 2px; background: var(--accent); }
35981
- .dstatus-page { margin-inline-start: auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
36182
+ .dstatus-hint { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; text-align: end; }
36183
+ .dstatus-page { white-space: nowrap; font-variant-numeric: tabular-nums; }
35982
36184
  /* inspector: roomier sections */
35983
36185
  .dright .insp-head { position: sticky; top: 0; z-index: 3; background: var(--panel); padding: 12px 16px; }
35984
36186
  .dright .cat { padding: 8px 16px 16px; gap: 8px; }
@@ -36013,7 +36215,7 @@ input[type=checkbox], input[type=radio] { width: 16px; height: 16px; accent-colo
36013
36215
 
36014
36216
  .pw-embed{display:block;font:var(--fw-regular) var(--fs-base)/var(--lh) var(--ui);color:var(--ink);background:var(--desk);border:1px solid var(--line);border-radius:8px;overflow:hidden}
36015
36217
  ` : "";
36016
- var BLANK = { $schema: "pagewright/report@1", name: "Untitled report", page: { size: "A4", margins: [36, 36, 36, 36] }, dataSources: [], dataSets: [], sections: { body: { items: [] } } };
36218
+ var BLANK = { $schema: "reportwright/report@1", name: "Untitled report", page: { size: "A4", margins: [36, 36, 36, 36] }, dataSources: [], dataSets: [], sections: { body: { items: [] } } };
36017
36219
  function mountDesigner(target, opts = {}) {
36018
36220
  const el = typeof target === "string" ? document.querySelector(target) : target;
36019
36221
  if (!el) throw new Error(`mountDesigner: no element for ${target}`);