minerva-design 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/charts/canvas.d.cts +7 -0
  3. package/dist/charts/canvas.d.ts +7 -0
  4. package/dist/charts/core.cjs +1 -1
  5. package/dist/charts/core.d.cts +5 -1
  6. package/dist/charts/core.d.ts +5 -1
  7. package/dist/charts/core.js +4 -1
  8. package/dist/charts/engine/canvas.cjs +2 -0
  9. package/dist/charts/engine/canvas.cjs.map +1 -0
  10. package/dist/charts/engine/canvas.d.cts +85 -0
  11. package/dist/charts/engine/canvas.d.ts +85 -0
  12. package/dist/charts/engine/canvas.js +165 -0
  13. package/dist/charts/engine/canvas.js.map +1 -0
  14. package/dist/charts/engine/chart.cjs +2 -2
  15. package/dist/charts/engine/chart.cjs.map +1 -1
  16. package/dist/charts/engine/chart.js +382 -440
  17. package/dist/charts/engine/chart.js.map +1 -1
  18. package/dist/charts/engine/color.cjs +1 -1
  19. package/dist/charts/engine/color.cjs.map +1 -1
  20. package/dist/charts/engine/color.d.cts +10 -0
  21. package/dist/charts/engine/color.d.ts +10 -0
  22. package/dist/charts/engine/color.js +75 -3
  23. package/dist/charts/engine/color.js.map +1 -1
  24. package/dist/charts/engine/controller.cjs +3 -0
  25. package/dist/charts/engine/controller.cjs.map +1 -0
  26. package/dist/charts/engine/controller.d.cts +182 -0
  27. package/dist/charts/engine/controller.d.ts +182 -0
  28. package/dist/charts/engine/controller.js +528 -0
  29. package/dist/charts/engine/controller.js.map +1 -0
  30. package/dist/charts/engine/model.cjs +1 -1
  31. package/dist/charts/engine/model.cjs.map +1 -1
  32. package/dist/charts/engine/model.d.cts +2 -2
  33. package/dist/charts/engine/model.d.ts +2 -2
  34. package/dist/charts/engine/model.js +72 -72
  35. package/dist/charts/engine/model.js.map +1 -1
  36. package/dist/charts/engine/overlay.cjs +1 -1
  37. package/dist/charts/engine/overlay.cjs.map +1 -1
  38. package/dist/charts/engine/overlay.d.cts +17 -1
  39. package/dist/charts/engine/overlay.d.ts +17 -1
  40. package/dist/charts/engine/overlay.js +63 -49
  41. package/dist/charts/engine/overlay.js.map +1 -1
  42. package/dist/charts/engine/presets.cjs +3 -0
  43. package/dist/charts/engine/presets.cjs.map +1 -0
  44. package/dist/charts/engine/presets.d.cts +103 -0
  45. package/dist/charts/engine/presets.d.ts +103 -0
  46. package/dist/charts/engine/presets.js +153 -0
  47. package/dist/charts/engine/presets.js.map +1 -0
  48. package/dist/charts/engine/renderers/canvas2d.cjs +1 -1
  49. package/dist/charts/engine/renderers/canvas2d.cjs.map +1 -1
  50. package/dist/charts/engine/renderers/canvas2d.d.cts +17 -1
  51. package/dist/charts/engine/renderers/canvas2d.d.ts +17 -1
  52. package/dist/charts/engine/renderers/canvas2d.js +88 -51
  53. package/dist/charts/engine/renderers/canvas2d.js.map +1 -1
  54. package/dist/charts/engine/scene.cjs +2 -0
  55. package/dist/charts/engine/scene.cjs.map +1 -0
  56. package/dist/charts/engine/scene.d.cts +89 -0
  57. package/dist/charts/engine/scene.d.ts +89 -0
  58. package/dist/charts/engine/scene.js +241 -0
  59. package/dist/charts/engine/scene.js.map +1 -0
  60. package/dist/charts/engine/theme.cjs +1 -1
  61. package/dist/charts/engine/theme.cjs.map +1 -1
  62. package/dist/charts/engine/theme.d.cts +25 -1
  63. package/dist/charts/engine/theme.d.ts +25 -1
  64. package/dist/charts/engine/theme.js +42 -26
  65. package/dist/charts/engine/theme.js.map +1 -1
  66. package/dist/charts/engine/types.d.cts +69 -2
  67. package/dist/charts/engine/types.d.ts +69 -2
  68. package/dist/charts/index.cjs +1 -1
  69. package/dist/charts/index.d.cts +1 -1
  70. package/dist/charts/index.d.ts +1 -1
  71. package/dist/charts/index.js +5 -2
  72. package/dist/charts/react/Chart.cjs +1 -1
  73. package/dist/charts/react/Chart.cjs.map +1 -1
  74. package/dist/charts/react/Chart.d.cts +11 -4
  75. package/dist/charts/react/Chart.d.ts +11 -4
  76. package/dist/charts/react/Chart.js +81 -39
  77. package/dist/charts/react/Chart.js.map +1 -1
  78. package/dist/charts/react/charts.cjs +1 -1
  79. package/dist/charts/react/charts.cjs.map +1 -1
  80. package/dist/charts/react/charts.d.cts +1 -1
  81. package/dist/charts/react/charts.d.ts +1 -1
  82. package/dist/charts/react/charts.js +99 -145
  83. package/dist/charts/react/charts.js.map +1 -1
  84. package/dist/charts/react/types.d.cts +29 -61
  85. package/dist/charts/react/types.d.ts +29 -61
  86. package/dist/native/charts/src/canvas.cjs +1 -0
  87. package/dist/native/charts/src/canvas.js +6 -0
  88. package/dist/native/charts/src/engine/axis.cjs +2 -0
  89. package/dist/native/charts/src/engine/axis.cjs.map +1 -0
  90. package/dist/native/charts/src/engine/axis.js +38 -0
  91. package/dist/native/charts/src/engine/axis.js.map +1 -0
  92. package/dist/native/charts/src/engine/canvas.cjs +1 -0
  93. package/dist/native/charts/src/engine/canvas.js +1 -0
  94. package/dist/native/charts/src/engine/color.cjs +2 -0
  95. package/dist/native/charts/src/engine/color.cjs.map +1 -0
  96. package/dist/native/charts/src/engine/color.js +130 -0
  97. package/dist/native/charts/src/engine/color.js.map +1 -0
  98. package/dist/native/charts/src/engine/controller.cjs +3 -0
  99. package/dist/native/charts/src/engine/controller.cjs.map +1 -0
  100. package/dist/native/charts/src/engine/controller.js +528 -0
  101. package/dist/native/charts/src/engine/controller.js.map +1 -0
  102. package/dist/native/charts/src/engine/data.cjs +2 -0
  103. package/dist/native/charts/src/engine/data.cjs.map +1 -0
  104. package/dist/native/charts/src/engine/data.js +104 -0
  105. package/dist/native/charts/src/engine/data.js.map +1 -0
  106. package/dist/native/charts/src/engine/decimate.cjs +2 -0
  107. package/dist/native/charts/src/engine/decimate.cjs.map +1 -0
  108. package/dist/native/charts/src/engine/decimate.js +28 -0
  109. package/dist/native/charts/src/engine/decimate.js.map +1 -0
  110. package/dist/native/charts/src/engine/format.cjs +2 -0
  111. package/dist/native/charts/src/engine/format.cjs.map +1 -0
  112. package/dist/native/charts/src/engine/format.js +34 -0
  113. package/dist/native/charts/src/engine/format.js.map +1 -0
  114. package/dist/native/charts/src/engine/layout.cjs +2 -0
  115. package/dist/native/charts/src/engine/layout.cjs.map +1 -0
  116. package/dist/native/charts/src/engine/layout.js +26 -0
  117. package/dist/native/charts/src/engine/layout.js.map +1 -0
  118. package/dist/native/charts/src/engine/model.cjs +2 -0
  119. package/dist/native/charts/src/engine/model.cjs.map +1 -0
  120. package/dist/native/charts/src/engine/model.js +175 -0
  121. package/dist/native/charts/src/engine/model.js.map +1 -0
  122. package/dist/native/charts/src/engine/overlay.cjs +2 -0
  123. package/dist/native/charts/src/engine/overlay.cjs.map +1 -0
  124. package/dist/native/charts/src/engine/overlay.js +49 -0
  125. package/dist/native/charts/src/engine/overlay.js.map +1 -0
  126. package/dist/native/charts/src/engine/presets.cjs +3 -0
  127. package/dist/native/charts/src/engine/presets.cjs.map +1 -0
  128. package/dist/native/charts/src/engine/presets.js +147 -0
  129. package/dist/native/charts/src/engine/presets.js.map +1 -0
  130. package/dist/native/charts/src/engine/scale.cjs +2 -0
  131. package/dist/native/charts/src/engine/scale.cjs.map +1 -0
  132. package/dist/native/charts/src/engine/scale.js +37 -0
  133. package/dist/native/charts/src/engine/scale.js.map +1 -0
  134. package/dist/native/charts/src/engine/scene.cjs +2 -0
  135. package/dist/native/charts/src/engine/scene.cjs.map +1 -0
  136. package/dist/native/charts/src/engine/scene.js +241 -0
  137. package/dist/native/charts/src/engine/scene.js.map +1 -0
  138. package/dist/native/charts/src/engine/spatial.cjs +2 -0
  139. package/dist/native/charts/src/engine/spatial.cjs.map +1 -0
  140. package/dist/native/charts/src/engine/spatial.js +53 -0
  141. package/dist/native/charts/src/engine/spatial.js.map +1 -0
  142. package/dist/native/charts/src/engine/theme.cjs +2 -0
  143. package/dist/native/charts/src/engine/theme.cjs.map +1 -0
  144. package/dist/native/charts/src/engine/theme.js +62 -0
  145. package/dist/native/charts/src/engine/theme.js.map +1 -0
  146. package/dist/native/charts/src/engine/time.cjs +2 -0
  147. package/dist/native/charts/src/engine/time.cjs.map +1 -0
  148. package/dist/native/charts/src/engine/time.js +189 -0
  149. package/dist/native/charts/src/engine/time.js.map +1 -0
  150. package/dist/native/charts/src/engine/viewport.cjs +2 -0
  151. package/dist/native/charts/src/engine/viewport.cjs.map +1 -0
  152. package/dist/native/charts/src/engine/viewport.js +12 -0
  153. package/dist/native/charts/src/engine/viewport.js.map +1 -0
  154. package/dist/native/components/Chart/ChartBase.cjs +2 -0
  155. package/dist/native/components/Chart/ChartBase.cjs.map +1 -0
  156. package/dist/native/components/Chart/ChartBase.d.cts +29 -0
  157. package/dist/native/components/Chart/ChartBase.d.ts +29 -0
  158. package/dist/native/components/Chart/ChartBase.js +287 -0
  159. package/dist/native/components/Chart/ChartBase.js.map +1 -0
  160. package/dist/native/components/Chart/charts.cjs +2 -0
  161. package/dist/native/components/Chart/charts.cjs.map +1 -0
  162. package/dist/native/components/Chart/charts.d.cts +19 -0
  163. package/dist/native/components/Chart/charts.d.ts +19 -0
  164. package/dist/native/components/Chart/charts.js +173 -0
  165. package/dist/native/components/Chart/charts.js.map +1 -0
  166. package/dist/native/components/Chart/index.cjs +1 -0
  167. package/dist/native/components/Chart/index.d.cts +2 -0
  168. package/dist/native/components/Chart/index.d.ts +2 -0
  169. package/dist/native/components/Chart/index.js +2 -0
  170. package/dist/native/components/Chart/measure.cjs +2 -0
  171. package/dist/native/components/Chart/measure.cjs.map +1 -0
  172. package/dist/native/components/Chart/measure.d.cts +5 -0
  173. package/dist/native/components/Chart/measure.d.ts +5 -0
  174. package/dist/native/components/Chart/measure.js +11 -0
  175. package/dist/native/components/Chart/measure.js.map +1 -0
  176. package/dist/native/components/Chart/scene.cjs +2 -0
  177. package/dist/native/components/Chart/scene.cjs.map +1 -0
  178. package/dist/native/components/Chart/scene.d.cts +41 -0
  179. package/dist/native/components/Chart/scene.d.ts +41 -0
  180. package/dist/native/components/Chart/scene.js +419 -0
  181. package/dist/native/components/Chart/scene.js.map +1 -0
  182. package/dist/native/components/Chart/theme.cjs +2 -0
  183. package/dist/native/components/Chart/theme.cjs.map +1 -0
  184. package/dist/native/components/Chart/theme.d.cts +10 -0
  185. package/dist/native/components/Chart/theme.d.ts +10 -0
  186. package/dist/native/components/Chart/theme.js +10 -0
  187. package/dist/native/components/Chart/theme.js.map +1 -0
  188. package/dist/native/components/Chart/types.d.cts +129 -0
  189. package/dist/native/components/Chart/types.d.ts +129 -0
  190. package/dist/native/index.cjs +1 -1
  191. package/dist/native/index.d.cts +1 -0
  192. package/dist/native/index.d.ts +1 -0
  193. package/dist/native/index.js +6 -4
  194. package/dist/native/manifest.d.cts +7 -0
  195. package/dist/native/manifest.d.ts +7 -0
  196. package/dist/native/source/components/Chart/ChartBase.tsx +545 -0
  197. package/dist/native/source/components/Chart/charts.tsx +291 -0
  198. package/dist/native/source/components/Chart/index.ts +8 -0
  199. package/dist/native/source/components/Chart/measure.ts +50 -0
  200. package/dist/native/source/components/Chart/scene.tsx +987 -0
  201. package/dist/native/source/components/Chart/theme.ts +16 -0
  202. package/dist/native/source/components/Chart/types.ts +194 -0
  203. package/dist/native/source/index.ts +1 -0
  204. package/dist/native/source/manifest.ts +14 -0
  205. package/dist/taro/charts.d.ts +144 -0
  206. package/dist/taro/index.d.ts +1 -0
  207. package/dist/taro/index.js +3064 -618
  208. package/dist/uni/BarChart.vue +75 -0
  209. package/dist/uni/BarChart.vue.d.ts +111 -0
  210. package/dist/uni/Chart.vue +68 -0
  211. package/dist/uni/Chart.vue.d.ts +100 -0
  212. package/dist/uni/LineChart.vue +75 -0
  213. package/dist/uni/LineChart.vue.d.ts +111 -0
  214. package/dist/uni/ProgressIndicator.vue.d.ts +1 -1
  215. package/dist/uni/QuadrantChart.vue +184 -0
  216. package/dist/uni/QuadrantChart.vue.d.ts +173 -0
  217. package/dist/uni/ScatterChart.vue +69 -0
  218. package/dist/uni/ScatterChart.vue.d.ts +100 -0
  219. package/dist/uni/chart-canvas.d.ts +68 -0
  220. package/dist/uni/chart-canvas.js +363 -0
  221. package/dist/uni/chart-types.d.ts +135 -0
  222. package/dist/uni/chart-types.js +84 -0
  223. package/dist/uni/charts-canvas.d.ts +1 -0
  224. package/dist/uni/charts-canvas.js +8 -0
  225. package/dist/uni/index.d.ts +6 -0
  226. package/dist/uni/index.js +6 -0
  227. package/dist/weapp/bar-chart/index.js +1 -0
  228. package/dist/weapp/bar-chart/index.json +1 -0
  229. package/dist/weapp/bar-chart/index.wxml +1 -0
  230. package/dist/weapp/bar-chart/index.wxss +1 -0
  231. package/dist/weapp/chart/index.js +1 -0
  232. package/dist/weapp/chart/index.json +1 -0
  233. package/dist/weapp/chart/index.wxml +1 -0
  234. package/dist/weapp/chart/index.wxss +1 -0
  235. package/dist/weapp/controls.js +4019 -266
  236. package/dist/weapp/line-chart/index.js +1 -0
  237. package/dist/weapp/line-chart/index.json +1 -0
  238. package/dist/weapp/line-chart/index.wxml +1 -0
  239. package/dist/weapp/line-chart/index.wxss +1 -0
  240. package/dist/weapp/quadrant-chart/index.js +1 -0
  241. package/dist/weapp/quadrant-chart/index.json +1 -0
  242. package/dist/weapp/quadrant-chart/index.wxml +1 -0
  243. package/dist/weapp/quadrant-chart/index.wxss +1 -0
  244. package/dist/weapp/scatter-chart/index.js +1 -0
  245. package/dist/weapp/scatter-chart/index.json +1 -0
  246. package/dist/weapp/scatter-chart/index.wxml +1 -0
  247. package/dist/weapp/scatter-chart/index.wxss +1 -0
  248. package/dist/weapp/types.d.ts +295 -0
  249. package/package.json +21 -1
@@ -431,7 +431,7 @@ var ref = /* @__NO_SIDE_EFFECTS__ */ (name) => ({
431
431
  kind: "ref",
432
432
  name
433
433
  });
434
- var mix = /* @__NO_SIDE_EFFECTS__ */ (a, amount, b) => ({
434
+ var mix$1 = /* @__NO_SIDE_EFFECTS__ */ (a, amount, b) => ({
435
435
  kind: "mix",
436
436
  a,
437
437
  amount,
@@ -482,20 +482,20 @@ function mergeBlocks(...blocks) {
482
482
  var lengthCss = (value) => value === 0 ? "0" : `${value}px`;
483
483
  /** CSS text of a token value, exactly as written in `tokens.css`. */
484
484
  /*#__NO_SIDE_EFFECTS__*/
485
- function toCss(value) {
485
+ function toCss$1(value) {
486
486
  if (typeof value === "string") return value;
487
487
  if (typeof value === "number") return String(value);
488
488
  switch (value.kind) {
489
489
  case "ref": return `var(--${value.name})`;
490
- case "mix": return `color-mix(in srgb, ${/* @__PURE__ */ toCss(value.a)} ${value.amount}%, ${/* @__PURE__ */ toCss(value.b)})`;
490
+ case "mix": return `color-mix(in srgb, ${/* @__PURE__ */ toCss$1(value.a)} ${value.amount}%, ${/* @__PURE__ */ toCss$1(value.b)})`;
491
491
  case "length": return value.value === 0 ? "0" : `${value.value}${value.unit}`;
492
- case "clamp": return `clamp(${/* @__PURE__ */ toCss(value.min)}, ${value.vw}vw, ${/* @__PURE__ */ toCss(value.max)})`;
492
+ case "clamp": return `clamp(${/* @__PURE__ */ toCss$1(value.min)}, ${value.vw}vw, ${/* @__PURE__ */ toCss$1(value.max)})`;
493
493
  case "shadow": return value.layers.length === 0 ? "none" : value.layers.map((layer) => [
494
494
  lengthCss(layer.x),
495
495
  lengthCss(layer.y),
496
496
  lengthCss(layer.blur),
497
497
  ...layer.spread === void 0 ? [] : [lengthCss(layer.spread)],
498
- /* @__PURE__ */ toCss(layer.color)
498
+ /* @__PURE__ */ toCss$1(layer.color)
499
499
  ].join(" ")).join(", ");
500
500
  case "transition": return `${value.duration}ms ${value.easing}`;
501
501
  case "cubic-bezier": return `cubic-bezier(${value.points.join(", ")})`;
@@ -605,7 +605,7 @@ var radiusTokens = {
605
605
  "radius-2xl": /* @__PURE__ */ px$1(24)
606
606
  }
607
607
  };
608
- var faded = /* @__NO_SIDE_EFFECTS__ */ (amount) => /* @__PURE__ */ mix(/* @__PURE__ */ ref("shadow-color"), amount, "transparent");
608
+ var faded = /* @__NO_SIDE_EFFECTS__ */ (amount) => /* @__PURE__ */ mix$1(/* @__PURE__ */ ref("shadow-color"), amount, "transparent");
609
609
  /** Shadow scale ("standard" keeps the theme / palette shadows: no block). */
610
610
  var shadowTokens = {
611
611
  none: {
@@ -710,21 +710,21 @@ var shadowColor = /* @__PURE__ */ ref("shadow-color");
710
710
  /** Semantic tokens derived from the base tokens. */
711
711
  var semanticTokens = {
712
712
  "surface-color": bg,
713
- "surface-muted-color": /* @__PURE__ */ mix(fg, 6, bg),
713
+ "surface-muted-color": /* @__PURE__ */ mix$1(fg, 6, bg),
714
714
  "surface-elevated-color": bg,
715
- "surface-subtle-color": /* @__PURE__ */ mix(fg, 3, bg),
715
+ "surface-subtle-color": /* @__PURE__ */ mix$1(fg, 3, bg),
716
716
  "canvas-color": /* @__PURE__ */ ref("surface-subtle-color"),
717
717
  "control-color": /* @__PURE__ */ ref("surface-subtle-color"),
718
718
  "hover-color": /* @__PURE__ */ ref("surface-muted-color"),
719
- "selected-color": /* @__PURE__ */ mix(/* @__PURE__ */ ref("primary-color"), 14, surface),
720
- "overlay-color": /* @__PURE__ */ mix("#000000", 45, "transparent"),
721
- "border-strong-color": /* @__PURE__ */ mix(fg, 35, bg),
719
+ "selected-color": /* @__PURE__ */ mix$1(/* @__PURE__ */ ref("primary-color"), 14, surface),
720
+ "overlay-color": /* @__PURE__ */ mix$1("#000000", 45, "transparent"),
721
+ "border-strong-color": /* @__PURE__ */ mix$1(fg, 35, bg),
722
722
  "text-color": fg,
723
- "text-secondary-color": /* @__PURE__ */ mix(fg, 75, bg),
724
- "text-muted-color": /* @__PURE__ */ mix(fg, 62, bg),
725
- "text-disabled-color": /* @__PURE__ */ mix(fg, 45, bg),
723
+ "text-secondary-color": /* @__PURE__ */ mix$1(fg, 75, bg),
724
+ "text-muted-color": /* @__PURE__ */ mix$1(fg, 62, bg),
725
+ "text-disabled-color": /* @__PURE__ */ mix$1(fg, 45, bg),
726
726
  "text-inverse-color": "#ffffff",
727
- "focus-ring-color": /* @__PURE__ */ mix(/* @__PURE__ */ ref("primary-color"), 45, "transparent"),
727
+ "focus-ring-color": /* @__PURE__ */ mix$1(/* @__PURE__ */ ref("primary-color"), 45, "transparent"),
728
728
  "shadow-sm": /* @__PURE__ */ shadow({
729
729
  x: 0,
730
730
  y: 1,
@@ -765,11 +765,11 @@ var ROLE_COLORS = [
765
765
  var roleTokens = /* @__NO_SIDE_EFFECTS__ */ (color) => {
766
766
  const c = /* @__PURE__ */ ref(`${color}-color`);
767
767
  return {
768
- [`${color}-color-hover`]: /* @__PURE__ */ mix(c, 85, fg),
769
- [`${color}-color-active`]: /* @__PURE__ */ mix(c, 72, fg),
770
- [`${color}-color-subtle`]: /* @__PURE__ */ mix(c, 12, surface),
771
- [`${color}-color-border`]: /* @__PURE__ */ mix(c, 40, surface),
772
- [`${color}-color-text`]: /* @__PURE__ */ mix(c, 80, fg)
768
+ [`${color}-color-hover`]: /* @__PURE__ */ mix$1(c, 85, fg),
769
+ [`${color}-color-active`]: /* @__PURE__ */ mix$1(c, 72, fg),
770
+ [`${color}-color-subtle`]: /* @__PURE__ */ mix$1(c, 12, surface),
771
+ [`${color}-color-border`]: /* @__PURE__ */ mix$1(c, 40, surface),
772
+ [`${color}-color-text`]: /* @__PURE__ */ mix$1(c, 80, fg)
773
773
  };
774
774
  };
775
775
  /** Role tokens of every role color. */
@@ -1535,7 +1535,7 @@ var reducedMotionTokens = {
1535
1535
  //#endregion
1536
1536
  //#region ../core/src/tokens/color.ts
1537
1537
  /** CSS basic named colors (+ `transparent`) */
1538
- var NAMED = {
1538
+ var NAMED$1 = {
1539
1539
  black: "#000000",
1540
1540
  silver: "#c0c0c0",
1541
1541
  gray: "#808080",
@@ -1559,7 +1559,7 @@ var NAMED = {
1559
1559
  transparent: "#00000000"
1560
1560
  };
1561
1561
  var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
1562
- function parseHex(hex) {
1562
+ function parseHex$1(hex) {
1563
1563
  if (!/^[\da-f]+$/i.test(hex)) return void 0;
1564
1564
  const digits = hex.length === 3 || hex.length === 4 ? hex.replace(/./g, (d) => d + d) : hex;
1565
1565
  if (digits.length !== 6 && digits.length !== 8) return void 0;
@@ -1618,7 +1618,7 @@ function mixArgument(text) {
1618
1618
  const trailing = /^(.+?)\s+(-?[\d.]+)%$/s.exec(text);
1619
1619
  const leading = /^(-?[\d.]+)%\s+(.+)$/s.exec(text);
1620
1620
  const [colorText, pctText] = trailing ? [trailing[1], trailing[2]] : leading ? [leading[2], leading[1]] : [text, void 0];
1621
- const color = parseColor(colorText);
1621
+ const color = parseColor$1(colorText);
1622
1622
  if (!color) return void 0;
1623
1623
  return {
1624
1624
  color,
@@ -1631,10 +1631,10 @@ function mixArgument(text) {
1631
1631
  * `transparent` and `color-mix(in srgb, ...)` (nested mixes included).
1632
1632
  * Returns `undefined` for anything else (system colors, other color spaces).
1633
1633
  */
1634
- function parseColor(text) {
1634
+ function parseColor$1(text) {
1635
1635
  const value = text.trim().toLowerCase();
1636
- if (value.startsWith("#")) return parseHex(value.slice(1));
1637
- if (value in NAMED) return parseHex(NAMED[value].slice(1));
1636
+ if (value.startsWith("#")) return parseHex$1(value.slice(1));
1637
+ if (value in NAMED$1) return parseHex$1(NAMED$1[value].slice(1));
1638
1638
  const fn = /^([a-z-]+)\((.*)\)$/s.exec(value);
1639
1639
  if (!fn) return void 0;
1640
1640
  const [, name, args] = fn;
@@ -1874,7 +1874,7 @@ function evaluateShadow(text, context) {
1874
1874
  if (length === void 0) rest.push(part);
1875
1875
  else lengths.push(length);
1876
1876
  }
1877
- const color = parseColor(rest.length ? rest.join(" ") : "black");
1877
+ const color = parseColor$1(rest.length ? rest.join(" ") : "black");
1878
1878
  if (lengths.length < 2 || lengths.length > 4 || !color) return void 0;
1879
1879
  const [x, y, blur = 0, spread = 0] = lengths;
1880
1880
  layers.push({
@@ -1895,7 +1895,7 @@ function evaluateShadow(text, context) {
1895
1895
  l.color
1896
1896
  ].join(" ")).join(", ");
1897
1897
  const first = layers[0];
1898
- const color = parseColor(first.color);
1898
+ const color = parseColor$1(first.color);
1899
1899
  return {
1900
1900
  css,
1901
1901
  layers,
@@ -2062,7 +2062,7 @@ function tokenCascade({ mode = "light", palette, design: designOptions, override
2062
2062
  const chosen = palette === void 0 ? presetPalette(design.preset) : palette;
2063
2063
  const values = /* @__PURE__ */ new Map();
2064
2064
  const apply = (block) => {
2065
- for (const [name, value] of Object.entries(block)) if (value !== void 0) values.set(name, /* @__PURE__ */ toCss(value));
2065
+ for (const [name, value] of Object.entries(block)) if (value !== void 0) values.set(name, /* @__PURE__ */ toCss$1(value));
2066
2066
  };
2067
2067
  apply(defaultThemeTokens);
2068
2068
  apply(scaleTokens);
@@ -2085,7 +2085,7 @@ var pxCss = (value) => `${round(value)}px`;
2085
2085
  function evaluate(kind, text, context) {
2086
2086
  switch (kind) {
2087
2087
  case "color": {
2088
- const color = parseColor(text);
2088
+ const color = parseColor$1(text);
2089
2089
  if (!color) return void 0;
2090
2090
  const css = formatColor(color);
2091
2091
  return {
@@ -3546,19 +3546,19 @@ var messages = {
3546
3546
  //#endregion
3547
3547
  //#region ../core/src/time.ts
3548
3548
  var TOKEN_PATTERN = /(HH|H|hh|h|mm|m|ss|s|a)/g;
3549
- var pad = (n) => String(n).padStart(2, "0");
3549
+ var pad$1 = (n) => String(n).padStart(2, "0");
3550
3550
  /** Format a time with tokens HH / H / hh / h / mm / m / ss / s / a */
3551
- var formatTime = (date, format) => {
3551
+ var formatTime$1 = (date, format) => {
3552
3552
  const hours24 = date.getHours();
3553
3553
  const hours12 = hours24 % 12 || 12;
3554
3554
  const values = {
3555
- HH: pad(hours24),
3555
+ HH: pad$1(hours24),
3556
3556
  H: String(hours24),
3557
- hh: pad(hours12),
3557
+ hh: pad$1(hours12),
3558
3558
  h: String(hours12),
3559
- mm: pad(date.getMinutes()),
3559
+ mm: pad$1(date.getMinutes()),
3560
3560
  m: String(date.getMinutes()),
3561
- ss: pad(date.getSeconds()),
3561
+ ss: pad$1(date.getSeconds()),
3562
3562
  s: String(date.getSeconds()),
3563
3563
  a: hours24 >= 12 ? "PM" : "AM"
3564
3564
  };
@@ -3630,7 +3630,7 @@ var parseTimeValue = (text) => {
3630
3630
  return date;
3631
3631
  };
3632
3632
  /** The value string of `date`: `HH:mm:ss`, or `HH:mm` without seconds. */
3633
- var toTimeValue = (date, withSeconds) => formatTime(date, withSeconds ? "HH:mm:ss" : "HH:mm");
3633
+ var toTimeValue = (date, withSeconds) => formatTime$1(date, withSeconds ? "HH:mm:ss" : "HH:mm");
3634
3634
  /** Seconds since midnight (compares times of day). */
3635
3635
  var secondsOfDay = (date) => date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
3636
3636
  /** Whether a display format contains a seconds token (`ss` / `s`) */
@@ -4026,11 +4026,11 @@ var base = {
4026
4026
  dir: "ltr",
4027
4027
  messages
4028
4028
  };
4029
- var text$6 = (value = "") => ({
4029
+ var text$7 = (value = "") => ({
4030
4030
  type: String,
4031
4031
  value
4032
4032
  });
4033
- var optional$6 = (value = null) => ({
4033
+ var optional$7 = (value = null) => ({
4034
4034
  type: null,
4035
4035
  value
4036
4036
  });
@@ -4240,19 +4240,19 @@ function enhanceConfiguration(c, consumers) {
4240
4240
  provider.template = `<view class="mn-provider {{themeClass}}" style="direction:{{effectiveDir}};{{themeStyle}}"><slot/></view>`;
4241
4241
  def.properties = {
4242
4242
  ...def.properties,
4243
- mode: text$6(),
4244
- theme: optional$6(""),
4245
- palette: optional$6(""),
4246
- design: optional$6({}),
4247
- locale: optional$6(),
4248
- dir: text$6(),
4249
- defaultTheme: text$6(kind === "theme" ? "system" : ""),
4250
- defaultPalette: optional$6(""),
4243
+ mode: text$7(),
4244
+ theme: optional$7(""),
4245
+ palette: optional$7(""),
4246
+ design: optional$7({}),
4247
+ locale: optional$7(),
4248
+ dir: text$7(),
4249
+ defaultTheme: text$7(kind === "theme" ? "system" : ""),
4250
+ defaultPalette: optional$7(""),
4251
4251
  disableStorage: {
4252
4252
  type: Boolean,
4253
4253
  value: kind !== "theme"
4254
4254
  },
4255
- storageKey: text$6("minerva-theme")
4255
+ storageKey: text$7("minerva-theme")
4256
4256
  };
4257
4257
  def.data = {
4258
4258
  themeClass: "mn-root",
@@ -4369,13 +4369,13 @@ function enhanceConfiguration(c, consumers) {
4369
4369
  const toggle = c.themeToggle;
4370
4370
  toggle.template = `<view class="mn-theme-toggle" role="group"><button wx:for="{{themeChoices}}" wx:key="value" class="mn-theme-choice mn-button mn-variant-outline {{item.value===activeTheme?'mn-active':''}} {{disabled?'mn-disabled':''}}" aria-pressed="{{item.value===activeTheme}}" disabled="{{disabled}}" data-value="{{item.value}}" bindtap="onChoose">{{item.label}}</button></view>`;
4371
4371
  Object.assign(toggle.definition.properties, {
4372
- value: optional$6(),
4372
+ value: optional$7(),
4373
4373
  showSystem: {
4374
4374
  type: Boolean,
4375
4375
  value: true
4376
4376
  },
4377
- labels: optional$6({}),
4378
- customThemes: optional$6([])
4377
+ labels: optional$7({}),
4378
+ customThemes: optional$7([])
4379
4379
  });
4380
4380
  toggle.definition.data = {
4381
4381
  ...toggle.definition.data,
@@ -4399,7 +4399,7 @@ function enhanceConfiguration(c, consumers) {
4399
4399
  const palette = c.paletteToggle;
4400
4400
  palette.definition.properties = {
4401
4401
  ...palette.definition.properties,
4402
- value: optional$6("")
4402
+ value: optional$7("")
4403
4403
  };
4404
4404
  palette.definition.data = {
4405
4405
  ...palette.definition.data,
@@ -4558,7 +4558,7 @@ function enhanceFeedback(c) {
4558
4558
  }
4559
4559
  //#endregion
4560
4560
  //#region src/basic-components.ts
4561
- var text$5 = (value = "") => ({
4561
+ var text$6 = (value = "") => ({
4562
4562
  type: String,
4563
4563
  value
4564
4564
  });
@@ -4566,11 +4566,11 @@ var number$3 = (value = 0) => ({
4566
4566
  type: Number,
4567
4567
  value
4568
4568
  });
4569
- var flag$7 = (value = false) => ({
4569
+ var flag$8 = (value = false) => ({
4570
4570
  type: Boolean,
4571
4571
  value
4572
4572
  });
4573
- var optional$5 = (value = null) => ({
4573
+ var optional$6 = (value = null) => ({
4574
4574
  type: null,
4575
4575
  value
4576
4576
  });
@@ -4785,11 +4785,11 @@ function textareaSync(self) {
4785
4785
  self.setData({ text: self.data.value === null ? self.data.localText : self.data.value });
4786
4786
  }
4787
4787
  function enhanceBasics(c) {
4788
- Object.assign(c.statCard.definition.properties, { icon: text$5() });
4788
+ Object.assign(c.statCard.definition.properties, { icon: text$6() });
4789
4789
  c.statCard.template = c.statCard.template.replace("<text class=\"mn-muted\">{{label}}</text>", "<view class=\"mn-stat-heading\"><text class=\"mn-muted\">{{label}}</text><view aria-hidden=\"true\"><slot name=\"icon\"/>{{icon}}</view></view>");
4790
4790
  Object.assign(c.loadingState.definition.properties, {
4791
- size: text$5("medium"),
4792
- label: text$5()
4791
+ size: text$6("medium"),
4792
+ label: text$6()
4793
4793
  });
4794
4794
  c.loadingState.template = c.loadingState.template.replace("class=\"mn-loading-state\"", "class=\"mn-loading-state mn-loading-{{size}}\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"").replace("{{label}}", "{{label || loadingLabel}}");
4795
4795
  c.loadingState.definition.observers = {
@@ -4801,15 +4801,15 @@ function enhanceBasics(c) {
4801
4801
  c.loadingState.definition.lifetimes = { attached() {
4802
4802
  this.setData({ loadingLabel: nativeTranslate(this, "loadingState.label") });
4803
4803
  } };
4804
- Object.assign(c.textLink.definition.properties, { variant: text$5("default") });
4804
+ Object.assign(c.textLink.definition.properties, { variant: text$6("default") });
4805
4805
  c.textLink.template = c.textLink.template.replaceAll("class=\"mn-text-link", "class=\"mn-text-link mn-text-link-{{variant}}").replaceAll("{{label}}</", "{{label}}<text wx:if=\"{{variant!=='default'}}\" class=\"mn-text-link-chevron\" aria-hidden=\"true\">›</text></");
4806
4806
  patch$2(c.input, `<view class="mn-input-wrapper mn-input-{{variant}} mn-control-{{size}} {{invalid?'mn-invalid':''}} {{disabled?'mn-disabled':''}}"><text wx:if="{{prefix}}">{{prefix}}</text><slot name="prefix"/><input class="mn-input {{disabled || readOnly?'mn-disabled':''}}" value="{{text}}" disabled="{{disabled || readOnly}}" placeholder="{{placeholder}}" name="{{name}}" type="{{type==='password'?'text':type}}" password="{{(password || type==='password') && !passwordVisible}}" maxlength="{{maxlength}}" focus="{{focused}}" aria-invalid="{{invalid}}" aria-required="{{required}}" bindinput="onInput" bindfocus="onFocus" bindblur="onBlur" bindconfirm="onConfirm"/><button wx:if="{{clearable && text && !disabled && !readOnly}}" class="mn-close mn-input-clear" aria-label="{{clearText}}" bindtap="onClear">×</button><button wx:if="{{password || type==='password'}}" class="mn-close mn-password-toggle {{disabled?'mn-disabled':''}}" disabled="{{disabled}}" aria-label="{{passwordVisible?hidePasswordText:showPasswordText}}" bindtap="onPassword">{{passwordVisible?hidePasswordText:showPasswordText}}</button><text wx:if="{{showCharCount}}" class="mn-muted">{{text.length}}{{maxlength>0?' / '+maxlength:''}}</text><text wx:if="{{suffix}}">{{suffix}}</text><slot name="suffix"/></view>`, {
4807
- value: optional$5(),
4808
- defaultValue: text$5(),
4807
+ value: optional$6(),
4808
+ defaultValue: text$6(),
4809
4809
  maxlength: number$3(-1),
4810
- clearLabel: text$5(),
4811
- showPasswordLabel: text$5(),
4812
- hidePasswordLabel: text$5()
4810
+ clearLabel: text$6(),
4811
+ showPasswordLabel: text$6(),
4812
+ hidePasswordLabel: text$6()
4813
4813
  }, {
4814
4814
  onInput(e) {
4815
4815
  if (blocked$4(this)) return this.data.text;
@@ -4859,14 +4859,14 @@ function enhanceBasics(c) {
4859
4859
  } }
4860
4860
  });
4861
4861
  patch$2(c.divider, `<view class="mn-native-divider {{isVertical?'mn-native-divider-vertical':''}} {{elevation?'mn-divider-elevated':''}} mn-divider-align-{{textAlign}} mn-divider" role="separator" aria-orientation="{{isVertical?'vertical':'horizontal'}}" style="{{dividerStyle}}"><view class="mn-divider-line" style="{{lineStyle}}"/><text wx:if="{{!isVertical && label}}" class="mn-divider-label">{{label}}</text><view wx:if="{{!isVertical && label}}" class="mn-divider-line" style="{{lineStyle}}"/></view>`, {
4862
- orientation: text$5("horizontal"),
4863
- variant: text$5("solid"),
4862
+ orientation: text$6("horizontal"),
4863
+ variant: text$6("solid"),
4864
4864
  thickness: number$3(1),
4865
- length: optional$5(),
4865
+ length: optional$6(),
4866
4866
  spacing: number$3(16),
4867
- textAlign: text$5("center"),
4868
- elevation: flag$7(),
4869
- flexItem: flag$7()
4867
+ textAlign: text$6("center"),
4868
+ elevation: flag$8(),
4869
+ flexItem: flag$8()
4870
4870
  }, {}, {
4871
4871
  data: {
4872
4872
  dividerStyle: "",
@@ -4881,13 +4881,13 @@ function enhanceBasics(c) {
4881
4881
  } }
4882
4882
  });
4883
4883
  patch$2(c.empty, `<view class="mn-empty {{size?'mn-empty-'+size:''}} {{showShadow?'mn-empty-shadow':''}}" style="{{emptyStyle}}" role="status" aria-label="{{title}}"><view wx:if="{{icon!==null && icon!==false}}" class="mn-empty-icon"><slot name="icon"/><view wx:if="{{useSvg && !icon}}" class="mn-empty-illustration"><view class="mn-empty-ellipse"/><view class="mn-empty-box"/><view class="mn-empty-box-lip"/></view><text>{{icon || (useSvg?'':'□')}}</text></view><text wx:if="{{title}}" class="mn-title">{{title}}</text><text wx:if="{{descriptionText!==null}}" class="mn-muted">{{descriptionText}}</text><view class="mn-empty-actions"><slot name="action"/><slot name="secondaryAction"/></view><slot/></view>`, {
4884
- size: text$5(),
4885
- width: optional$5(),
4886
- height: optional$5(),
4887
- showShadow: flag$7(),
4888
- icon: optional$5(""),
4889
- description: optional$5(""),
4890
- useSvg: flag$7()
4884
+ size: text$6(),
4885
+ width: optional$6(),
4886
+ height: optional$6(),
4887
+ showShadow: flag$8(),
4888
+ icon: optional$6(""),
4889
+ description: optional$6(""),
4890
+ useSvg: flag$8()
4891
4891
  }, {}, {
4892
4892
  data: {
4893
4893
  emptyStyle: "",
@@ -4901,14 +4901,14 @@ function enhanceBasics(c) {
4901
4901
  } }
4902
4902
  });
4903
4903
  patch$2(c.iconButton, `<view class="mn-icon-button-root"><button class="mn-button mn-icon-button mn-size-{{size}} mn-color-{{color}} mn-variant-{{variant}} mn-icon-shape-{{shape}} {{disabled || loading?'mn-disabled':''}} {{effectivePressed?'mn-active':''}}" aria-label="{{label}}" aria-pressed="{{isToggle?effectivePressed:undefined}}" aria-busy="{{loading}}" disabled="{{disabled || loading}}" bindtap="onTap" bindlongpress="onTooltip"><view wx:if="{{loading}}" class="mn-spinner"/><block wx:else><slot/>{{icon}}</block></button><view wx:if="{{tooltipVisible && tooltipEnabled}}" class="mn-tooltip mn-popup mn-color-{{tooltip.color || 'neutral'}} mn-variant-{{tooltip.variant || 'solid'}} mn-tooltip-{{tooltip.shape || 'default'}}" bindtap="onTooltipClose">{{tooltipText}}</view></view>`, {
4904
- size: text$5("medium"),
4905
- color: text$5("neutral"),
4906
- shape: text$5("circle"),
4907
- pressed: optional$5(),
4908
- defaultPressed: optional$5(),
4909
- toggle: flag$7(),
4910
- tooltip: optional$5({}),
4911
- showTooltip: optional$5()
4904
+ size: text$6("medium"),
4905
+ color: text$6("neutral"),
4906
+ shape: text$6("circle"),
4907
+ pressed: optional$6(),
4908
+ defaultPressed: optional$6(),
4909
+ toggle: flag$8(),
4910
+ tooltip: optional$6({}),
4911
+ showTooltip: optional$6()
4912
4912
  }, {
4913
4913
  onTap() {
4914
4914
  if (this.data.disabled || this.data.loading) return;
@@ -4942,18 +4942,18 @@ function enhanceBasics(c) {
4942
4942
  } }
4943
4943
  });
4944
4944
  patch$2(c.jsonField, `<view class="mn-json-field"><textarea class="mn-input mn-code mn-textarea mn-textarea-{{size}} mn-input-{{variant}} {{invalid || !jsonValid?'mn-invalid':''}} {{disabled || readOnly?'mn-disabled':''}}" value="{{text}}" disabled="{{disabled || readOnly}}" placeholder="{{placeholder}}" style="min-height:{{rows*24}}px" maxlength="{{maxlength}}" aria-invalid="{{invalid || !jsonValid}}" bindinput="onInput"/><view wx:if="{{!hideToolbar}}" class="mn-json-toolbar"><button class="mn-close mn-json-format" aria-label="{{formatText}}" disabled="{{disabled || readOnly || !jsonValid}}" bindtap="onFormat">{{formatText}}</button></view><text wx:if="{{text}}" class="{{jsonValid?'mn-muted':'mn-error'}}" role="status">{{jsonValid?validText:error}}</text></view>`, {
4945
- value: optional$5(),
4946
- defaultValue: text$5(),
4945
+ value: optional$6(),
4946
+ defaultValue: text$6(),
4947
4947
  indent: number$3(2),
4948
- hideToolbar: flag$7(),
4949
- formatLabel: text$5(),
4950
- validLabel: text$5(),
4951
- invalidLabel: text$5(),
4948
+ hideToolbar: flag$8(),
4949
+ formatLabel: text$6(),
4950
+ validLabel: text$6(),
4951
+ invalidLabel: text$6(),
4952
4952
  rows: number$3(8),
4953
- size: text$5("medium"),
4954
- variant: text$5("outline"),
4955
- invalid: flag$7(),
4956
- placeholder: text$5(),
4953
+ size: text$6("medium"),
4954
+ variant: text$6("outline"),
4955
+ invalid: flag$8(),
4956
+ placeholder: text$6(),
4957
4957
  maxlength: number$3(-1)
4958
4958
  }, {
4959
4959
  onInput(e) {
@@ -4980,27 +4980,27 @@ function enhanceBasics(c) {
4980
4980
  } }
4981
4981
  });
4982
4982
  Object.assign(c.radio.definition.properties, {
4983
- name: text$5(),
4984
- size: text$5("medium"),
4985
- color: text$5("primary"),
4986
- error: flag$7(),
4987
- required: flag$7(),
4988
- errorMessage: text$5(),
4989
- helperText: text$5(),
4990
- errorIcon: text$5("!"),
4991
- ariaLabel: text$5()
4983
+ name: text$6(),
4984
+ size: text$6("medium"),
4985
+ color: text$6("primary"),
4986
+ error: flag$8(),
4987
+ required: flag$8(),
4988
+ errorMessage: text$6(),
4989
+ helperText: text$6(),
4990
+ errorIcon: text$6("!"),
4991
+ ariaLabel: text$6()
4992
4992
  });
4993
4993
  c.radio.template = `<view role="radio" aria-label="{{ariaLabel || label}}" aria-checked="{{effectiveChecked}}" aria-disabled="{{disabled}}" aria-invalid="{{error}}" aria-required="{{required}}" class="mn-choice mn-choice-size-{{size}} mn-choice-color-{{color}} {{disabled || readOnly?'mn-disabled':''}} {{error?'mn-invalid':''}}" bindtap="onChoose"><text class="mn-choice-indicator mn-radio {{effectiveChecked?'mn-active':''}}">{{effectiveChecked?'●':''}}</text><view class="mn-choice-content"><text>{{label}}</text><slot/></view><text wx:if="{{error && errorMessage || helperText}}" class="mn-choice-helper {{error?'mn-error':''}}"><block wx:if="{{error}}"><slot name="errorIcon"/>{{errorIcon}}</block>{{error && errorMessage?errorMessage:helperText}}</text></view>`;
4994
4994
  patch$2(c.radioGroup, `<view class="mn-radio-group mn-{{direction}} {{error?'mn-invalid':''}}" role="radiogroup" aria-label="{{ariaLabel || label}}" aria-required="{{required}}" aria-invalid="{{error}}"><text wx:if="{{label}}">{{label}}</text><view wx:for="{{options}}" wx:key="value" class="mn-choice mn-choice-size-{{size || item.size || 'medium'}} mn-choice-color-{{color || item.color || 'primary'}} {{disabled || readOnly || item.disabled?'mn-disabled':''}}" role="radio" aria-checked="{{effectiveValue===item.value}}" aria-disabled="{{disabled || item.disabled}}" data-index="{{index}}" bindtap="onSelect"><text class="mn-choice-indicator mn-radio {{effectiveValue===item.value?'mn-active':''}}">{{effectiveValue===item.value?'●':''}}</text><text>{{item.label}}</text></view><slot/><text wx:if="{{helperText}}" class="mn-choice-helper {{error?'mn-error':''}}">{{helperText}}</text></view>`, {
4995
- value: optional$5(groupUnset),
4996
- defaultValue: optional$5(),
4997
- label: text$5(),
4998
- ariaLabel: text$5(),
4999
- size: text$5(),
5000
- color: text$5(),
5001
- required: flag$7(),
5002
- error: flag$7(),
5003
- helperText: text$5()
4995
+ value: optional$6(groupUnset),
4996
+ defaultValue: optional$6(),
4997
+ label: text$6(),
4998
+ ariaLabel: text$6(),
4999
+ size: text$6(),
5000
+ color: text$6(),
5001
+ required: flag$8(),
5002
+ error: flag$8(),
5003
+ helperText: text$6()
5004
5004
  }, { onSelect(e) {
5005
5005
  const o = this.data.options[Number(e.currentTarget.dataset.index)];
5006
5006
  if (blocked$4(this) || !o || o.disabled || o.value === this.data.effectiveValue) return;
@@ -5021,18 +5021,18 @@ function enhanceBasics(c) {
5021
5021
  } }
5022
5022
  });
5023
5023
  patch$2(c.select, `<view class="mn-select"><button class="mn-input mn-select-trigger mn-control-{{size}} {{invalid?'mn-invalid':''}} {{disabled || readOnly?'mn-disabled':''}}" role="combobox" aria-expanded="{{expanded}}" aria-invalid="{{invalid}}" aria-required="{{required}}" aria-label="{{ariaLabel}}" disabled="{{disabled || readOnly}}" bindtap="onToggle">{{selectedLabel || placeholder}} ▾</button><view wx:if="{{expanded}}" class="mn-popup {{contentClassName}}" role="listbox"><input wx:if="{{searchable}}" class="mn-input" value="{{query}}" placeholder="{{searchLabel}}" bindinput="onQuery"/><block wx:for="{{filtered}}" wx:key="key"><view wx:if="{{item.type==='label'}}" class="mn-select-group">{{item.label}}</view><view wx:elif="{{item.type==='separator'}}" class="mn-divider" role="separator"/><button wx:else role="option" aria-selected="{{effectiveValue===item.value}}" class="mn-option {{effectiveValue===item.value?'mn-active':''}} {{item.disabled?'mn-disabled':''}}" disabled="{{item.disabled}}" data-index="{{index}}" bindtap="onChoose"><text>{{item.icon}}</text>{{item.label}}<text class="mn-muted">{{item.description}}</text></button></block><text wx:if="{{!filtered.length}}" class="mn-muted">{{emptyLabel}}</text><slot name="content"/></view><slot/></view>`, {
5024
- value: optional$5(),
5025
- defaultValue: text$5(),
5026
- open: optional$5(),
5027
- defaultOpen: flag$7(),
5028
- size: text$5("medium"),
5029
- invalid: flag$7(),
5030
- required: flag$7(),
5031
- name: text$5(),
5032
- ariaLabel: text$5(),
5033
- contentClassName: text$5(),
5034
- searchPlaceholder: text$5(),
5035
- emptyText: text$5()
5024
+ value: optional$6(),
5025
+ defaultValue: text$6(),
5026
+ open: optional$6(),
5027
+ defaultOpen: flag$8(),
5028
+ size: text$6("medium"),
5029
+ invalid: flag$8(),
5030
+ required: flag$8(),
5031
+ name: text$6(),
5032
+ ariaLabel: text$6(),
5033
+ contentClassName: text$6(),
5034
+ searchPlaceholder: text$6(),
5035
+ emptyText: text$6()
5036
5036
  }, {
5037
5037
  onToggle() {
5038
5038
  selectOpen(this, !this.data.expanded);
@@ -5071,13 +5071,13 @@ function enhanceBasics(c) {
5071
5071
  } }
5072
5072
  });
5073
5073
  patch$2(c.tabs, `<view class="mn-tabs mn-tabs-{{orientation}} mn-tabs-{{variant}} mn-color-{{color}}" style="direction:{{dir}}"><view class="mn-tabs-list" role="tablist" aria-orientation="{{orientation}}"><view wx:for="{{items}}" wx:key="value" class="mn-tab mn-color-{{item.color || color}} {{item.value===effectiveValue?'mn-active':''}}"><button class="mn-option {{disabled || item.disabled?'mn-disabled':''}}" role="tab" aria-selected="{{item.value===effectiveValue}}" disabled="{{disabled || item.disabled}}" data-index="{{index}}" bindtap="onChoose">{{item.label}}</button></view></view><block wx:for="{{items}}" wx:key="value"><view wx:if="{{item.forceMount || item.value===effectiveValue}}" hidden="{{item.value!==effectiveValue}}" class="mn-tab-panel" role="tabpanel">{{item.content}}<slot name="{{item.value}}"/></view></block><slot/></view>`, {
5074
- value: optional$5(),
5075
- defaultValue: text$5(),
5076
- orientation: text$5("horizontal"),
5077
- variant: text$5("line"),
5078
- color: text$5("primary"),
5079
- dir: text$5("ltr"),
5080
- activationMode: text$5("automatic")
5074
+ value: optional$6(),
5075
+ defaultValue: text$6(),
5076
+ orientation: text$6("horizontal"),
5077
+ variant: text$6("line"),
5078
+ color: text$6("primary"),
5079
+ dir: text$6("ltr"),
5080
+ activationMode: text$6("automatic")
5081
5081
  }, { onChoose(e) {
5082
5082
  const item = this.data.items[Number(e.currentTarget.dataset.index)];
5083
5083
  if (blocked$4(this) || !item || item.disabled || item.value === this.data.effectiveValue) return;
@@ -5098,22 +5098,22 @@ function enhanceBasics(c) {
5098
5098
  } }
5099
5099
  });
5100
5100
  patch$2(c.skeleton, `<view wx:if="{{loading}}" class="mn-skeleton-root {{effectiveVariant==='card'?'mn-skeleton-card-root':''}} {{active?'mn-skeleton-active':''}}" role="{{decorative?'none':'status'}}" aria-hidden="{{decorative}}" aria-busy="{{!decorative}}" aria-label="{{loadingLabel}}"><view wx:if="{{avatar && !decorative}}" class="mn-skeleton mn-skeleton-{{avatarShape}} mn-skeleton-{{animation}}" style="{{avatarStyle}}"/><view class="mn-skeleton-lines"><view wx:if="{{title && !decorative}}" class="mn-skeleton mn-skeleton-title mn-skeleton-{{animation}}"/><view wx:if="{{paragraph && !decorative}}" wx:for="{{paragraphLines}}" wx:key="*this" class="mn-skeleton mn-skeleton-paragraph mn-skeleton-{{animation}}" style="width:{{item}}"/><view wx:for="{{lineItems}}" wx:key="*this" class="mn-skeleton mn-skeleton-line mn-skeleton-{{effectiveVariant}} mn-skeleton-{{animation}}" style="{{lineStyle}}"/></view></view><block wx:else><slot/></block>`, {
5101
- variant: text$5("text"),
5102
- animation: text$5("pulse"),
5103
- decorative: flag$7(),
5104
- size: optional$5(),
5105
- width: optional$5(),
5106
- height: optional$5(),
5107
- loading: flag$7(true),
5108
- borderRadius: optional$5(),
5101
+ variant: text$6("text"),
5102
+ animation: text$6("pulse"),
5103
+ decorative: flag$8(),
5104
+ size: optional$6(),
5105
+ width: optional$6(),
5106
+ height: optional$6(),
5107
+ loading: flag$8(true),
5108
+ borderRadius: optional$6(),
5109
5109
  lines: number$3(1),
5110
- avatar: flag$7(),
5111
- avatarSize: optional$5(40),
5112
- avatarShape: text$5("circle"),
5113
- active: flag$7(),
5114
- paragraph: flag$7(),
5115
- title: flag$7(),
5116
- ariaLabel: text$5()
5110
+ avatar: flag$8(),
5111
+ avatarSize: optional$6(40),
5112
+ avatarShape: text$6("circle"),
5113
+ active: flag$8(),
5114
+ paragraph: flag$8(),
5115
+ title: flag$8(),
5116
+ ariaLabel: text$6()
5117
5117
  }, {}, {
5118
5118
  data: {
5119
5119
  lineItems: [],
@@ -5129,11 +5129,11 @@ function enhanceBasics(c) {
5129
5129
  } }
5130
5130
  });
5131
5131
  patch$2(c.skeletonText, `<view class="mn-skeleton-text" style="{{textStyle}}" aria-hidden="true"><view wx:for="{{lineItems}}" wx:key="*this" class="mn-skeleton mn-skeleton-{{animation}}" style="{{lineStyle}};width:{{shrinkLast && index===lineItems.length-1?lastLineWidth:'100%'}}"/></view>`, {
5132
- lineHeight: optional$5("1em"),
5133
- gap: optional$5(2),
5134
- shrinkLast: flag$7(true),
5135
- lastLineWidth: text$5("70%"),
5136
- animation: text$5("pulse")
5132
+ lineHeight: optional$6("1em"),
5133
+ gap: optional$6(2),
5134
+ shrinkLast: flag$8(true),
5135
+ lastLineWidth: text$6("70%"),
5136
+ animation: text$6("pulse")
5137
5137
  }, {}, {
5138
5138
  data: {
5139
5139
  lineItems: [
@@ -5160,20 +5160,20 @@ function enhanceBasics(c) {
5160
5160
  } }
5161
5161
  });
5162
5162
  patch$2(c.tooltip, `<view class="mn-popover"><view class="mn-popover-trigger" bindtap="onToggle" bindlongpress="onEnter" bindtouchend="onLeave"><slot/></view><view wx:if="{{visible}}" class="mn-popup mn-tooltip mn-placement-{{placement}} mn-color-{{color}} mn-variant-{{variant}} mn-tooltip-{{shape}} mn-tooltip-animation-{{animation}} {{contentClassName}}" style="{{tooltipStyle}}" role="tooltip" aria-label="{{ariaLabel}}"><view wx:if="{{arrow}}" class="mn-tooltip-arrow"/><text>{{content}}</text><button class="mn-close" bindtap="close">×</button><slot name="content"/></view></view>`, {
5163
- open: optional$5(),
5164
- defaultOpen: flag$7(),
5165
- placement: text$5("top"),
5166
- color: text$5("neutral"),
5167
- variant: text$5("solid"),
5168
- shape: text$5("default"),
5169
- animation: text$5("fade"),
5163
+ open: optional$6(),
5164
+ defaultOpen: flag$8(),
5165
+ placement: text$6("top"),
5166
+ color: text$6("neutral"),
5167
+ variant: text$6("solid"),
5168
+ shape: text$6("default"),
5169
+ animation: text$6("fade"),
5170
5170
  enterDelay: number$3(200),
5171
5171
  leaveDelay: number$3(),
5172
- offset: optional$5([0, 0]),
5172
+ offset: optional$6([0, 0]),
5173
5173
  zIndex: number$3(1500),
5174
- arrow: flag$7(),
5175
- contentClassName: text$5(),
5176
- ariaLabel: text$5()
5174
+ arrow: flag$8(),
5175
+ contentClassName: text$6(),
5176
+ ariaLabel: text$6()
5177
5177
  }, {
5178
5178
  open() {
5179
5179
  tooltipRequest(this, true);
@@ -5214,10 +5214,10 @@ function enhanceBasics(c) {
5214
5214
  }
5215
5215
  });
5216
5216
  patch$2(c.codeBlock, `<view class="mn-code-block"><view class="mn-row"><text class="mn-muted">{{language}}</text><button wx:if="{{copyable}}" class="mn-close" bindtap="onCopy">{{copyLabel}}</button></view><scroll-view scroll-x="{{!wrap}}" scroll-y style="{{codeStyle}}" role="region" aria-label="{{codeRegionLabel}}"><text class="mn-code" selectable style="white-space:{{wrap?'pre-wrap':'pre'}};word-break:{{wrap?'break-word':'normal'}}">{{code}}</text></scroll-view><text class="mn-visually-hidden" aria-live="polite">{{copyStatus}}</text></view>`, {
5217
- wrap: flag$7(true),
5218
- maxHeight: optional$5("24rem"),
5219
- ariaLabel: text$5(),
5220
- copyable: flag$7()
5217
+ wrap: flag$8(true),
5218
+ maxHeight: optional$6("24rem"),
5219
+ ariaLabel: text$6(),
5220
+ copyable: flag$8()
5221
5221
  }, { onCopy() {
5222
5222
  const sourceText = this.data.code;
5223
5223
  wx.setClipboardData({
@@ -5268,23 +5268,23 @@ function enhanceBasics(c) {
5268
5268
  }
5269
5269
  });
5270
5270
  patch$2(c.list, `<view class="mn-list mn-list-{{density}} {{bordered?'mn-list-bordered':''}} {{dividers && divided?'mn-list-divided':''}}" role="{{role}}"><view wx:for="{{items}}" wx:key="index" class="mn-list-item {{item.disabled?'mn-disabled':''}}" role="listitem" data-index="{{index}}" bindtap="onItem"><text wx:if="{{item.icon}}" aria-hidden="true">{{item.icon}}</text><view class="mn-list-content"><text>{{item.primary===undefined?item.title:item.primary}}</text><text class="mn-muted">{{item.secondary===undefined?item.description:item.secondary}}</text></view><view class="mn-list-actions">{{item.actions}}<slot name="{{'actions-'+index}}"/></view></view><slot/></view>`, {
5271
- density: text$5("default"),
5272
- bordered: flag$7(),
5273
- dividers: flag$7(true),
5274
- role: text$5("list")
5271
+ density: text$6("default"),
5272
+ bordered: flag$8(),
5273
+ dividers: flag$8(true),
5274
+ role: text$6("list")
5275
5275
  });
5276
5276
  patch$2(c.descriptionList, `<view class="mn-description-list {{bordered?'mn-list-bordered':''}} {{striped?'mn-list-striped':''}}" style="grid-template-columns:repeat({{columns}},minmax(0,1fr))"><view wx:for="{{items}}" wx:key="key" class="mn-description-item {{striped && index%2===1?'mn-row-striped':''}}"><text class="mn-muted">{{item.label}}</text><text>{{item.value}}</text><slot name="{{item.key}}"/></view><slot/></view>`, {
5277
- bordered: flag$7(),
5278
- striped: flag$7()
5277
+ bordered: flag$8(),
5278
+ striped: flag$8()
5279
5279
  });
5280
5280
  patch$2(c.textarea, `<textarea class="mn-input mn-textarea mn-textarea-{{size}} mn-input-{{variant}} {{invalid?'mn-invalid':''}} {{disabled || readOnly?'mn-disabled':''}}" value="{{text}}" disabled="{{disabled || readOnly}}" name="{{name}}" placeholder="{{placeholder}}" maxlength="{{maxlength}}" auto-height="{{autoHeight}}" style="{{rows?'min-height:'+rows*24+'px':''}}" aria-invalid="{{invalid}}" aria-required="{{required}}" bindinput="onInput" bindfocus="onFocus" bindblur="onBlur"/>`, {
5281
- value: optional$5(),
5282
- defaultValue: text$5(),
5283
- size: text$5("medium"),
5284
- variant: text$5("outline"),
5285
- invalid: flag$7(),
5286
- required: flag$7(),
5287
- name: text$5(),
5281
+ value: optional$6(),
5282
+ defaultValue: text$6(),
5283
+ size: text$6("medium"),
5284
+ variant: text$6("outline"),
5285
+ invalid: flag$8(),
5286
+ required: flag$8(),
5287
+ name: text$6(),
5288
5288
  rows: number$3()
5289
5289
  }, {
5290
5290
  onInput(e) {
@@ -5316,21 +5316,21 @@ function enhanceBasics(c) {
5316
5316
  const switchChange = c.toggle.definition.methods.onChange;
5317
5317
  Object.assign(c.toggle.definition.options ?? (c.toggle.definition.options = {}), { multipleSlots: true });
5318
5318
  Object.assign(c.toggle.definition.properties, {
5319
- size: text$5("medium"),
5320
- color: text$5("primary"),
5321
- shape: text$5("round"),
5322
- variant: text$5("slider"),
5323
- label: text$5(),
5324
- offLabel: text$5(),
5325
- onLabel: text$5(),
5326
- labelPlacement: text$5("end"),
5327
- loading: flag$7(),
5328
- ripple: flag$7(true),
5329
- trackStyle: optional$5({}),
5330
- thumbStyle: optional$5({}),
5331
- icon: text$5(),
5332
- iconPlacement: text$5("start"),
5333
- value: text$5("on")
5319
+ size: text$6("medium"),
5320
+ color: text$6("primary"),
5321
+ shape: text$6("round"),
5322
+ variant: text$6("slider"),
5323
+ label: text$6(),
5324
+ offLabel: text$6(),
5325
+ onLabel: text$6(),
5326
+ labelPlacement: text$6("end"),
5327
+ loading: flag$8(),
5328
+ ripple: flag$8(true),
5329
+ trackStyle: optional$6({}),
5330
+ thumbStyle: optional$6({}),
5331
+ icon: text$6(),
5332
+ iconPlacement: text$6("start"),
5333
+ value: text$6("on")
5334
5334
  });
5335
5335
  Object.assign(c.toggle.definition.methods, {
5336
5336
  onChange(e) {
@@ -5363,7 +5363,7 @@ function enhanceBasics(c) {
5363
5363
  }
5364
5364
  //#endregion
5365
5365
  //#region src/advanced-components.ts
5366
- var text$4 = (value = "") => ({
5366
+ var text$5 = (value = "") => ({
5367
5367
  type: String,
5368
5368
  value
5369
5369
  });
@@ -5371,11 +5371,11 @@ var number$2 = (value = 0) => ({
5371
5371
  type: Number,
5372
5372
  value
5373
5373
  });
5374
- var flag$6 = (value = false) => ({
5374
+ var flag$7 = (value = false) => ({
5375
5375
  type: Boolean,
5376
5376
  value
5377
5377
  });
5378
- var optional$4 = (value = null) => ({
5378
+ var optional$5 = (value = null) => ({
5379
5379
  type: null,
5380
5380
  value
5381
5381
  });
@@ -5653,17 +5653,17 @@ function commandOpen(self, open) {
5653
5653
  }
5654
5654
  function enhanceAdvanced(c) {
5655
5655
  patch$1(c.drawer, `<view class="mn-drawer-root"><view class="mn-drawer-trigger" bindtap="onOpen"><slot name="trigger"/></view><view wx:if="{{visible || forceMount}}" hidden="{{!visible}}" class="mn-overlay {{modal?'':'mn-drawer-nonmodal'}}"><view class="mn-backdrop {{modal?'':'mn-backdrop-clear'}} {{overlayClassName}}" bindtap="onBackdrop"/><view class="mn-dialog mn-drawer mn-drawer-{{effectiveSide}} mn-drawer-{{size}}" role="{{role}}" aria-modal="{{modal}}" aria-label="{{title}}"><view class="mn-row"><slot name="header"/><text class="mn-title">{{title}}</text><button wx:if="{{!hideCloseButton}}" class="mn-close mn-drawer-close" aria-label="{{closeText}}" disabled="{{loading}}" bindtap="onClose">×</button></view><text class="{{description?'mn-muted':'mn-visually-hidden'}}">{{descriptionText}}</text><view class="mn-dialog-content"><slot/></view><slot name="footer"/></view></view></view>`, {
5656
- open: optional$4(),
5657
- defaultOpen: flag$6(),
5658
- side: text$4(),
5659
- size: text$4("medium"),
5660
- modal: flag$6(true),
5661
- forceMount: flag$6(),
5662
- hideCloseButton: flag$6(),
5663
- closeLabel: text$4(),
5664
- hiddenDescription: text$4(),
5665
- role: text$4("dialog"),
5666
- overlayClassName: text$4()
5656
+ open: optional$5(),
5657
+ defaultOpen: flag$7(),
5658
+ side: text$5(),
5659
+ size: text$5("medium"),
5660
+ modal: flag$7(true),
5661
+ forceMount: flag$7(),
5662
+ hideCloseButton: flag$7(),
5663
+ closeLabel: text$5(),
5664
+ hiddenDescription: text$5(),
5665
+ role: text$5("dialog"),
5666
+ overlayClassName: text$5()
5667
5667
  }, {
5668
5668
  configure(config) {
5669
5669
  drawers.set(this, config);
@@ -5705,15 +5705,15 @@ function enhanceAdvanced(c) {
5705
5705
  };
5706
5706
  c.modal.template = c.drawer.template.replaceAll("mn-drawer", "mn-modal").replace(" mn-modal-{{effectiveSide}}", "").replace("<text class=\"{{description?'mn-muted':'mn-visually-hidden'}}\">{{descriptionText}}</text>", "<text wx:if=\"{{description}}\" class=\"mn-muted\">{{description}}</text>");
5707
5707
  patch$1(c.virtualList, `<scroll-view scroll-y class="mn-virtual-list" scroll-top="{{scrollTop}}" style="max-height:{{effectiveHeight}}px;height:{{effectiveHeight}}px" role="list" aria-label="{{ariaLabel}}" aria-busy="{{loading || loadingMore}}" bindscroll="onScroll"><view style="height:{{before}}px"/><view wx:for="{{visible}}" wx:key="key" class="mn-list-item mn-virtual-item" role="listitem" style="{{rowHeight?'height:'+rowHeight+'px;':''}}padding:{{itemPadding}}px;box-sizing:border-box" data-index="{{item.index}}" bindtap="onItem"><view class="mn-virtual-content"><row-renderer wx:if="{{customRowRenderer}}" row="{{item.item}}" value="{{item.label}}" row-index="{{item.index}}"/><text wx:else>{{item.label}}</text></view></view><view style="height:{{after}}px"/><view wx:if="{{loading || loadingMore}}" class="mn-virtual-loading"><view class="mn-spinner"/>{{localeLabels.loading}}</view><slot name="footer"/></scroll-view>`, {
5708
- itemHeight: optional$4(),
5709
- maxHeight: optional$4(),
5708
+ itemHeight: optional$5(),
5709
+ maxHeight: optional$5(),
5710
5710
  itemPadding: number$2(8),
5711
5711
  overscan: number$2(5),
5712
5712
  loadMoreThreshold: number$2(100),
5713
- highPerformance: flag$6(),
5714
- loading: flag$6(),
5715
- ariaLabel: text$4(),
5716
- customRowRenderer: flag$6()
5713
+ highPerformance: flag$7(),
5714
+ loading: flag$7(),
5715
+ ariaLabel: text$5(),
5716
+ customRowRenderer: flag$7()
5717
5717
  }, {
5718
5718
  configure(config) {
5719
5719
  virtualConfigs.set(this, config);
@@ -5783,16 +5783,16 @@ function enhanceAdvanced(c) {
5783
5783
  });
5784
5784
  Object.assign(c.virtualList, { componentGenerics: { "row-renderer": { default: "../table-cell-content/index" } } });
5785
5785
  patch$1(c.upload, `<view class="mn-upload" role="group" aria-label="{{label}}" aria-busy="{{loading}}"><text>{{label}}</text><view wx:for="{{fileRows}}" wx:key="id" class="mn-upload-item"><image wx:if="{{item.previewUrl}}" class="mn-upload-preview" src="{{item.previewUrl}}" mode="aspectFit"/><text>{{item.name}}</text><text class="mn-muted">{{item.statusLabel}}</text><button wx:if="{{retryable && item.status==='error'}}" class="mn-close mn-upload-retry" disabled="{{disabled || loading}}" aria-label="{{item.retryLabel}}" data-index="{{index}}" bindtap="onRetry">↻</button><button wx:if="{{removable}}" class="mn-close mn-upload-remove" disabled="{{disabled}}" aria-label="{{item.removeLabel}}" data-index="{{index}}" bindtap="onRemove">×</button></view><button class="mn-button mn-variant-outline mn-upload-select" loading="{{loading}}" disabled="{{selectionBlocked}}" bindtap="onChoose">{{selectLabel}}</button><text wx:if="{{errorMessage}}" class="mn-error" role="alert">{{errorMessage}}</text><slot/></view>`, {
5786
- label: text$4(),
5787
- accept: text$4("*"),
5788
- multiple: flag$6(),
5789
- replace: flag$6(),
5790
- maxCount: optional$4(),
5791
- maxSize: optional$4(),
5792
- loading: flag$6(),
5793
- labels: optional$4({}),
5794
- removable: flag$6(true),
5795
- retryable: flag$6(true)
5786
+ label: text$5(),
5787
+ accept: text$5("*"),
5788
+ multiple: flag$7(),
5789
+ replace: flag$7(),
5790
+ maxCount: optional$5(),
5791
+ maxSize: optional$5(),
5792
+ loading: flag$7(),
5793
+ labels: optional$5({}),
5794
+ removable: flag$7(true),
5795
+ retryable: flag$7(true)
5796
5796
  }, {
5797
5797
  configure(config) {
5798
5798
  uploadConfigs.set(this, config);
@@ -5862,28 +5862,28 @@ function enhanceAdvanced(c) {
5862
5862
  }
5863
5863
  });
5864
5864
  patch$1(c.alert, `<view wx:if="{{!closed}}" class="mn-alert mn-color-{{effectiveColor}} mn-variant-{{variant}} mn-size-{{size}} {{banner?'mn-alert-banner':''}} {{elevation?'mn-alert-elevated':''}} {{rounded?'':'mn-alert-square'}} {{animation?'mn-alert-'+animationName:''}}" role="{{effectiveRole}}" style="{{radiusStyle}}"><view wx:if="{{showIcon}}" class="mn-alert-icon" aria-label="{{iconLabel}}"><slot name="icon"/><text wx:if="{{!customIcon}}">{{statusIcon}}</text></view><view class="mn-alert-main"><text class="mn-title">{{title}}</text><view wx:if="{{!collapsible || !title || effectiveExpanded}}" class="mn-alert-content"><text>{{description}}</text><slot/></view></view><slot name="action"/><button wx:if="{{collapsible && title}}" class="mn-close mn-alert-expand" aria-label="{{effectiveExpanded?collapseText:expandText}}" aria-expanded="{{effectiveExpanded}}" bindtap="onExpand">{{effectiveExpanded?'−':'+'}}</button><button wx:if="{{closable}}" class="mn-close mn-alert-close" aria-label="{{closeText}}" bindtap="onClose"><slot name="closeIcon"/><text wx:if="{{!customCloseIcon}}">{{closeIcon}}</text></button></view>`, {
5865
- color: text$4(),
5866
- variant: text$4("subtle"),
5867
- size: text$4("medium"),
5868
- showIcon: flag$6(true),
5869
- customIcon: flag$6(),
5870
- customCloseIcon: flag$6(),
5871
- icon: text$4(),
5872
- closeIcon: text$4("×"),
5873
- animation: flag$6(true),
5874
- animationName: text$4("slideIn"),
5875
- banner: flag$6(),
5876
- elevation: flag$6(),
5877
- rounded: flag$6(true),
5878
- borderRadius: optional$4(),
5879
- collapsible: flag$6(),
5880
- expanded: optional$4(),
5881
- defaultExpanded: flag$6(true),
5882
- closeLabel: text$4(),
5883
- expandLabel: text$4(),
5884
- collapseLabel: text$4(),
5885
- iconLabel: text$4(),
5886
- role: text$4()
5865
+ color: text$5(),
5866
+ variant: text$5("subtle"),
5867
+ size: text$5("medium"),
5868
+ showIcon: flag$7(true),
5869
+ customIcon: flag$7(),
5870
+ customCloseIcon: flag$7(),
5871
+ icon: text$5(),
5872
+ closeIcon: text$5("×"),
5873
+ animation: flag$7(true),
5874
+ animationName: text$5("slideIn"),
5875
+ banner: flag$7(),
5876
+ elevation: flag$7(),
5877
+ rounded: flag$7(true),
5878
+ borderRadius: optional$5(),
5879
+ collapsible: flag$7(),
5880
+ expanded: optional$5(),
5881
+ defaultExpanded: flag$7(true),
5882
+ closeLabel: text$5(),
5883
+ expandLabel: text$5(),
5884
+ collapseLabel: text$5(),
5885
+ iconLabel: text$5(),
5886
+ role: text$5()
5887
5887
  }, {
5888
5888
  onExpand() {
5889
5889
  const expanded = !this.data.effectiveExpanded;
@@ -5921,12 +5921,12 @@ function enhanceAdvanced(c) {
5921
5921
  "minH",
5922
5922
  "maxW",
5923
5923
  "maxH"
5924
- ].map((key) => [key, optional$4()])),
5925
- bg: text$4(),
5926
- rounded: text$4(),
5927
- boxShadow: text$4(),
5928
- border: text$4(),
5929
- customStyle: optional$4({})
5924
+ ].map((key) => [key, optional$5()])),
5925
+ bg: text$5(),
5926
+ rounded: text$5(),
5927
+ boxShadow: text$5(),
5928
+ border: text$5(),
5929
+ customStyle: optional$5({})
5930
5930
  }, {}, {
5931
5931
  data: { boxStyle: "" },
5932
5932
  observers: { "**": function() {
@@ -5937,15 +5937,15 @@ function enhanceAdvanced(c) {
5937
5937
  } }
5938
5938
  });
5939
5939
  patch$1(c.commandDialog, `<view class="mn-command-root"><view bindtap="onOpen"><slot name="trigger"/></view><view wx:if="{{visible}}" class="mn-overlay"><view class="mn-backdrop" bindtap="onClose"/><view class="mn-dialog" role="dialog" aria-label="{{commandLabels.title}}"><text class="mn-title">{{commandLabels.title}}</text><text>{{shortcutLabel}}</text><text class="mn-muted">{{commandLabels.description}}</text><input class="mn-input mn-command-input" value="{{query}}" placeholder="{{commandLabels.placeholder}}" bindinput="onQuery"/><view role="listbox" aria-label="{{commandLabels.results}}"><button wx:for="{{results}}" wx:key="id" class="mn-option" data-index="{{index}}" bindtap="onSelect"><text>{{item.title}}</text><text class="mn-muted">{{item.description}}</text><text>{{item.group}}</text></button></view><text wx:if="{{!results.length}}">{{commandLabels.empty}}</text><slot/></view></view></view>`, {
5940
- open: optional$4(),
5941
- defaultOpen: flag$6(),
5942
- title: text$4(),
5943
- description: text$4(),
5944
- placeholder: text$4(),
5945
- emptyText: text$4(),
5946
- shortcutLabel: text$4(),
5947
- resultsLabel: text$4(),
5948
- enterLabel: text$4()
5940
+ open: optional$5(),
5941
+ defaultOpen: flag$7(),
5942
+ title: text$5(),
5943
+ description: text$5(),
5944
+ placeholder: text$5(),
5945
+ emptyText: text$5(),
5946
+ shortcutLabel: text$5(),
5947
+ resultsLabel: text$5(),
5948
+ enterLabel: text$5()
5949
5949
  }, {
5950
5950
  configure(config) {
5951
5951
  commands.set(this, config);
@@ -6024,8 +6024,39 @@ var configurations = {
6024
6024
  dataTable: method("configure", "configure(config: NativeTableConfig): void", "Same callbacks as Table; pagination receives already paginated rows by default."),
6025
6025
  popover: method("configure", "configure(config: NativePopoverConfig): void", "Optional measure() supplies native anchor/panel/viewport rectangles; onInteractOutside() returning false prevents dismissal."),
6026
6026
  configProvider: method("configure", "configure(config: { messages?: Record<string, Messages> }): void", "Merge custom message trees per language into the inherited core translations and refresh descendants."),
6027
- themeProvider: method("configure", "configure(config: { messages?: Record<string, Messages> }): void", "Merge custom message trees per language into inherited translations.")
6027
+ themeProvider: method("configure", "configure(config: { messages?: Record<string, Messages> }): void", "Merge custom message trees per language into inherited translations."),
6028
+ quadrantChart: method("configure", "configure(config: NativeQuadrantChartConfig): void", "renderTooltip(point, index) returns the tooltip text of a point (lines separated by \\n) or null to hide it.")
6028
6029
  };
6030
+ var chartConfiguration = method("configure", "configure(config: NativeChartConfig): void", "Function options: xAxis.format / yAxis.format tick formatters and renderTooltip(event) returning the tooltip text (lines separated by \\n) or null to hide it.");
6031
+ for (const name of [
6032
+ "chart",
6033
+ "lineChart",
6034
+ "barChart",
6035
+ "scatterChart"
6036
+ ]) configurations[name] = chartConfiguration;
6037
+ var chartMethods = [
6038
+ method("resize", "resize(): void", "Measure the canvas again after a host layout change (e.g. a chart created hidden)."),
6039
+ method("resetZoom", "resetZoom(): void", "Show the whole data range."),
6040
+ method("getView", "getView(): NativeChartView | null", "Visible axis ranges; null before the canvas is ready."),
6041
+ method("setView", "setView(view: Partial<NativeChartView>): void", "Set the visible axis ranges."),
6042
+ method("getPlotRect", "getPlotRect(): NativeChartRect | null", "Plot area in px of the chart, for host overlays."),
6043
+ method("toPixel", "toPixel(x: number, y: number): { x: number; y: number } | null", "Data coordinates to px of the chart."),
6044
+ method("fromPixel", "fromPixel(x: number, y: number): { x: number; y: number } | null", "Px of the chart to data coordinates.")
6045
+ ];
6046
+ var chartEvent = {
6047
+ hover: event("hover", "{ items: NativeChartHoverItem[]; x: number | null; xLabel: string }", "Highlighted points after a tap or a finger scrub; items is empty when cleared."),
6048
+ zoom: event("zoom", "{ x: [number, number]; y: [number, number] }", "Visible range after a pinch, a pan or a double-tap reset."),
6049
+ layout: event("layout", "{ x: number; y: number; width: number; height: number }", "The plot area moved or was resized (px of the chart).")
6050
+ };
6051
+ var seriesChartEvents = [
6052
+ chartEvent.hover,
6053
+ event("pointclick", "{ items: NativeChartHoverItem[]; x: number; xLabel: string }", "A point or bar was tapped."),
6054
+ event("plotclick", "{ x: number; y: number }", "The plot area was tapped where there is no point (data coordinates)."),
6055
+ chartEvent.zoom,
6056
+ chartEvent.layout,
6057
+ event("pointdrag", "{ item: NativeChartHoverItem; x: number; y: number }", "A scatter point is dragged (interaction.dragPoints); the data is not changed."),
6058
+ event("pointdrop", "{ item: NativeChartHoverItem; x: number; y: number }", "A dragged scatter point was released; update the series to move it.")
6059
+ ];
6029
6060
  var tableEvents = [
6030
6061
  event("sortchange", "{ sortState: { key: string; order: 'ascend' | 'descend' | null } }", "Requested sort state."),
6031
6062
  event("selectionchange", "{ selectedRowKeys: Array<string | number>; selectedRows: Record<string, unknown>[] }", "Requested row selection, excluding disabled rows from select-all."),
@@ -6035,6 +6066,19 @@ var tableEvents = [
6035
6066
  event("cellaction", "{ row: Record<string, unknown>; key: string | number; index: number; columnKey: string; detail: unknown }", "Action emitted from a native rich cell or custom cell-renderer Component.")
6036
6067
  ];
6037
6068
  var events = {
6069
+ chart: seriesChartEvents,
6070
+ lineChart: seriesChartEvents,
6071
+ barChart: seriesChartEvents,
6072
+ scatterChart: seriesChartEvents,
6073
+ quadrantChart: [
6074
+ chartEvent.hover,
6075
+ event("pointclick", "{ point: NativeQuadrantPoint; index: number }", "A dot was tapped."),
6076
+ event("quadrantclick", "{ quadrant: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; x: number; y: number }", "The empty area of a quadrant was tapped."),
6077
+ event("pointdrag", "{ point: NativeQuadrantPoint; index: number; target: NativeQuadrantDropTarget }", "A dot is dragged (draggable)."),
6078
+ event("pointdrop", "{ point: NativeQuadrantPoint; index: number; target: NativeQuadrantDropTarget }", "A dragged dot was released; update points to move it."),
6079
+ chartEvent.zoom,
6080
+ chartEvent.layout
6081
+ ],
6038
6082
  drawer: [
6039
6083
  open,
6040
6084
  event("close", "{ reason: 'trigger' | 'close' | 'overlay' }", "Close reason."),
@@ -6133,6 +6177,13 @@ function annotateNativeApi(controls) {
6133
6177
  if (name === "tagInput") methods.push(method("paste", "paste(text: string, start?: number, end?: number): void", "Insert delimited clipboard text at the supplied draft selection; native input does not expose browser clipboard ranges."));
6134
6178
  if (name === "confirmProvider") methods.push(method("request", "request(options: NativeConfirmOptions): Promise<boolean>", "Queue a native confirmation and resolve on confirm/cancel or provider teardown."));
6135
6179
  if (configurations[name]) methods.push(configurations[name]);
6180
+ if ([
6181
+ "chart",
6182
+ "lineChart",
6183
+ "barChart",
6184
+ "scatterChart",
6185
+ "quadrantChart"
6186
+ ].includes(name)) methods.push(...chartMethods);
6136
6187
  if ([
6137
6188
  "responsiveGrid",
6138
6189
  "formLayout",
@@ -6155,6 +6206,3693 @@ function annotateNativeApi(controls) {
6155
6206
  }
6156
6207
  }
6157
6208
  //#endregion
6209
+ //#region ../charts/src/engine/color.ts
6210
+ var clamp01 = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
6211
+ var parseHex = (hex) => {
6212
+ const h = hex.slice(1);
6213
+ if (!/^[0-9a-f]+$/i.test(h)) return null;
6214
+ const expand = h.length === 3 || h.length === 4;
6215
+ if (!expand && h.length !== 6 && h.length !== 8) return null;
6216
+ const channel = (i) => expand ? parseInt(h[i] + h[i], 16) / 255 : parseInt(h.slice(i * 2, i * 2 + 2), 16) / 255;
6217
+ const hasAlpha = h.length === 4 || h.length === 8;
6218
+ return [
6219
+ channel(0),
6220
+ channel(1),
6221
+ channel(2),
6222
+ hasAlpha ? channel(3) : 1
6223
+ ];
6224
+ };
6225
+ var parseComponent = (part, scale) => {
6226
+ const v = parseFloat(part);
6227
+ if (Number.isNaN(v)) return 0;
6228
+ return part.trim().endsWith("%") ? v / 100 : v / scale;
6229
+ };
6230
+ /** Splits `a b c / d` or `a, b, c, d` */
6231
+ var splitArgs = (args) => {
6232
+ const [main, alpha] = args.split("/");
6233
+ const parts = main.split(/[\s,]+/).filter(Boolean);
6234
+ if (alpha !== void 0) parts.push(alpha.trim());
6235
+ return parts;
6236
+ };
6237
+ /**
6238
+ * Parses the color syntaxes returned by `getComputedStyle` (`rgb()`,
6239
+ * `rgba()`, `color(srgb ...)`) and hex colors; `null` for anything else
6240
+ * (named colors, `oklch()`, ... are resolved by `resolveColor`).
6241
+ */
6242
+ var parseColor = (input) => {
6243
+ const value = input.trim().toLowerCase();
6244
+ if (value.startsWith("#")) return parseHex(value);
6245
+ if (value === "transparent") return [
6246
+ 0,
6247
+ 0,
6248
+ 0,
6249
+ 0
6250
+ ];
6251
+ let match = /^rgba?\((.*)\)$/.exec(value);
6252
+ if (match) {
6253
+ const parts = splitArgs(match[1]);
6254
+ if (parts.length < 3) return null;
6255
+ return [
6256
+ clamp01(parseComponent(parts[0], 255)),
6257
+ clamp01(parseComponent(parts[1], 255)),
6258
+ clamp01(parseComponent(parts[2], 255)),
6259
+ parts[3] === void 0 ? 1 : clamp01(parseComponent(parts[3], 1))
6260
+ ];
6261
+ }
6262
+ match = /^color\(srgb\s+(.*)\)$/.exec(value);
6263
+ if (match) {
6264
+ const parts = splitArgs(match[1]);
6265
+ if (parts.length < 3) return null;
6266
+ return [
6267
+ clamp01(parseComponent(parts[0], 1)),
6268
+ clamp01(parseComponent(parts[1], 1)),
6269
+ clamp01(parseComponent(parts[2], 1)),
6270
+ parts[3] === void 0 ? 1 : clamp01(parseComponent(parts[3], 1))
6271
+ ];
6272
+ }
6273
+ return null;
6274
+ };
6275
+ /** Splits the arguments of `var(--name, fallback)` (the fallback may contain commas) */
6276
+ var parseVar = (value) => {
6277
+ const match = /^var\(\s*(--[\w-]+)\s*(?:,([\s\S]*))?\)$/.exec(value.trim());
6278
+ if (!match) return null;
6279
+ const fallback = match[2]?.trim();
6280
+ return {
6281
+ name: match[1],
6282
+ ...fallback ? { fallback } : {}
6283
+ };
6284
+ };
6285
+ /**
6286
+ * Resolves a color without a DOM (mini-programs, React Native, workers):
6287
+ * hex, `rgb()`, `transparent` and `var(--name, fallback)` looked up in
6288
+ * `variables` (nested fallbacks included).
6289
+ */
6290
+ var resolveStaticColor = (value, variables = {}, fallback = [
6291
+ .4,
6292
+ .4,
6293
+ .4,
6294
+ 1
6295
+ ], depth = 0) => {
6296
+ const direct = parseColor(value);
6297
+ if (direct) return direct;
6298
+ const ref = depth < 8 ? parseVar(value) : null;
6299
+ if (ref) {
6300
+ const defined = variables[ref.name];
6301
+ if (defined) return resolveStaticColor(defined, variables, fallback, depth + 1);
6302
+ if (ref.fallback) return resolveStaticColor(ref.fallback, variables, fallback, depth + 1);
6303
+ }
6304
+ return NAMED[value.trim().toLowerCase()] ?? fallback;
6305
+ };
6306
+ var NAMED = {
6307
+ black: [
6308
+ 0,
6309
+ 0,
6310
+ 0,
6311
+ 1
6312
+ ],
6313
+ white: [
6314
+ 1,
6315
+ 1,
6316
+ 1,
6317
+ 1
6318
+ ],
6319
+ red: [
6320
+ 1,
6321
+ 0,
6322
+ 0,
6323
+ 1
6324
+ ],
6325
+ green: [
6326
+ 0,
6327
+ 128 / 255,
6328
+ 0,
6329
+ 1
6330
+ ],
6331
+ blue: [
6332
+ 0,
6333
+ 0,
6334
+ 1,
6335
+ 1
6336
+ ],
6337
+ gray: [
6338
+ 128 / 255,
6339
+ 128 / 255,
6340
+ 128 / 255,
6341
+ 1
6342
+ ],
6343
+ grey: [
6344
+ 128 / 255,
6345
+ 128 / 255,
6346
+ 128 / 255,
6347
+ 1
6348
+ ],
6349
+ orange: [
6350
+ 1,
6351
+ 165 / 255,
6352
+ 0,
6353
+ 1
6354
+ ]
6355
+ };
6356
+ /** `rgba()` string usable by Canvas2D and the DOM */
6357
+ var toCss = (c, alpha = 1) => `rgba(${Math.round(c[0] * 255)}, ${Math.round(c[1] * 255)}, ${Math.round(c[2] * 255)}, ${+(c[3] * alpha).toFixed(3)})`;
6358
+ /** Packs a color as little-endian `unorm8x4` (r in the lowest byte) */
6359
+ var packColor = (c) => (Math.round(clamp01(c[3]) * 255) << 24 | Math.round(clamp01(c[2]) * 255) << 16 | Math.round(clamp01(c[1]) * 255) << 8 | Math.round(clamp01(c[0]) * 255)) >>> 0;
6360
+ /** Mixes two colors (t = 0 -> a, 1 -> b) */
6361
+ var mix = (a, b, t) => [
6362
+ a[0] + (b[0] - a[0]) * t,
6363
+ a[1] + (b[1] - a[1]) * t,
6364
+ a[2] + (b[2] - a[2]) * t,
6365
+ a[3] + (b[3] - a[3]) * t
6366
+ ];
6367
+ //#endregion
6368
+ //#region ../charts/src/engine/data.ts
6369
+ var isColumns = (data) => typeof data === "object" && data !== null && !("length" in data) && "y" in data;
6370
+ /** Converts an x value to a number for the axis type */
6371
+ var xResolver = (type, categoryIndex) => {
6372
+ return (value, index) => {
6373
+ if (typeof value === "number") return value;
6374
+ if (value instanceof Date) return value.getTime();
6375
+ if (typeof value === "string") {
6376
+ if (type === "category") return categoryIndex(value);
6377
+ if (type === "time") return Date.parse(value);
6378
+ const n = Number(value);
6379
+ return Number.isNaN(n) ? index : n;
6380
+ }
6381
+ return index;
6382
+ };
6383
+ };
6384
+ var toNumber = (v) => typeof v === "number" ? v : v === null || v === void 0 ? NaN : Number(v);
6385
+ /** Category names used by string x values, in order of appearance */
6386
+ var collectCategories = (datas) => {
6387
+ const seen = /* @__PURE__ */ new Set();
6388
+ const add = (v) => {
6389
+ if (typeof v === "string") seen.add(v);
6390
+ };
6391
+ for (const data of datas) {
6392
+ if (isColumns(data)) {
6393
+ const xs = data.x;
6394
+ if (xs && !ArrayBuffer.isView(xs)) for (let i = 0; i < xs.length; i++) add(xs[i]);
6395
+ continue;
6396
+ }
6397
+ const list = data;
6398
+ for (let i = 0; i < list.length; i++) {
6399
+ const item = list[i];
6400
+ if (Array.isArray(item)) add(item[0]);
6401
+ else if (item && typeof item === "object") add(item.x);
6402
+ }
6403
+ }
6404
+ return [...seen];
6405
+ };
6406
+ var finalize = (x, y, count, extra) => {
6407
+ let xMin = Infinity;
6408
+ let xMax = -Infinity;
6409
+ let yMin = Infinity;
6410
+ let yMax = -Infinity;
6411
+ let sorted = true;
6412
+ let prev = -Infinity;
6413
+ for (let i = 0; i < count; i++) {
6414
+ const xi = x[i];
6415
+ if (!Number.isFinite(xi)) {
6416
+ y[i] = NaN;
6417
+ continue;
6418
+ }
6419
+ if (xi < prev) sorted = false;
6420
+ prev = xi;
6421
+ const yi = y[i];
6422
+ if (!Number.isFinite(yi)) continue;
6423
+ if (xi < xMin) xMin = xi;
6424
+ if (xi > xMax) xMax = xi;
6425
+ if (yi < yMin) yMin = yi;
6426
+ if (yi > yMax) yMax = yi;
6427
+ }
6428
+ const empty = xMin > xMax;
6429
+ return {
6430
+ x,
6431
+ y,
6432
+ count,
6433
+ sorted,
6434
+ xMin: empty ? NaN : xMin,
6435
+ xMax: empty ? NaN : xMax,
6436
+ yMin: empty ? NaN : yMin,
6437
+ yMax: empty ? NaN : yMax,
6438
+ ...extra
6439
+ };
6440
+ };
6441
+ /** Turns any supported data form into columns */
6442
+ var normalizeData = (data, resolveX) => {
6443
+ const none = {
6444
+ size: null,
6445
+ colors: null,
6446
+ labels: null
6447
+ };
6448
+ if (isColumns(data)) {
6449
+ const count = data.y.length;
6450
+ const x = new Float64Array(count);
6451
+ const y = new Float64Array(count);
6452
+ const xs = data.x;
6453
+ for (let i = 0; i < count; i++) {
6454
+ y[i] = toNumber(data.y[i]);
6455
+ x[i] = xs ? resolveX(xs[i], i) : i;
6456
+ }
6457
+ let size = null;
6458
+ if (data.size) {
6459
+ size = new Float32Array(count);
6460
+ for (let i = 0; i < count; i++) size[i] = toNumber(data.size[i]);
6461
+ }
6462
+ return finalize(x, y, count, {
6463
+ ...none,
6464
+ size
6465
+ });
6466
+ }
6467
+ const list = data;
6468
+ const count = list.length;
6469
+ const x = new Float64Array(count);
6470
+ const y = new Float64Array(count);
6471
+ let size = null;
6472
+ let colors = null;
6473
+ let labels = null;
6474
+ for (let i = 0; i < count; i++) {
6475
+ const item = list[i];
6476
+ if (item === null || item === void 0 || typeof item === "number") {
6477
+ x[i] = i;
6478
+ y[i] = toNumber(item);
6479
+ } else if (Array.isArray(item)) {
6480
+ x[i] = resolveX(item[0], i);
6481
+ y[i] = toNumber(item[1]);
6482
+ } else if (typeof item === "object") {
6483
+ const d = item;
6484
+ x[i] = d.x === void 0 ? i : resolveX(d.x, i);
6485
+ y[i] = toNumber(d.y);
6486
+ if (d.size !== void 0) {
6487
+ size ??= new Float32Array(count).fill(NaN);
6488
+ size[i] = d.size;
6489
+ }
6490
+ if (d.color !== void 0) {
6491
+ colors ??= new Array(count);
6492
+ colors[i] = d.color;
6493
+ }
6494
+ if (d.label !== void 0) {
6495
+ labels ??= new Array(count);
6496
+ labels[i] = d.label;
6497
+ }
6498
+ } else {
6499
+ x[i] = i;
6500
+ y[i] = NaN;
6501
+ }
6502
+ }
6503
+ return finalize(x, y, count, {
6504
+ size,
6505
+ colors,
6506
+ labels
6507
+ });
6508
+ };
6509
+ /** First index whose x is >= value (sorted x) */
6510
+ var lowerBound = (x, count, value) => {
6511
+ let lo = 0;
6512
+ let hi = count;
6513
+ while (lo < hi) {
6514
+ const mid = lo + hi >>> 1;
6515
+ if (x[mid] < value) lo = mid + 1;
6516
+ else hi = mid;
6517
+ }
6518
+ return lo;
6519
+ };
6520
+ /** Index of the point with the closest x and a finite y (sorted x), -1 if none */
6521
+ var nearestIndex = (x, y, count, value) => {
6522
+ if (count === 0) return -1;
6523
+ const i = lowerBound(x, count, value);
6524
+ let left = i - 1;
6525
+ let right = i;
6526
+ while (left >= 0 && !Number.isFinite(y[left])) left--;
6527
+ while (right < count && !Number.isFinite(y[right])) right++;
6528
+ if (left < 0) return right < count ? right : -1;
6529
+ if (right >= count) return left;
6530
+ return value - x[left] <= x[right] - value ? left : right;
6531
+ };
6532
+ //#endregion
6533
+ //#region ../charts/src/engine/decimate.ts
6534
+ /**
6535
+ * Decimates the points `[start, end)` of a line with sorted x, given as
6536
+ * interleaved `x, y` values. `column` maps an x value to its pixel column.
6537
+ * Missing values (NaN or `gap`) are kept as a single NaN point so the
6538
+ * gaps survive.
6539
+ */
6540
+ var decimateMinMax = (points, start, end, column, gap = Infinity) => {
6541
+ const out = new Float64Array(Math.max(0, end - start) * 2);
6542
+ let length = 0;
6543
+ let col = NaN;
6544
+ let first = -1;
6545
+ let min = -1;
6546
+ let max = -1;
6547
+ let last = -1;
6548
+ const push = (i) => {
6549
+ out[length * 2] = points[i * 2];
6550
+ out[length * 2 + 1] = points[i * 2 + 1];
6551
+ length++;
6552
+ };
6553
+ const flush = () => {
6554
+ if (first < 0) return;
6555
+ push(first);
6556
+ const lo = Math.min(min, max);
6557
+ const hi = Math.max(min, max);
6558
+ if (lo !== first) push(lo);
6559
+ if (hi !== lo && hi !== first) push(hi);
6560
+ if (last !== hi && last !== lo && last !== first) push(last);
6561
+ first = -1;
6562
+ };
6563
+ const valid = (v) => Number.isFinite(v) && Math.abs(v) < gap;
6564
+ for (let i = start; i < end; i++) {
6565
+ const x = points[i * 2];
6566
+ const y = points[i * 2 + 1];
6567
+ if (!valid(x) || !valid(y)) {
6568
+ flush();
6569
+ col = NaN;
6570
+ if (length > 0 && !Number.isNaN(out[length * 2 - 1])) {
6571
+ out[length * 2] = x;
6572
+ out[length * 2 + 1] = NaN;
6573
+ length++;
6574
+ }
6575
+ continue;
6576
+ }
6577
+ const c = Math.floor(column(x));
6578
+ if (c !== col || first < 0) {
6579
+ flush();
6580
+ col = c;
6581
+ first = min = max = last = i;
6582
+ } else {
6583
+ if (y < points[min * 2 + 1]) min = i;
6584
+ if (y > points[max * 2 + 1]) max = i;
6585
+ last = i;
6586
+ }
6587
+ }
6588
+ flush();
6589
+ return {
6590
+ points: out,
6591
+ length
6592
+ };
6593
+ };
6594
+ //#endregion
6595
+ //#region ../charts/src/engine/layout.ts
6596
+ var createScales = (plot, view, reverseX, reverseY) => {
6597
+ const [x0, x1] = view.x;
6598
+ const [y0, y1] = view.y;
6599
+ const xs = plot.width / (x1 - x0 || 1);
6600
+ const ys = plot.height / (y1 - y0 || 1);
6601
+ const left = plot.x;
6602
+ const right = plot.x + plot.width;
6603
+ const top = plot.y;
6604
+ const bottom = plot.y + plot.height;
6605
+ return {
6606
+ plot,
6607
+ view,
6608
+ xToPx: reverseX ? (v) => right - (v - x0) * xs : (v) => left + (v - x0) * xs,
6609
+ yToPx: reverseY ? (v) => top + (v - y0) * ys : (v) => bottom - (v - y0) * ys,
6610
+ pxToX: reverseX ? (p) => x0 + (right - p) / xs : (p) => x0 + (p - left) / xs,
6611
+ pxToY: reverseY ? (p) => y0 + (p - top) / ys : (p) => y0 + (bottom - p) / ys,
6612
+ xPerPx: 1 / xs,
6613
+ yPerPx: 1 / ys
6614
+ };
6615
+ };
6616
+ /** Room for the axes, then the plot area */
6617
+ var computePlot = (input) => {
6618
+ const { width, height, padding, fontSize } = input;
6619
+ const line = Math.ceil(fontSize * 1.4);
6620
+ const left = padding.left + (input.yLabelWidth > 0 ? input.yLabelWidth + 8 : 0) + (input.yTitle ? line + 6 : 0);
6621
+ const bottom = padding.bottom + (input.xAxisVisible ? line + 8 : 0) + (input.xTitle ? line + 4 : 0);
6622
+ const top = padding.top;
6623
+ const right = padding.right;
6624
+ return {
6625
+ x: Math.round(left),
6626
+ y: Math.round(top),
6627
+ width: Math.max(10, Math.round(width - left - right)),
6628
+ height: Math.max(10, Math.round(height - top - bottom))
6629
+ };
6630
+ };
6631
+ //#endregion
6632
+ //#region ../charts/src/engine/scale.ts
6633
+ var E10 = Math.sqrt(50);
6634
+ var E5 = Math.sqrt(10);
6635
+ var E2 = Math.sqrt(2);
6636
+ /** Tick step close to `(max - min) / count`, of the form 1, 2 or 5 × 10^k */
6637
+ var tickStep = (min, max, count) => {
6638
+ const span = Math.abs(max - min);
6639
+ if (!(span > 0) || !Number.isFinite(span)) return 0;
6640
+ const raw = span / Math.max(1, count);
6641
+ const base = 10 ** Math.floor(Math.log10(raw));
6642
+ const error = raw / base;
6643
+ return (error >= E10 ? 10 : error >= E5 ? 5 : error >= E2 ? 2 : 1) * base;
6644
+ };
6645
+ /** Rounds a value computed from a step (avoids 0.30000000000000004) */
6646
+ var roundTo = (value, step) => {
6647
+ const decimals = Math.max(0, -Math.floor(Math.log10(step)) + 1);
6648
+ return decimals > 0 && decimals < 20 ? +value.toFixed(decimals) : value;
6649
+ };
6650
+ /** Tick values inside [min, max] */
6651
+ var linearTicks = (min, max, count) => {
6652
+ if (min > max) [min, max] = [max, min];
6653
+ const step = tickStep(min, max, count);
6654
+ if (!step) return Number.isFinite(min) ? [min] : [];
6655
+ const start = Math.ceil(min / step - 1e-9);
6656
+ const end = Math.floor(max / step + 1e-9);
6657
+ const ticks = [];
6658
+ for (let i = start; i <= end && ticks.length < 1e3; i++) ticks.push(roundTo(i * step, step));
6659
+ return ticks;
6660
+ };
6661
+ /** Extends [min, max] to tick boundaries */
6662
+ var niceDomain = (min, max, count) => {
6663
+ if (min > max) [min, max] = [max, min];
6664
+ let step = tickStep(min, max, count);
6665
+ for (let i = 0; i < 3 && step; i++) {
6666
+ const nextMin = Math.floor(min / step) * step;
6667
+ const nextMax = Math.ceil(max / step) * step;
6668
+ min = roundTo(nextMin, step);
6669
+ max = roundTo(nextMax, step);
6670
+ const next = tickStep(min, max, count);
6671
+ if (next === step) break;
6672
+ step = next;
6673
+ }
6674
+ return [min, max];
6675
+ };
6676
+ /**
6677
+ * Range covering [min, max] with a usable span: a single value (or no data)
6678
+ * becomes a small range around it.
6679
+ */
6680
+ var ensureSpan = (min, max, fallback = [0, 1]) => {
6681
+ if (!Number.isFinite(min) || !Number.isFinite(max)) return fallback;
6682
+ if (min > max) [min, max] = [max, min];
6683
+ if (max - min > 0) return [min, max];
6684
+ const pad = min === 0 ? 1 : Math.abs(min) * .1;
6685
+ return [min - pad, max + pad];
6686
+ };
6687
+ /** Number of decimals that keeps ticks distinct for a step */
6688
+ var stepDecimals = (step) => step > 0 && Number.isFinite(step) ? Math.min(12, Math.max(0, -Math.floor(Math.log10(step) + 1e-9))) : 0;
6689
+ //#endregion
6690
+ //#region ../charts/src/engine/spatial.ts
6691
+ var GridIndex = class {
6692
+ constructor(x, y, count, pointsPerCell = 4) {
6693
+ let xMin = Infinity;
6694
+ let xMax = -Infinity;
6695
+ let yMin = Infinity;
6696
+ let yMax = -Infinity;
6697
+ let valid = 0;
6698
+ for (let i = 0; i < count; i++) {
6699
+ const xi = x[i];
6700
+ const yi = y[i];
6701
+ if (!Number.isFinite(xi) || !Number.isFinite(yi)) continue;
6702
+ valid++;
6703
+ if (xi < xMin) xMin = xi;
6704
+ if (xi > xMax) xMax = xi;
6705
+ if (yi < yMin) yMin = yi;
6706
+ if (yi > yMax) yMax = yi;
6707
+ }
6708
+ const side = Math.min(1024, Math.max(1, Math.ceil(Math.sqrt(valid / pointsPerCell))));
6709
+ this.cols = side;
6710
+ this.rows = side;
6711
+ this.x0 = valid ? xMin : 0;
6712
+ this.y0 = valid ? yMin : 0;
6713
+ this.cellW = valid && xMax > xMin ? (xMax - xMin) / side : 1;
6714
+ this.cellH = valid && yMax > yMin ? (yMax - yMin) / side : 1;
6715
+ const cells = new Int32Array(count);
6716
+ const counts = new Uint32Array(side * side + 1);
6717
+ for (let i = 0; i < count; i++) {
6718
+ const xi = x[i];
6719
+ const yi = y[i];
6720
+ if (!Number.isFinite(xi) || !Number.isFinite(yi)) {
6721
+ cells[i] = -1;
6722
+ continue;
6723
+ }
6724
+ const cell = this.cellOf(xi, yi);
6725
+ cells[i] = cell;
6726
+ counts[cell + 1]++;
6727
+ }
6728
+ for (let c = 1; c < counts.length; c++) counts[c] += counts[c - 1];
6729
+ this.starts = counts.slice();
6730
+ const cursor = counts;
6731
+ this.order = new Uint32Array(valid);
6732
+ for (let i = 0; i < count; i++) {
6733
+ const cell = cells[i];
6734
+ if (cell >= 0) this.order[cursor[cell]++] = i;
6735
+ }
6736
+ }
6737
+ column(xi) {
6738
+ const c = Math.floor((xi - this.x0) / this.cellW);
6739
+ return c < 0 ? 0 : c >= this.cols ? this.cols - 1 : c;
6740
+ }
6741
+ row(yi) {
6742
+ const r = Math.floor((yi - this.y0) / this.cellH);
6743
+ return r < 0 ? 0 : r >= this.rows ? this.rows - 1 : r;
6744
+ }
6745
+ cellOf(xi, yi) {
6746
+ return this.row(yi) * this.cols + this.column(xi);
6747
+ }
6748
+ /** Calls `visit` with every point that may lie inside the box */
6749
+ query(xMin, xMax, yMin, yMax, visit) {
6750
+ if (this.order.length === 0) return;
6751
+ const c0 = this.column(Math.min(xMin, xMax));
6752
+ const c1 = this.column(Math.max(xMin, xMax));
6753
+ const r0 = this.row(Math.min(yMin, yMax));
6754
+ const r1 = this.row(Math.max(yMin, yMax));
6755
+ for (let r = r0; r <= r1; r++) for (let c = c0; c <= c1; c++) {
6756
+ const cell = r * this.cols + c;
6757
+ for (let k = this.starts[cell]; k < this.starts[cell + 1]; k++) visit(this.order[k]);
6758
+ }
6759
+ }
6760
+ };
6761
+ //#endregion
6762
+ //#region ../charts/src/engine/model.ts
6763
+ var firstX = (data) => {
6764
+ if (typeof data === "object" && data !== null && !("length" in data)) {
6765
+ const xs = data.x;
6766
+ return xs && xs.length ? xs[0] : void 0;
6767
+ }
6768
+ const list = data;
6769
+ for (let i = 0; i < Math.min(list.length, 8); i++) {
6770
+ const item = list[i];
6771
+ if (Array.isArray(item)) return item[0];
6772
+ if (item && typeof item === "object") return item.x;
6773
+ }
6774
+ };
6775
+ /** Axis type when not given: dates -> time, strings -> category */
6776
+ var detectXType = (datas) => {
6777
+ for (const data of datas) {
6778
+ const x = firstX(data);
6779
+ if (x instanceof Date) return "time";
6780
+ if (typeof x === "string") return "category";
6781
+ }
6782
+ return "linear";
6783
+ };
6784
+ var axisModel = (options, type, categories, gridDefault) => ({
6785
+ type,
6786
+ reverse: !!options?.reverse,
6787
+ categories,
6788
+ title: options?.title,
6789
+ format: options?.format,
6790
+ grid: options?.grid ?? gridDefault,
6791
+ visible: options?.visible ?? true,
6792
+ tickCount: options?.tickCount
6793
+ });
6794
+ var extent = (values) => {
6795
+ let min = Infinity;
6796
+ let max = -Infinity;
6797
+ for (let i = 0; i < values.length; i++) {
6798
+ const v = values[i];
6799
+ if (!Number.isFinite(v)) continue;
6800
+ if (v < min) min = v;
6801
+ if (v > max) max = v;
6802
+ }
6803
+ return [min, max];
6804
+ };
6805
+ /** Smallest positive gap between consecutive x values (bar width on numeric axes) */
6806
+ var smallestStep = (cols) => {
6807
+ let step = Infinity;
6808
+ for (const c of cols) {
6809
+ const xs = c.sorted ? c.x : Float64Array.from(c.x).sort();
6810
+ for (let i = 1; i < c.count; i++) {
6811
+ const d = xs[i] - xs[i - 1];
6812
+ if (d > 0 && d < step) step = d;
6813
+ }
6814
+ }
6815
+ return step;
6816
+ };
6817
+ var buildModel = (options, theme, hidden, cache, resolver = null) => {
6818
+ const resolve = resolver ?? theme.resolve ?? ((value, fallback) => resolveStaticColor(value, {}, fallback));
6819
+ const input = options.series;
6820
+ const datas = input.map((s) => s.data);
6821
+ const xType = options.xAxis?.type ?? detectXType(datas);
6822
+ const categories = xType === "category" ? [...options.xAxis?.categories ?? collectCategories(datas)] : [];
6823
+ const categoryMap = new Map(categories.map((c, i) => [c, i]));
6824
+ const resolveX = xResolver(xType, (name) => categoryMap.get(name) ?? NaN);
6825
+ const resolverKey = `${xType}|${categories.join("")}`;
6826
+ const usedKeys = /* @__PURE__ */ new Set();
6827
+ const series = input.map((s, index) => {
6828
+ let key = s.id ?? `#${index}`;
6829
+ while (usedKeys.has(key)) key += "'";
6830
+ usedKeys.add(key);
6831
+ let entry = cache.get(key);
6832
+ if (!entry || entry.data !== s.data || entry.resolverKey !== resolverKey) {
6833
+ entry = {
6834
+ data: s.data,
6835
+ resolverKey,
6836
+ cols: normalizeData(s.data, resolveX)
6837
+ };
6838
+ cache.set(key, entry);
6839
+ }
6840
+ const type = s.type ?? "line";
6841
+ const color = s.color ? resolve(s.color, theme.palette[index % theme.palette.length]) : theme.palette[index % theme.palette.length];
6842
+ const cols = entry.cols;
6843
+ let pointColors = null;
6844
+ if (type === "scatter" && cols.colors) {
6845
+ const resolved = /* @__PURE__ */ new Map();
6846
+ pointColors = cols.colors.map((c) => {
6847
+ if (c === void 0) return void 0;
6848
+ let rgba = resolved.get(c);
6849
+ if (!rgba) resolved.set(c, rgba = resolve(c, color));
6850
+ return rgba;
6851
+ });
6852
+ }
6853
+ const id = s.id ?? String(index);
6854
+ return {
6855
+ index,
6856
+ key,
6857
+ id,
6858
+ name: s.name ?? `Series ${index + 1}`,
6859
+ type,
6860
+ color,
6861
+ colorCss: toCss(color),
6862
+ lineWidth: s.lineWidth ?? 2,
6863
+ pointSize: s.pointSize ?? 8,
6864
+ opacity: s.opacity ?? (type === "area" ? .28 : type === "scatter" ? .78 : 1),
6865
+ hidden: !!s.hidden || hidden.has(id),
6866
+ showLabels: !!s.showLabels,
6867
+ cols,
6868
+ barOffset: 0,
6869
+ barHalfWidth: 0,
6870
+ barBase: null,
6871
+ barTop: null,
6872
+ pointColors
6873
+ };
6874
+ });
6875
+ const visible = series.filter((s) => !s.hidden);
6876
+ const allScatter = series.length > 0 && series.every((s) => s.type === "scatter");
6877
+ const bars = visible.filter((s) => s.type === "bar");
6878
+ const band = xType === "category" ? 1 : (() => {
6879
+ const step = smallestStep(bars.map((s) => s.cols));
6880
+ return Number.isFinite(step) ? step : 1;
6881
+ })();
6882
+ if (bars.length) {
6883
+ const slots = /* @__PURE__ */ new Map();
6884
+ for (const s of bars) {
6885
+ const stack = input[s.index].stack ?? `\u0000${s.key}`;
6886
+ if (!slots.has(stack)) slots.set(stack, slots.size);
6887
+ }
6888
+ const group = band * (slots.size > 1 ? .78 : .62);
6889
+ const slotWidth = group / slots.size;
6890
+ const sums = /* @__PURE__ */ new Map();
6891
+ for (const s of bars) {
6892
+ const stack = input[s.index].stack ?? `\u0000${s.key}`;
6893
+ const slot = slots.get(stack) ?? 0;
6894
+ s.barOffset = -group / 2 + slotWidth * (slot + .5);
6895
+ s.barHalfWidth = slotWidth / 2 * (slots.size > 1 ? .86 : 1);
6896
+ let totals = sums.get(stack);
6897
+ if (!totals) sums.set(stack, totals = /* @__PURE__ */ new Map());
6898
+ const { x, y, count } = s.cols;
6899
+ s.barBase = new Float64Array(count);
6900
+ s.barTop = new Float64Array(count);
6901
+ for (let i = 0; i < count; i++) {
6902
+ const v = y[i];
6903
+ if (!Number.isFinite(v)) {
6904
+ s.barBase[i] = NaN;
6905
+ s.barTop[i] = NaN;
6906
+ continue;
6907
+ }
6908
+ const t = totals.get(x[i]) ?? [0, 0];
6909
+ const base = v >= 0 ? t[0] : t[1];
6910
+ s.barBase[i] = base;
6911
+ s.barTop[i] = base + v;
6912
+ if (v >= 0) t[0] += v;
6913
+ else t[1] += v;
6914
+ totals.set(x[i], t);
6915
+ }
6916
+ }
6917
+ }
6918
+ const xOpts = options.xAxis;
6919
+ let xRange;
6920
+ if (xType === "category") xRange = [-.5, Math.max(1, categories.length) - .5];
6921
+ else {
6922
+ const values = [];
6923
+ for (const s of visible) {
6924
+ values.push(s.cols.xMin, s.cols.xMax);
6925
+ if (s.type === "bar") values.push(s.cols.xMin - band / 2, s.cols.xMax + band / 2);
6926
+ }
6927
+ xRange = ensureSpan(...extent(values), xType === "time" ? [Date.now() - 864e5, Date.now()] : [0, 1]);
6928
+ if (allScatter) {
6929
+ const pad = (xRange[1] - xRange[0]) * .04;
6930
+ xRange = [xRange[0] - pad, xRange[1] + pad];
6931
+ }
6932
+ if ((xOpts?.nice ?? (allScatter && xType === "linear")) && xType === "linear") xRange = niceDomain(xRange[0], xRange[1], xOpts?.tickCount ?? 6);
6933
+ }
6934
+ if (xOpts?.min !== void 0) xRange[0] = xOpts.min;
6935
+ if (xOpts?.max !== void 0) xRange[1] = xOpts.max;
6936
+ xRange = ensureSpan(xRange[0], xRange[1]);
6937
+ const yOpts = options.yAxis;
6938
+ const yValues = [];
6939
+ for (const s of visible) if (s.type === "bar" && s.barBase && s.barTop) yValues.push(...extent(s.barBase), ...extent(s.barTop));
6940
+ else yValues.push(s.cols.yMin, s.cols.yMax);
6941
+ if (bars.length || yOpts?.zero) yValues.push(0);
6942
+ let yRange = ensureSpan(...extent(yValues));
6943
+ if (allScatter) {
6944
+ const pad = (yRange[1] - yRange[0]) * .06;
6945
+ yRange = [yRange[0] - pad, yRange[1] + pad];
6946
+ }
6947
+ if ((yOpts?.nice ?? true) && (yOpts?.type ?? "linear") === "linear") yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);
6948
+ if (bars.length && !yOpts?.zero) {
6949
+ if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;
6950
+ }
6951
+ if (yOpts?.min !== void 0) yRange[0] = yOpts.min;
6952
+ if (yOpts?.max !== void 0) yRange[1] = yOpts.max;
6953
+ yRange = ensureSpan(yRange[0], yRange[1]);
6954
+ const zoomOption = options.interaction === false ? false : options.interaction === true || options.interaction === void 0 ? true : options.interaction.zoom ?? true;
6955
+ const zoomAxes = zoomOption === false ? {
6956
+ x: false,
6957
+ y: false
6958
+ } : zoomOption === true ? {
6959
+ x: true,
6960
+ y: allScatter
6961
+ } : {
6962
+ x: zoomOption.includes("x"),
6963
+ y: zoomOption.includes("y")
6964
+ };
6965
+ const tooltip = typeof options.tooltip === "object" ? options.tooltip : void 0;
6966
+ return {
6967
+ series,
6968
+ x: axisModel(xOpts, xType, categories, false),
6969
+ y: axisModel(yOpts, yOpts?.type === "time" ? "time" : "linear", [], true),
6970
+ base: {
6971
+ x: xRange,
6972
+ y: yRange
6973
+ },
6974
+ allScatter,
6975
+ zoom: zoomAxes,
6976
+ tooltipMode: tooltip?.mode ?? (allScatter ? "nearest" : "axis"),
6977
+ baseline: Math.min(Math.max(0, yRange[0]), yRange[1]),
6978
+ minSpan: {
6979
+ x: xType === "category" ? 1 : (xRange[1] - xRange[0]) * 1e-7,
6980
+ y: (yRange[1] - yRange[0]) * 1e-7
6981
+ }
6982
+ };
6983
+ };
6984
+ var grids = /* @__PURE__ */ new WeakMap();
6985
+ /** Spatial index of a scatter series, built on first use and kept with its data */
6986
+ var gridOf = (s) => {
6987
+ let grid = grids.get(s.cols);
6988
+ if (!grid) {
6989
+ grid = new GridIndex(s.cols.x, s.cols.y, s.cols.count);
6990
+ grids.set(s.cols, grid);
6991
+ }
6992
+ return grid;
6993
+ };
6994
+ //#endregion
6995
+ //#region ../charts/src/engine/overlay.ts
6996
+ var font = (theme, size = theme.fontSize, weight = 400) => `${weight} ${size}px ${theme.fontFamily}`;
6997
+ var crisp = (v) => Math.round(v) + .5;
6998
+ /** Box of a text annotation, kept inside the plot */
6999
+ var textBox = (a, s, width, height) => {
7000
+ const { plot } = s;
7001
+ const px = a.x === void 0 ? plot.x + plot.width / 2 : s.xToPx(a.x);
7002
+ const py = a.y === void 0 ? plot.y + plot.height / 2 : s.yToPx(a.y);
7003
+ const gap = 6;
7004
+ let x = px - width / 2;
7005
+ let y = py - height / 2;
7006
+ if (a.anchor === "top") y = py + gap;
7007
+ else if (a.anchor === "bottom") y = py - gap - height;
7008
+ else if (a.anchor === "left") x = px + gap;
7009
+ else if (a.anchor === "right") x = px - gap - width;
7010
+ x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));
7011
+ y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));
7012
+ return {
7013
+ x,
7014
+ y,
7015
+ width,
7016
+ height
7017
+ };
7018
+ };
7019
+ var rectOf = (a, s) => {
7020
+ const { plot } = s;
7021
+ const xa = a.x0 === void 0 ? -Infinity : s.xToPx(a.x0);
7022
+ const xb = a.x1 === void 0 ? Infinity : s.xToPx(a.x1);
7023
+ const ya = a.y0 === void 0 ? Infinity : s.yToPx(a.y0);
7024
+ const yb = a.y1 === void 0 ? -Infinity : s.yToPx(a.y1);
7025
+ const left = Math.max(plot.x, Math.min(xa, xb));
7026
+ const right = Math.min(plot.x + plot.width, Math.max(xa, xb));
7027
+ const top = Math.max(plot.y, Math.min(ya, yb));
7028
+ const bottom = Math.min(plot.y + plot.height, Math.max(ya, yb));
7029
+ return {
7030
+ x: left,
7031
+ y: top,
7032
+ width: right - left,
7033
+ height: bottom - top
7034
+ };
7035
+ };
7036
+ var drawBackground = (ctx, input) => {
7037
+ const { scales, theme, x, y, xTicks, yTicks } = input;
7038
+ const { plot } = scales;
7039
+ ctx.clearRect(0, 0, input.width, input.height);
7040
+ ctx.save();
7041
+ ctx.beginPath();
7042
+ ctx.rect(plot.x, plot.y, plot.width, plot.height);
7043
+ ctx.clip();
7044
+ for (const a of input.annotations) {
7045
+ if (a.type !== "rect") continue;
7046
+ const r = rectOf(a, scales);
7047
+ if (r.width <= 0 || r.height <= 0) continue;
7048
+ ctx.fillStyle = toCss(a.color, a.opacity);
7049
+ ctx.fillRect(r.x, r.y, r.width, r.height);
7050
+ }
7051
+ ctx.restore();
7052
+ ctx.lineWidth = 1;
7053
+ ctx.strokeStyle = toCss(theme.grid);
7054
+ ctx.beginPath();
7055
+ if (y.grid) for (const v of yTicks.values) {
7056
+ const py = crisp(scales.yToPx(v));
7057
+ if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;
7058
+ ctx.moveTo(plot.x, py);
7059
+ ctx.lineTo(plot.x + plot.width, py);
7060
+ }
7061
+ if (x.grid) for (const v of xTicks.values) {
7062
+ const px = crisp(scales.xToPx(v));
7063
+ if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;
7064
+ ctx.moveTo(px, plot.y);
7065
+ ctx.lineTo(px, plot.y + plot.height);
7066
+ }
7067
+ ctx.stroke();
7068
+ const line = Math.ceil(theme.fontSize * 1.4);
7069
+ ctx.font = font(theme);
7070
+ ctx.fillStyle = toCss(theme.textMuted);
7071
+ if (x.visible) {
7072
+ ctx.strokeStyle = toCss(theme.axis);
7073
+ ctx.beginPath();
7074
+ const base = crisp(plot.y + plot.height);
7075
+ ctx.moveTo(plot.x, base);
7076
+ ctx.lineTo(plot.x + plot.width, base);
7077
+ ctx.stroke();
7078
+ ctx.textBaseline = "top";
7079
+ ctx.textAlign = "center";
7080
+ let lastRight = -Infinity;
7081
+ const order = xTicks.values.map((v, i) => ({
7082
+ px: scales.xToPx(v),
7083
+ text: xTicks.labels[i]
7084
+ })).sort((a, b) => a.px - b.px);
7085
+ for (const { px, text } of order) {
7086
+ if (px < plot.x - .5 || px > plot.x + plot.width + .5) continue;
7087
+ const w = ctx.measureText(text).width;
7088
+ const left = Math.max(0, Math.min(input.width - w, px - w / 2));
7089
+ if (left < lastRight + 6) continue;
7090
+ lastRight = left + w;
7091
+ ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);
7092
+ }
7093
+ if (x.title) {
7094
+ ctx.font = font(theme, theme.fontSize + 1, 500);
7095
+ ctx.fillStyle = toCss(theme.text, .8);
7096
+ ctx.fillText(x.title, plot.x + plot.width / 2, plot.y + plot.height + line + 10);
7097
+ }
7098
+ }
7099
+ if (y.visible) {
7100
+ ctx.font = font(theme);
7101
+ ctx.fillStyle = toCss(theme.textMuted);
7102
+ ctx.textAlign = "right";
7103
+ ctx.textBaseline = "middle";
7104
+ yTicks.values.forEach((v, i) => {
7105
+ const py = scales.yToPx(v);
7106
+ if (py < plot.y - .5 || py > plot.y + plot.height + .5) return;
7107
+ ctx.fillText(yTicks.labels[i], plot.x - 8, py);
7108
+ });
7109
+ if (y.title) {
7110
+ ctx.save();
7111
+ ctx.font = font(theme, theme.fontSize + 1, 500);
7112
+ ctx.fillStyle = toCss(theme.text, .8);
7113
+ ctx.translate(line / 2 + 4, plot.y + plot.height / 2);
7114
+ ctx.rotate(-Math.PI / 2);
7115
+ ctx.textAlign = "center";
7116
+ ctx.fillText(y.title, 0, 0);
7117
+ ctx.restore();
7118
+ }
7119
+ }
7120
+ };
7121
+ var overlaps = (a, b) => a.x < b.x + b.width && b.x < a.x + a.width && a.y < b.y + b.height && b.y < a.y + a.height;
7122
+ var inside = (r, plot) => r.x >= plot.x && r.y >= plot.y && r.x + r.width <= plot.x + plot.width && r.y + r.height <= plot.y + plot.height;
7123
+ /** Text with a halo in the background color (readable over data) */
7124
+ var haloText = (ctx, text, x, y, color, halo) => {
7125
+ ctx.lineWidth = 3;
7126
+ ctx.lineJoin = "round";
7127
+ ctx.strokeStyle = halo;
7128
+ ctx.strokeText(text, x, y);
7129
+ ctx.fillStyle = color;
7130
+ ctx.fillText(text, x, y);
7131
+ };
7132
+ /** Greedy placement: right, left, above, below the dot; skipped when no slot is free */
7133
+ var placeLabels = (labels, plot, measure, height, occupied = []) => {
7134
+ const placed = [];
7135
+ for (const label of labels) {
7136
+ const w = measure(label.text);
7137
+ const gap = label.r + 4;
7138
+ const box = [
7139
+ {
7140
+ x: label.x + gap,
7141
+ y: label.y - height / 2,
7142
+ width: w,
7143
+ height
7144
+ },
7145
+ {
7146
+ x: label.x - gap - w,
7147
+ y: label.y - height / 2,
7148
+ width: w,
7149
+ height
7150
+ },
7151
+ {
7152
+ x: label.x - w / 2,
7153
+ y: label.y - gap - height,
7154
+ width: w,
7155
+ height
7156
+ },
7157
+ {
7158
+ x: label.x - w / 2,
7159
+ y: label.y + gap,
7160
+ width: w,
7161
+ height
7162
+ }
7163
+ ].find((c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)));
7164
+ if (!box) continue;
7165
+ occupied.push(box);
7166
+ placed.push({
7167
+ label,
7168
+ box
7169
+ });
7170
+ }
7171
+ return placed;
7172
+ };
7173
+ var drawForeground = (ctx, input) => {
7174
+ const { scales, theme } = input;
7175
+ const { plot } = scales;
7176
+ if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);
7177
+ ctx.save();
7178
+ ctx.beginPath();
7179
+ ctx.rect(plot.x, plot.y, plot.width, plot.height);
7180
+ ctx.clip();
7181
+ const halo = toCss(theme.background, .9);
7182
+ const occupied = [];
7183
+ const labelHeight = theme.fontSize + 4;
7184
+ for (const a of input.annotations) {
7185
+ if (a.type !== "line") continue;
7186
+ const color = toCss(a.color);
7187
+ ctx.strokeStyle = color;
7188
+ ctx.lineWidth = a.width;
7189
+ ctx.setLineDash(a.dash);
7190
+ ctx.beginPath();
7191
+ if (a.axis === "y") {
7192
+ const py = crisp(scales.yToPx(a.value));
7193
+ ctx.moveTo(plot.x, py);
7194
+ ctx.lineTo(plot.x + plot.width, py);
7195
+ ctx.stroke();
7196
+ if (a.label) {
7197
+ ctx.setLineDash([]);
7198
+ ctx.font = font(theme, theme.fontSize, 500);
7199
+ ctx.textAlign = "right";
7200
+ ctx.textBaseline = "bottom";
7201
+ haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);
7202
+ }
7203
+ } else {
7204
+ const px = crisp(scales.xToPx(a.value));
7205
+ ctx.moveTo(px, plot.y);
7206
+ ctx.lineTo(px, plot.y + plot.height);
7207
+ ctx.stroke();
7208
+ if (a.label) {
7209
+ ctx.setLineDash([]);
7210
+ ctx.font = font(theme, theme.fontSize, 500);
7211
+ ctx.textAlign = "left";
7212
+ ctx.textBaseline = "top";
7213
+ haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);
7214
+ }
7215
+ }
7216
+ }
7217
+ ctx.setLineDash([]);
7218
+ ctx.font = font(theme, theme.fontSize + 1, 600);
7219
+ for (const a of input.annotations) {
7220
+ if (a.type !== "rect" || !a.label) continue;
7221
+ const r = rectOf(a, scales);
7222
+ if (r.width <= 0 || r.height <= 0) continue;
7223
+ const pad = 10;
7224
+ const w = ctx.measureText(a.label).width;
7225
+ const pos = a.labelPosition;
7226
+ const tx = pos.endsWith("left") ? r.x + pad : pos.endsWith("right") ? r.x + r.width - pad - w : r.x + (r.width - w) / 2;
7227
+ const ty = pos.startsWith("top") ? r.y + pad : pos.startsWith("bottom") ? r.y + r.height - pad - labelHeight : r.y + (r.height - labelHeight) / 2;
7228
+ ctx.textAlign = "left";
7229
+ ctx.textBaseline = "top";
7230
+ ctx.fillStyle = toCss(a.labelColor);
7231
+ ctx.fillText(a.label, tx, ty);
7232
+ occupied.push({
7233
+ x: tx,
7234
+ y: ty,
7235
+ width: w,
7236
+ height: labelHeight
7237
+ });
7238
+ }
7239
+ for (const a of input.annotations) {
7240
+ if (a.type !== "text" || !a.text) continue;
7241
+ ctx.font = font(theme, theme.fontSize, a.weight);
7242
+ const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);
7243
+ ctx.textAlign = "left";
7244
+ ctx.textBaseline = "middle";
7245
+ haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);
7246
+ occupied.push(box);
7247
+ }
7248
+ if (input.pointLabels.length) {
7249
+ ctx.font = font(theme);
7250
+ ctx.textAlign = "left";
7251
+ ctx.textBaseline = "middle";
7252
+ const textColor = toCss(theme.text, .85);
7253
+ const placed = placeLabels(input.pointLabels, plot, (t) => ctx.measureText(t).width, labelHeight - 2, occupied);
7254
+ for (const { label, box } of placed) haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);
7255
+ }
7256
+ ctx.restore();
7257
+ };
7258
+ //#endregion
7259
+ //#region ../charts/src/engine/format.ts
7260
+ var UNITS = [
7261
+ [0xe8d4a51000, "T"],
7262
+ [1e9, "B"],
7263
+ [1e6, "M"],
7264
+ [1e3, "k"]
7265
+ ];
7266
+ var trim = (text) => text.includes(".") ? text.replace(/\.?0+$/, "") : text;
7267
+ /** `1234567` -> `1.23M`, `0.5` -> `0.5`; `-0` is printed as `0` */
7268
+ var formatCompact = (value, maxDecimals = 2) => {
7269
+ if (!Number.isFinite(value)) return String(value);
7270
+ if (Object.is(value, -0) || value === 0) return "0";
7271
+ const abs = Math.abs(value);
7272
+ for (const [unit, suffix] of UNITS) if (abs >= unit) return trim((value / unit).toFixed(maxDecimals)) + suffix;
7273
+ if (abs < 1e-4) return value.toExponential(1);
7274
+ const decimals = Math.min(6, Math.max(maxDecimals, stepDecimals(abs) + 2));
7275
+ return trim(value.toFixed(decimals));
7276
+ };
7277
+ /**
7278
+ * Formatter of the ticks of a linear axis: enough decimals to tell the
7279
+ * ticks apart; compact units (k, M, ...) when the values are large.
7280
+ */
7281
+ var tickFormatter = (step, maxAbs) => {
7282
+ if (maxAbs >= 1e4) {
7283
+ const unit = UNITS.find(([u]) => maxAbs >= u)?.[0] ?? 1;
7284
+ const decimals = Math.min(3, stepDecimals(step / unit));
7285
+ return (value) => formatCompact(value, decimals);
7286
+ }
7287
+ const decimals = stepDecimals(step);
7288
+ return (value) => {
7289
+ const text = value.toFixed(decimals);
7290
+ return /^-0(\.0*)?$/.test(text) ? text.slice(1) : text;
7291
+ };
7292
+ };
7293
+ /** Value of a tooltip: up to 4 significant decimals */
7294
+ var formatValue = (value) => {
7295
+ if (!Number.isFinite(value)) return "–";
7296
+ const abs = Math.abs(value);
7297
+ if (abs >= 1e6) return formatCompact(value, 2);
7298
+ if (Number.isInteger(value)) return value.toLocaleString("en-US");
7299
+ return trim(value.toFixed(abs >= 100 ? 2 : abs >= 1 ? 3 : 4));
7300
+ };
7301
+ //#endregion
7302
+ //#region ../charts/src/engine/time.ts
7303
+ var SECOND = 1e3;
7304
+ var MINUTE = 60 * SECOND;
7305
+ var HOUR = 60 * MINUTE;
7306
+ var DAY = 24 * HOUR;
7307
+ var MONTH = 30 * DAY;
7308
+ var YEAR = 365 * DAY;
7309
+ var INTERVALS = [
7310
+ {
7311
+ unit: "second",
7312
+ step: 1,
7313
+ ms: SECOND
7314
+ },
7315
+ {
7316
+ unit: "second",
7317
+ step: 5,
7318
+ ms: 5 * SECOND
7319
+ },
7320
+ {
7321
+ unit: "second",
7322
+ step: 15,
7323
+ ms: 15 * SECOND
7324
+ },
7325
+ {
7326
+ unit: "second",
7327
+ step: 30,
7328
+ ms: 30 * SECOND
7329
+ },
7330
+ {
7331
+ unit: "minute",
7332
+ step: 1,
7333
+ ms: MINUTE
7334
+ },
7335
+ {
7336
+ unit: "minute",
7337
+ step: 5,
7338
+ ms: 5 * MINUTE
7339
+ },
7340
+ {
7341
+ unit: "minute",
7342
+ step: 15,
7343
+ ms: 15 * MINUTE
7344
+ },
7345
+ {
7346
+ unit: "minute",
7347
+ step: 30,
7348
+ ms: 30 * MINUTE
7349
+ },
7350
+ {
7351
+ unit: "hour",
7352
+ step: 1,
7353
+ ms: HOUR
7354
+ },
7355
+ {
7356
+ unit: "hour",
7357
+ step: 3,
7358
+ ms: 3 * HOUR
7359
+ },
7360
+ {
7361
+ unit: "hour",
7362
+ step: 6,
7363
+ ms: 6 * HOUR
7364
+ },
7365
+ {
7366
+ unit: "hour",
7367
+ step: 12,
7368
+ ms: 12 * HOUR
7369
+ },
7370
+ {
7371
+ unit: "day",
7372
+ step: 1,
7373
+ ms: DAY
7374
+ },
7375
+ {
7376
+ unit: "day",
7377
+ step: 2,
7378
+ ms: 2 * DAY
7379
+ },
7380
+ {
7381
+ unit: "day",
7382
+ step: 7,
7383
+ ms: 7 * DAY
7384
+ },
7385
+ {
7386
+ unit: "month",
7387
+ step: 1,
7388
+ ms: MONTH
7389
+ },
7390
+ {
7391
+ unit: "month",
7392
+ step: 3,
7393
+ ms: 3 * MONTH
7394
+ },
7395
+ {
7396
+ unit: "month",
7397
+ step: 6,
7398
+ ms: 6 * MONTH
7399
+ }
7400
+ ];
7401
+ var pad = (n, width = 2) => String(n).padStart(width, "0");
7402
+ var chooseInterval = (span, count) => {
7403
+ const target = span / Math.max(1, count);
7404
+ if (target < SECOND * .75) return {
7405
+ unit: "millisecond",
7406
+ step: tickStep(0, span, count),
7407
+ ms: 1
7408
+ };
7409
+ for (const interval of INTERVALS) if (interval.ms >= target * .75) return interval;
7410
+ const years = Math.max(1, tickStep(0, span / YEAR, count));
7411
+ return {
7412
+ unit: "year",
7413
+ step: Math.round(years),
7414
+ ms: Math.round(years) * YEAR
7415
+ };
7416
+ };
7417
+ /** Start of the tick sequence: `t` floored to the unit, aligned on the step */
7418
+ var floorTo = (t, { unit, step }) => {
7419
+ const d = new Date(t);
7420
+ switch (unit) {
7421
+ case "second":
7422
+ d.setMilliseconds(0);
7423
+ d.setSeconds(d.getSeconds() - d.getSeconds() % step);
7424
+ break;
7425
+ case "minute":
7426
+ d.setSeconds(0, 0);
7427
+ d.setMinutes(d.getMinutes() - d.getMinutes() % step);
7428
+ break;
7429
+ case "hour":
7430
+ d.setMinutes(0, 0, 0);
7431
+ d.setHours(d.getHours() - d.getHours() % step);
7432
+ break;
7433
+ case "day":
7434
+ d.setHours(0, 0, 0, 0);
7435
+ if (step === 7) d.setDate(d.getDate() - (d.getDay() + 6) % 7);
7436
+ break;
7437
+ case "month":
7438
+ d.setHours(0, 0, 0, 0);
7439
+ d.setDate(1);
7440
+ d.setMonth(d.getMonth() - d.getMonth() % step);
7441
+ break;
7442
+ case "year":
7443
+ d.setHours(0, 0, 0, 0);
7444
+ d.setMonth(0, 1);
7445
+ d.setFullYear(d.getFullYear() - d.getFullYear() % step);
7446
+ }
7447
+ return d;
7448
+ };
7449
+ var advance = (d, { unit, step }) => {
7450
+ switch (unit) {
7451
+ case "second":
7452
+ d.setSeconds(d.getSeconds() + step);
7453
+ break;
7454
+ case "minute":
7455
+ d.setMinutes(d.getMinutes() + step);
7456
+ break;
7457
+ case "hour":
7458
+ d.setHours(d.getHours() + step);
7459
+ break;
7460
+ case "day":
7461
+ d.setDate(d.getDate() + step);
7462
+ break;
7463
+ case "month":
7464
+ d.setMonth(d.getMonth() + step);
7465
+ break;
7466
+ case "year": d.setFullYear(d.getFullYear() + step);
7467
+ }
7468
+ };
7469
+ /** Calendar-aligned ticks between two timestamps */
7470
+ var timeTicks = (min, max, count) => {
7471
+ if (min > max) [min, max] = [max, min];
7472
+ const interval = chooseInterval(max - min, count);
7473
+ if (interval.unit === "millisecond") return {
7474
+ values: linearTicks(min, max, count),
7475
+ unit: "millisecond",
7476
+ format: (v) => formatTime(v, "millisecond")
7477
+ };
7478
+ const values = [];
7479
+ const d = floorTo(min, interval);
7480
+ while (d.getTime() < min) advance(d, interval);
7481
+ while (d.getTime() <= max && values.length < 500) {
7482
+ values.push(d.getTime());
7483
+ advance(d, interval);
7484
+ }
7485
+ const { unit } = interval;
7486
+ return {
7487
+ values,
7488
+ unit,
7489
+ format: (v) => formatTick(v, unit)
7490
+ };
7491
+ };
7492
+ var ymd = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
7493
+ var hm = (d) => `${pad(d.getHours())}:${pad(d.getMinutes())}`;
7494
+ /** Short tick label; day boundaries show the date, year boundaries the year */
7495
+ var formatTick = (value, unit) => {
7496
+ const d = new Date(value);
7497
+ const midnight = d.getHours() === 0 && d.getMinutes() === 0 && d.getSeconds() === 0;
7498
+ switch (unit) {
7499
+ case "second": return `${hm(d)}:${pad(d.getSeconds())}`;
7500
+ case "minute":
7501
+ case "hour": return midnight ? `${pad(d.getMonth() + 1)}-${pad(d.getDate())}` : hm(d);
7502
+ case "day": return d.getMonth() === 0 && d.getDate() === 1 ? String(d.getFullYear()) : `${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
7503
+ case "month": return d.getMonth() === 0 ? String(d.getFullYear()) : `${d.getFullYear()}-${pad(d.getMonth() + 1)}`;
7504
+ default: return String(d.getFullYear());
7505
+ }
7506
+ };
7507
+ /** Full label (tooltips): precision follows the unit of the ticks */
7508
+ var formatTime = (value, unit = "minute") => {
7509
+ const d = new Date(value);
7510
+ if (Number.isNaN(d.getTime())) return "–";
7511
+ switch (unit) {
7512
+ case "millisecond": return `${ymd(d)} ${hm(d)}:${pad(d.getSeconds())}.${pad(d.getMilliseconds(), 3)}`;
7513
+ case "second": return `${ymd(d)} ${hm(d)}:${pad(d.getSeconds())}`;
7514
+ case "minute":
7515
+ case "hour": return `${ymd(d)} ${hm(d)}`;
7516
+ default: return ymd(d);
7517
+ }
7518
+ };
7519
+ //#endregion
7520
+ //#region ../charts/src/engine/axis.ts
7521
+ /**
7522
+ * @param count approximate number of ticks (numeric / time axes) or the
7523
+ * maximum number of labels (category axes)
7524
+ */
7525
+ var axisTicks = (axis, range, count) => {
7526
+ const [min, max] = range[0] <= range[1] ? range : [range[1], range[0]];
7527
+ if (axis.type === "category") {
7528
+ const n = axis.categories.length;
7529
+ const first = Math.max(0, Math.ceil(min - 1e-9));
7530
+ const last = Math.min(n - 1, Math.floor(max + 1e-9));
7531
+ const visible = Math.max(0, last - first + 1);
7532
+ const step = Math.max(1, Math.ceil(visible / Math.max(1, count)));
7533
+ const values = [];
7534
+ for (let i = first - first % step; i <= last; i += step) if (i >= first) values.push(i);
7535
+ const name = (v) => {
7536
+ const i = Math.round(v);
7537
+ return axis.format ? axis.format(i) : axis.categories[i] ?? String(i);
7538
+ };
7539
+ return {
7540
+ values,
7541
+ labels: values.map(name),
7542
+ formatValue: name
7543
+ };
7544
+ }
7545
+ if (axis.type === "time") {
7546
+ const ticks = timeTicks(min, max, count);
7547
+ const unit = ticks.unit === "day" || ticks.unit === "month" || ticks.unit === "year" ? "day" : ticks.unit;
7548
+ const full = axis.format ?? ((v) => formatTime(v, unit));
7549
+ return {
7550
+ values: ticks.values,
7551
+ labels: ticks.values.map(axis.format ?? ticks.format),
7552
+ formatValue: full
7553
+ };
7554
+ }
7555
+ const values = linearTicks(min, max, count);
7556
+ const step = tickStep(min, max, count);
7557
+ const tick = axis.format ?? tickFormatter(step, Math.max(Math.abs(min), Math.abs(max)));
7558
+ return {
7559
+ values,
7560
+ labels: values.map(tick),
7561
+ formatValue: axis.format ?? formatValue
7562
+ };
7563
+ };
7564
+ var DEFAULT_PADDING = {
7565
+ top: 12,
7566
+ right: 16,
7567
+ bottom: 4,
7568
+ left: 4
7569
+ };
7570
+ var fallbackResolve = (_value, fallback) => fallback;
7571
+ /** Annotation colors resolved against the theme */
7572
+ var resolveAnnotations = (annotations, theme) => {
7573
+ const resolve = theme.resolve ?? fallbackResolve;
7574
+ return (annotations ?? []).map((a) => {
7575
+ if (a.type === "rect") {
7576
+ const color = a.color ? resolve(a.color, theme.primary) : theme.primary;
7577
+ return {
7578
+ type: "rect",
7579
+ x0: a.x0,
7580
+ x1: a.x1,
7581
+ y0: a.y0,
7582
+ y1: a.y1,
7583
+ color,
7584
+ opacity: a.opacity ?? .08,
7585
+ label: a.label,
7586
+ labelPosition: a.labelPosition ?? "top-left",
7587
+ labelColor: a.labelColor ? resolve(a.labelColor, color) : mix(color, theme.text, .2)
7588
+ };
7589
+ }
7590
+ if (a.type === "text") return {
7591
+ type: "text",
7592
+ x: a.x,
7593
+ y: a.y,
7594
+ text: a.text,
7595
+ anchor: a.anchor ?? "center",
7596
+ color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,
7597
+ weight: a.weight ?? 500
7598
+ };
7599
+ return {
7600
+ type: "line",
7601
+ axis: a.axis,
7602
+ value: a.value,
7603
+ color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,
7604
+ width: a.width ?? 1,
7605
+ dash: [...a.dash ?? [4, 4]],
7606
+ label: a.label
7607
+ };
7608
+ });
7609
+ };
7610
+ /** Ticks, room for the axes and the plot rectangle */
7611
+ var layoutChart = (input) => {
7612
+ const { model, view, theme, width, height, measure } = input;
7613
+ const yCount = model.y.tickCount ?? (height >= 220 ? 5 : Math.max(2, Math.round((height - 48) / 52)));
7614
+ const yTicks = axisTicks(model.y, view.y, yCount);
7615
+ let yLabelWidth = 0;
7616
+ if (model.y.visible) for (const label of yTicks.labels) yLabelWidth = Math.max(yLabelWidth, measure(label));
7617
+ let categoryWidth = 48;
7618
+ if (model.x.type === "category") {
7619
+ categoryWidth = 0;
7620
+ const step = Math.max(1, Math.floor(model.x.categories.length / 200));
7621
+ for (let i = 0; i < model.x.categories.length; i += step) categoryWidth = Math.max(categoryWidth, measure(model.x.categories[i]));
7622
+ }
7623
+ const plot = computePlot({
7624
+ width,
7625
+ height,
7626
+ padding: {
7627
+ ...DEFAULT_PADDING,
7628
+ ...input.padding
7629
+ },
7630
+ yLabelWidth: model.y.visible ? Math.ceil(yLabelWidth) : 0,
7631
+ xAxisVisible: model.x.visible,
7632
+ xTitle: !!model.x.title && model.x.visible,
7633
+ yTitle: !!model.y.title && model.y.visible,
7634
+ fontSize: theme.fontSize
7635
+ });
7636
+ if (input.top) plot.y += input.top;
7637
+ const xCount = model.x.type === "category" ? Math.max(1, Math.floor(plot.width / (categoryWidth + 14))) : model.x.tickCount ?? Math.max(2, Math.floor(plot.width / 96));
7638
+ const xTicks = axisTicks(model.x, view.x, xCount);
7639
+ return {
7640
+ plot,
7641
+ scales: createScales(plot, view, model.x.reverse, model.y.reverse),
7642
+ xTicks,
7643
+ yTicks
7644
+ };
7645
+ };
7646
+ /** Labels of the visible scatter points (`showLabels`) */
7647
+ var collectPointLabels = (model, view, s) => {
7648
+ const labels = [];
7649
+ for (const series of model.series) {
7650
+ if (series.hidden || series.type !== "scatter" || !series.showLabels) continue;
7651
+ const { x, y, count, labels: texts, size } = series.cols;
7652
+ if (!texts) continue;
7653
+ for (let i = 0; i < count && labels.length < 300; i++) {
7654
+ const text = texts[i];
7655
+ if (!text) continue;
7656
+ const xi = x[i];
7657
+ const yi = y[i];
7658
+ if (xi < view.x[0] || xi > view.x[1] || yi < view.y[0] || yi > view.y[1]) continue;
7659
+ const d = size && size[i] > 0 ? size[i] : series.pointSize;
7660
+ labels.push({
7661
+ x: s.xToPx(xi),
7662
+ y: s.yToPx(yi),
7663
+ r: d / 2,
7664
+ text
7665
+ });
7666
+ }
7667
+ }
7668
+ return labels;
7669
+ };
7670
+ /** Pixel position of a point (the top of a bar) */
7671
+ var pointOf = (s, i, sc) => {
7672
+ const xv = s.cols.x[i] + (s.type === "bar" ? s.barOffset : 0);
7673
+ const yv = s.type === "bar" && s.barTop ? s.barTop[i] : s.cols.y[i];
7674
+ return {
7675
+ px: sc.xToPx(xv),
7676
+ py: sc.yToPx(yv)
7677
+ };
7678
+ };
7679
+ var candidateOf = (s, i, px, py, sc) => {
7680
+ const p = pointOf(s, i, sc);
7681
+ let inside = false;
7682
+ if (s.type === "bar" && s.barBase) {
7683
+ const half = s.barHalfWidth / sc.xPerPx;
7684
+ const base = sc.yToPx(s.barBase[i]);
7685
+ inside = Math.abs(px - p.px) <= half && py >= Math.min(base, p.py) - 2 && py <= Math.max(base, p.py) + 2;
7686
+ }
7687
+ return {
7688
+ series: s,
7689
+ index: i,
7690
+ px: p.px,
7691
+ py: p.py,
7692
+ dx: Math.abs(sc.xToPx(s.cols.x[i]) - px),
7693
+ dist: inside ? 0 : Math.hypot(p.px - px, p.py - py),
7694
+ inside
7695
+ };
7696
+ };
7697
+ /** Diameter of a scatter dot */
7698
+ var dotSize = (s, i) => s.cols.size && s.cols.size[i] > 0 ? s.cols.size[i] : s.pointSize;
7699
+ var nearestScatter = (s, px, py, sc, slop) => {
7700
+ const radius = Math.max(s.pointSize / 2 + 6, 10) + slop;
7701
+ const xv = sc.pxToX(px);
7702
+ const yv = sc.pxToY(py);
7703
+ const rx = radius * sc.xPerPx;
7704
+ const ry = radius * sc.yPerPx;
7705
+ let best = -1;
7706
+ let bestDist = Infinity;
7707
+ const { x, y } = s.cols;
7708
+ gridOf(s).query(xv - rx, xv + rx, yv - ry, yv + ry, (i) => {
7709
+ const d = Math.hypot(sc.xToPx(x[i]) - px, sc.yToPx(y[i]) - py);
7710
+ if (d <= Math.max(dotSize(s, i) / 2 + 4, 8) + slop && d <= bestDist) {
7711
+ bestDist = d;
7712
+ best = i;
7713
+ }
7714
+ });
7715
+ return best;
7716
+ };
7717
+ var nearestX = (s, xv) => {
7718
+ const { x, y, count, sorted } = s.cols;
7719
+ if (sorted) return nearestIndex(x, y, count, xv);
7720
+ let best = -1;
7721
+ let bestD = Infinity;
7722
+ for (let i = 0; i < count; i++) {
7723
+ if (!Number.isFinite(y[i])) continue;
7724
+ const d = Math.abs(x[i] - xv);
7725
+ if (d < bestD) {
7726
+ bestD = d;
7727
+ best = i;
7728
+ }
7729
+ }
7730
+ return best;
7731
+ };
7732
+ /** Hover payload item of a point */
7733
+ var hoverItemOf = (s, index) => {
7734
+ const pc = s.pointColors?.[index];
7735
+ const label = s.cols.labels?.[index];
7736
+ return {
7737
+ seriesIndex: s.index,
7738
+ seriesId: s.id,
7739
+ seriesName: s.name,
7740
+ index,
7741
+ x: s.cols.x[index],
7742
+ y: s.cols.y[index],
7743
+ color: pc ? toCss(pc) : s.colorCss,
7744
+ ...label !== void 0 ? { label } : {}
7745
+ };
7746
+ };
7747
+ var eventOf = (candidates, xTicks) => {
7748
+ if (!candidates.length) return null;
7749
+ candidates.sort((a, b) => a.series.index - b.series.index);
7750
+ const items = candidates.map((c) => hoverItemOf(c.series, c.index));
7751
+ const x = items[0].x;
7752
+ return {
7753
+ items,
7754
+ x,
7755
+ xLabel: xTicks?.formatValue(x) ?? String(x)
7756
+ };
7757
+ };
7758
+ /**
7759
+ * Points under a pixel of the stage: the nearest point (scatter / `nearest`
7760
+ * tooltips) or every series at the nearest x (`axis` tooltips).
7761
+ * `slop` widens the reach of the dots (touch screens).
7762
+ */
7763
+ var hitTest = (model, sc, xTicks, px, py, slop = 0) => {
7764
+ const { plot } = sc;
7765
+ const margin = 6 + slop;
7766
+ if (px < plot.x - margin || px > plot.x + plot.width + margin || py < plot.y - margin || py > plot.y + plot.height + margin) return null;
7767
+ const xv = sc.pxToX(px);
7768
+ const scatter = [];
7769
+ const others = [];
7770
+ for (const s of model.series) {
7771
+ if (s.hidden || s.cols.count === 0) continue;
7772
+ if (s.type === "scatter") {
7773
+ const i = nearestScatter(s, px, py, sc, slop);
7774
+ if (i >= 0) scatter.push(candidateOf(s, i, px, py, sc));
7775
+ } else {
7776
+ const i = nearestX(s, xv);
7777
+ if (i >= 0) others.push(candidateOf(s, i, px, py, sc));
7778
+ }
7779
+ }
7780
+ if (model.tooltipMode === "nearest") {
7781
+ const all = [...scatter, ...others].filter((c) => c.inside || c.series.type === "scatter" || c.dist <= 32 + slop);
7782
+ if (!all.length) return null;
7783
+ return eventOf([all.reduce((a, b) => b.dist <= a.dist ? b : a)], xTicks);
7784
+ }
7785
+ if (!others.length) {
7786
+ if (!scatter.length) return null;
7787
+ return eventOf([scatter.reduce((a, b) => b.dist <= a.dist ? b : a)], xTicks);
7788
+ }
7789
+ const bestDx = Math.min(...others.map((c) => c.dx));
7790
+ const bandPx = model.x.type === "category" ? .5 / sc.xPerPx : 0;
7791
+ const aligned = others.filter((c) => c.dx <= bestDx + Math.max(1, bandPx));
7792
+ const first = aligned.reduce((a, b) => b.dx < a.dx ? b : a);
7793
+ const event = eventOf([
7794
+ first,
7795
+ ...aligned.filter((c) => c !== first),
7796
+ ...scatter
7797
+ ], xTicks);
7798
+ if (event) {
7799
+ event.x = hoverItemOf(first.series, first.index).x;
7800
+ event.xLabel = xTicks?.formatValue(event.x) ?? String(event.x);
7801
+ }
7802
+ return event;
7803
+ };
7804
+ /** Whether two hover payloads point at the same points */
7805
+ var sameHover = (a, b) => a === b || !!a && !!b && a.items.length === b.items.length && a.items.every((it, i) => it.index === b.items[i].index && it.seriesIndex === b.items[i].seriesIndex);
7806
+ /** Default tooltip content of a hover payload */
7807
+ var tooltipContent = (model, event, yTicks) => {
7808
+ const yFormat = yTicks?.formatValue ?? String;
7809
+ if (event.items.every((it) => model.series[it.seriesIndex].type === "scatter") && event.items.length === 1) {
7810
+ const it = event.items[0];
7811
+ const rows = [{
7812
+ color: null,
7813
+ name: model.x.title ?? "x",
7814
+ value: event.xLabel
7815
+ }, {
7816
+ color: null,
7817
+ name: model.y.title ?? "y",
7818
+ value: yFormat(it.y)
7819
+ }];
7820
+ if (it.label !== void 0 && model.series.length > 1) rows.push({
7821
+ color: null,
7822
+ name: "",
7823
+ value: it.seriesName
7824
+ });
7825
+ return {
7826
+ title: it.label ?? it.seriesName,
7827
+ titleColor: it.color,
7828
+ rows
7829
+ };
7830
+ }
7831
+ return {
7832
+ title: event.xLabel,
7833
+ titleColor: null,
7834
+ rows: event.items.map((it) => ({
7835
+ color: it.color,
7836
+ name: it.label ? `${it.seriesName} · ${it.label}` : it.seriesName,
7837
+ value: yFormat(it.y)
7838
+ }))
7839
+ };
7840
+ };
7841
+ /** Markers of the hovered points (pixels of the stage) */
7842
+ var hoverMarks = (model, sc, event) => {
7843
+ const marks = [];
7844
+ const { plot } = sc;
7845
+ for (const it of event.items) {
7846
+ const s = model.series[it.seriesIndex];
7847
+ if (s.type === "bar" && s.barBase && s.barTop) {
7848
+ const cx = sc.xToPx(it.x + s.barOffset);
7849
+ const half = Math.max(s.barHalfWidth / sc.xPerPx, 1);
7850
+ const a = sc.yToPx(s.barBase[it.index]);
7851
+ const b = sc.yToPx(s.barTop[it.index]);
7852
+ marks.push({
7853
+ kind: "bar",
7854
+ x: cx - half,
7855
+ y: Math.min(a, b),
7856
+ width: half * 2,
7857
+ height: Math.max(1, Math.abs(a - b))
7858
+ });
7859
+ continue;
7860
+ }
7861
+ const px = sc.xToPx(it.x);
7862
+ const py = sc.yToPx(it.y);
7863
+ if (px < plot.x - 1 || px > plot.x + plot.width + 1 || py < plot.y - 1 || py > plot.y + plot.height + 1) continue;
7864
+ const size = s.type === "scatter" ? dotSize(s, it.index) + 6 : Math.max(10, s.lineWidth * 2 + 6);
7865
+ marks.push({
7866
+ kind: "dot",
7867
+ x: px,
7868
+ y: py,
7869
+ size,
7870
+ color: it.color
7871
+ });
7872
+ }
7873
+ return marks;
7874
+ };
7875
+ /** Whether the guide line follows the pointer */
7876
+ var showsCrosshair = (model, event, crosshair) => crosshair ?? (model.tooltipMode === "axis" && event.items.some((it) => model.series[it.seriesIndex].type !== "scatter"));
7877
+ //#endregion
7878
+ //#region ../charts/src/engine/theme.ts
7879
+ /** Used when no CSS variable is defined (e.g. without the Minerva stylesheet) */
7880
+ var DEFAULT_PALETTE = [
7881
+ "#4f46e5",
7882
+ "#10b981",
7883
+ "#f59e0b",
7884
+ "#ef4444",
7885
+ "#0ea5e9",
7886
+ "#8b5cf6",
7887
+ "#14b8a6",
7888
+ "#f97316"
7889
+ ];
7890
+ /** Builds a theme from plain values (no DOM) */
7891
+ var createTheme = (input = {}, palette) => {
7892
+ const variables = input.variables ?? {};
7893
+ return {
7894
+ ...buildTheme((name) => variables[name]?.trim() ?? "", staticColorResolver(variables), palette?.length ? palette : input.palette, ""),
7895
+ ...input.fontFamily ? { fontFamily: input.fontFamily } : {},
7896
+ ...input.fontSize ? { fontSize: input.fontSize } : {}
7897
+ };
7898
+ };
7899
+ /** Resolver of `var(--name, fallback)` colors against plain variables */
7900
+ var staticColorResolver = (variables) => (value, fallback) => resolveStaticColor(value, variables, fallback);
7901
+ var buildTheme = (readVariable, resolve, palette, inheritedFont) => {
7902
+ const fallbackGray = [
7903
+ .4,
7904
+ .4,
7905
+ .4,
7906
+ 1
7907
+ ];
7908
+ const resolveColor = (value) => resolve(value, fallbackGray);
7909
+ const color = (names, fallback) => {
7910
+ for (const name of names) if (readVariable(name)) return resolveColor(`var(${name})`);
7911
+ return resolveColor(fallback);
7912
+ };
7913
+ const background = color(["--surface-color", "--background-color"], "#ffffff");
7914
+ const text = color(["--text-color"], "#1f2937");
7915
+ const textMuted = color(["--text-secondary-color", "--text-muted-color"], "#6b7280");
7916
+ const border = color(["--border-color"], "#e5e7eb");
7917
+ let colors;
7918
+ if (palette && palette.length) colors = palette.map((c) => resolveColor(c));
7919
+ else {
7920
+ const custom = [];
7921
+ for (let i = 1; i <= 8; i++) {
7922
+ const name = `--chart-series-${i}`;
7923
+ if (readVariable(name)) custom.push(resolveColor(`var(${name})`));
7924
+ }
7925
+ if (custom.length) colors = custom;
7926
+ else colors = [...[
7927
+ "--primary-color",
7928
+ "--success-color",
7929
+ "--warning-color",
7930
+ "--danger-color",
7931
+ "--info-color"
7932
+ ].map((name, i) => readVariable(name) ? resolveColor(`var(${name})`) : resolveColor(DEFAULT_PALETTE[i])), ...DEFAULT_PALETTE.slice(5).map((c) => resolveColor(c))];
7933
+ }
7934
+ const fontFamily = readVariable("--font-family-sans") || inheritedFont || "system-ui, -apple-system, 'Segoe UI', sans-serif";
7935
+ return {
7936
+ palette: colors,
7937
+ text,
7938
+ textMuted,
7939
+ grid: mix(background, border, .75),
7940
+ axis: border,
7941
+ background,
7942
+ surface: background,
7943
+ primary: colors[0],
7944
+ fontFamily,
7945
+ fontSize: 11,
7946
+ resolve
7947
+ };
7948
+ };
7949
+ //#endregion
7950
+ //#region ../charts/src/engine/viewport.ts
7951
+ /**
7952
+ * Keeps a range inside `bounds` with a span between `minSpan` and the
7953
+ * span of the bounds (shifts it back instead of shrinking it).
7954
+ */
7955
+ var clampRange = (range, bounds, minSpan) => {
7956
+ const maxSpan = bounds[1] - bounds[0];
7957
+ const span = Math.min(Math.max(range[1] - range[0], minSpan), maxSpan);
7958
+ let a = (range[0] + range[1]) / 2 - span / 2;
7959
+ let b = a + span;
7960
+ if (a < bounds[0]) {
7961
+ a = bounds[0];
7962
+ b = a + span;
7963
+ }
7964
+ if (b > bounds[1]) {
7965
+ b = bounds[1];
7966
+ a = b - span;
7967
+ }
7968
+ return [a, b];
7969
+ };
7970
+ /** Scales a range around `anchor` (factor < 1 zooms in) */
7971
+ var zoomRange = (range, anchor, factor) => [anchor - (anchor - range[0]) * factor, anchor + (range[1] - anchor) * factor];
7972
+ var panRange = (range, delta) => [range[0] + delta, range[1] + delta];
7973
+ var sameRange = (a, b, epsilon = 1e-9) => {
7974
+ const span = Math.max(Math.abs(b[1] - b[0]), 1e-300);
7975
+ return Math.abs(a[0] - b[0]) <= span * epsilon && Math.abs(a[1] - b[1]) <= span * epsilon;
7976
+ };
7977
+ //#endregion
7978
+ //#region ../charts/src/engine/controller.ts
7979
+ var copyView = (v) => ({
7980
+ x: [v.x[0], v.x[1]],
7981
+ y: [v.y[0], v.y[1]]
7982
+ });
7983
+ var TAP_SLOP = 6;
7984
+ var TOUCH_SLOP = 10;
7985
+ var DOUBLE_TAP_MS = 320;
7986
+ var LEGEND_ROW = 20;
7987
+ var createChartController = (config) => {
7988
+ let options = config.options;
7989
+ let themeInput = config.theme;
7990
+ let theme = createTheme(themeInput, options.palette);
7991
+ const cache = /* @__PURE__ */ new Map();
7992
+ const hidden = /* @__PURE__ */ new Set();
7993
+ const listeners = {};
7994
+ let model;
7995
+ let view = {
7996
+ x: [0, 1],
7997
+ y: [0, 1]
7998
+ };
7999
+ let zoomed = false;
8000
+ let width = 0;
8001
+ let height = 0;
8002
+ let annotations = [];
8003
+ let scene = null;
8004
+ let sceneDirty = true;
8005
+ let lastPlot = "";
8006
+ let destroyed = false;
8007
+ let hover = null;
8008
+ const pointers = /* @__PURE__ */ new Map();
8009
+ let gesture = null;
8010
+ let lastTap = {
8011
+ time: 0,
8012
+ x: 0,
8013
+ y: 0
8014
+ };
8015
+ const emit = (type, event) => {
8016
+ listeners[type]?.forEach((listener) => listener(event));
8017
+ };
8018
+ const invalidate = () => {
8019
+ sceneDirty = true;
8020
+ if (!destroyed) config.onInvalidate?.();
8021
+ };
8022
+ const interaction = () => {
8023
+ const value = options.interaction;
8024
+ if (value === false) return null;
8025
+ const o = typeof value === "object" ? value : {};
8026
+ return {
8027
+ pan: o.pan ?? true,
8028
+ dragPoints: o.dragPoints ?? false
8029
+ };
8030
+ };
8031
+ const measure = (text, size = theme.fontSize, weight = 400) => config.measureText(text, font(theme, size, weight));
8032
+ const rebuild = () => {
8033
+ model = buildModel(options, theme, hidden, cache);
8034
+ const { base, minSpan } = model;
8035
+ if (!zoomed) view = copyView(base);
8036
+ else {
8037
+ view = {
8038
+ x: model.zoom.x ? clampRange(view.x, base.x, minSpan.x) : [...base.x],
8039
+ y: model.zoom.y ? clampRange(view.y, base.y, minSpan.y) : [...base.y]
8040
+ };
8041
+ zoomed = !sameRange(view.x, base.x) || !sameRange(view.y, base.y);
8042
+ }
8043
+ annotations = resolveAnnotations(options.annotations, theme);
8044
+ if (hover) {
8045
+ if (!hover.event.items.every((it) => model.series[it.seriesIndex] && !model.series[it.seriesIndex].hidden && it.index < model.series[it.seriesIndex].cols.count)) setHover(null);
8046
+ }
8047
+ invalidate();
8048
+ };
8049
+ const legendLayout = () => {
8050
+ const option = options.legend;
8051
+ const named = options.series.filter((s) => s.name).length;
8052
+ if (!(option === void 0 ? named > 1 : !!option)) return null;
8053
+ const cfg = typeof option === "object" ? option : {};
8054
+ const position = cfg.position === "bottom" ? "bottom" : "top";
8055
+ const entries = [];
8056
+ let x = 4;
8057
+ let row = 0;
8058
+ for (const s of model.series) {
8059
+ const w = 14 + measure(s.name, 12) + 8;
8060
+ if (x + w > width - 4 && x > 4) {
8061
+ x = 4;
8062
+ row++;
8063
+ }
8064
+ entries.push({
8065
+ id: s.id,
8066
+ name: s.name,
8067
+ color: s.colorCss,
8068
+ shape: s.type === "scatter" ? "dot" : s.type === "line" ? "line" : "square",
8069
+ hidden: s.hidden,
8070
+ box: {
8071
+ x,
8072
+ y: row * LEGEND_ROW,
8073
+ width: w,
8074
+ height: LEGEND_ROW
8075
+ }
8076
+ });
8077
+ x += w + 10;
8078
+ }
8079
+ const legendHeight = (row + 1) * LEGEND_ROW + 6;
8080
+ if (position === "bottom") for (const e of entries) e.box.y += height - legendHeight + 6;
8081
+ return {
8082
+ entries,
8083
+ position,
8084
+ toggle: cfg.toggle ?? true,
8085
+ height: legendHeight
8086
+ };
8087
+ };
8088
+ const tooltipLayout = (event, anchorX, anchorY) => {
8089
+ const tooltip = options.tooltip;
8090
+ if (tooltip === false) return null;
8091
+ const custom = typeof tooltip === "object" ? tooltip.render : void 0;
8092
+ let text = null;
8093
+ if (custom) {
8094
+ const result = custom(event);
8095
+ if (result === null || result === "") return null;
8096
+ if (typeof result === "string") text = result.split("\n");
8097
+ }
8098
+ const content = tooltipContent(model, event, scene?.layout.yTicks ?? null);
8099
+ const lineHeight = 18;
8100
+ const padding = 8;
8101
+ let w = 0;
8102
+ let lines;
8103
+ if (text) {
8104
+ for (const line of text) w = Math.max(w, measure(line, 12));
8105
+ lines = text.length;
8106
+ } else {
8107
+ w = measure(content.title, 12, 600) + (content.titleColor ? 14 : 0);
8108
+ for (const row of content.rows) w = Math.max(w, (row.color ? 14 : 0) + measure(row.name, 12) + 16 + measure(row.value, 12, 600));
8109
+ lines = 1 + content.rows.length;
8110
+ }
8111
+ const boxW = Math.ceil(Math.max(w, 96) + 16 + 4);
8112
+ const boxH = lines * lineHeight + 16;
8113
+ let left = anchorX + 14;
8114
+ if (left + boxW > width - 4) left = anchorX - 14 - boxW;
8115
+ left = Math.max(4, Math.min(left, width - boxW - 4));
8116
+ const top = Math.max(4, Math.min(anchorY - boxH / 2, height - boxH - 4));
8117
+ return {
8118
+ content,
8119
+ text,
8120
+ box: {
8121
+ x: left,
8122
+ y: top,
8123
+ width: boxW,
8124
+ height: boxH
8125
+ },
8126
+ lineHeight,
8127
+ padding
8128
+ };
8129
+ };
8130
+ const computeScene = () => {
8131
+ if (width <= 0 || height <= 0) return null;
8132
+ const legend = legendLayout();
8133
+ const legendTop = legend?.position === "top" ? legend.height : 0;
8134
+ const layout = layoutChart({
8135
+ model,
8136
+ view,
8137
+ theme,
8138
+ width,
8139
+ height: height - (legend?.height ?? 0),
8140
+ padding: options.padding,
8141
+ top: legendTop,
8142
+ measure: (text) => measure(text)
8143
+ });
8144
+ const labels = collectPointLabels(model, view, layout.scales);
8145
+ const occupied = [];
8146
+ const labelHeight = theme.fontSize + 4;
8147
+ for (const a of annotations) {
8148
+ if (a.type === "text" && a.text) {
8149
+ occupied.push(textBox(a, layout.scales, measure(a.text, theme.fontSize, a.weight), labelHeight));
8150
+ continue;
8151
+ }
8152
+ if (a.type !== "rect" || !a.label) continue;
8153
+ const s = layout.scales;
8154
+ const x0 = a.x0 === void 0 ? layout.plot.x : s.xToPx(a.x0);
8155
+ const x1 = a.x1 === void 0 ? layout.plot.x + layout.plot.width : s.xToPx(a.x1);
8156
+ const y0 = a.y0 === void 0 ? layout.plot.y + layout.plot.height : s.yToPx(a.y0);
8157
+ const y1 = a.y1 === void 0 ? layout.plot.y : s.yToPx(a.y1);
8158
+ const w = measure(a.label, theme.fontSize + 1, 600);
8159
+ const left = Math.min(x0, x1);
8160
+ const right = Math.max(x0, x1);
8161
+ const top = Math.min(y0, y1);
8162
+ const bottom = Math.max(y0, y1);
8163
+ const pos = a.labelPosition;
8164
+ occupied.push({
8165
+ x: pos.endsWith("left") ? left + 10 : pos.endsWith("right") ? right - 10 - w : (left + right - w) / 2,
8166
+ y: pos.startsWith("top") ? top + 10 : pos.startsWith("bottom") ? bottom - 10 - labelHeight : (top + bottom - labelHeight) / 2,
8167
+ width: w,
8168
+ height: labelHeight
8169
+ });
8170
+ }
8171
+ const pointLabels = placeLabels(labels, layout.plot, (t) => measure(t), labelHeight - 2, occupied);
8172
+ const next = {
8173
+ width,
8174
+ height,
8175
+ theme,
8176
+ model,
8177
+ view: copyView(view),
8178
+ layout,
8179
+ annotations,
8180
+ pointLabels,
8181
+ legend,
8182
+ hover: null,
8183
+ dragging: null
8184
+ };
8185
+ scene = next;
8186
+ if (hover) {
8187
+ const crosshair = showsCrosshair(model, hover.event, options.crosshair);
8188
+ const cx = layout.scales.xToPx(hover.event.items[0].x);
8189
+ next.hover = {
8190
+ event: hover.event,
8191
+ marks: hoverMarks(model, layout.scales, hover.event),
8192
+ crosshairX: crosshair && cx >= layout.plot.x && cx <= layout.plot.x + layout.plot.width ? cx : null,
8193
+ tooltip: gesture?.kind === "pan" || gesture?.kind === "point" ? null : tooltipLayout(hover.event, hover.x, hover.y)
8194
+ };
8195
+ }
8196
+ if (gesture?.kind === "point") {
8197
+ const s = model.series[gesture.item.seriesIndex];
8198
+ next.dragging = {
8199
+ x: gesture.x,
8200
+ y: gesture.y,
8201
+ color: gesture.item.color,
8202
+ size: (s ? dotSize(s, gesture.item.index) : 8) + 6
8203
+ };
8204
+ }
8205
+ const rect = layout.plot;
8206
+ const key = `${rect.x},${rect.y},${rect.width},${rect.height}`;
8207
+ if (key !== lastPlot) {
8208
+ lastPlot = key;
8209
+ emit("layout", { ...rect });
8210
+ }
8211
+ return next;
8212
+ };
8213
+ const getScene = () => {
8214
+ if (sceneDirty || !scene) {
8215
+ sceneDirty = false;
8216
+ scene = computeScene();
8217
+ }
8218
+ return scene;
8219
+ };
8220
+ const scales = () => getScene()?.layout.scales ?? null;
8221
+ const setHover = (next) => {
8222
+ const changed = !sameHover(hover?.event ?? null, next?.event ?? null);
8223
+ hover = next;
8224
+ invalidate();
8225
+ if (changed) emit("hover", next ? next.event : null);
8226
+ };
8227
+ const hitAt = (x, y, touch) => {
8228
+ const sc = scales();
8229
+ return sc ? hitTest(model, sc, scene?.layout.xTicks ?? null, x, y, touch ? 8 : 0) : null;
8230
+ };
8231
+ const inPlot = (x, y) => {
8232
+ const p = scales()?.plot;
8233
+ return !!p && x >= p.x && x <= p.x + p.width && y >= p.y && y <= p.y + p.height;
8234
+ };
8235
+ const dataAt = (x, y) => {
8236
+ const sc = scales();
8237
+ if (!sc) return null;
8238
+ const { plot } = sc;
8239
+ const cx = Math.max(plot.x, Math.min(plot.x + plot.width, x));
8240
+ const cy = Math.max(plot.y, Math.min(plot.y + plot.height, y));
8241
+ return {
8242
+ x: sc.pxToX(cx),
8243
+ y: sc.pxToY(cy)
8244
+ };
8245
+ };
8246
+ const setViewInternal = (next, notify) => {
8247
+ const { base, minSpan } = model;
8248
+ view = {
8249
+ x: clampRange(next.x, base.x, minSpan.x),
8250
+ y: clampRange(next.y, base.y, minSpan.y)
8251
+ };
8252
+ zoomed = !sameRange(view.x, base.x) || !sameRange(view.y, base.y);
8253
+ if (notify) emit("zoom", copyView(view));
8254
+ invalidate();
8255
+ };
8256
+ const zoomAt = (x, y, factor) => {
8257
+ const sc = scales();
8258
+ if (!sc || !model.zoom.x && !model.zoom.y) return;
8259
+ const next = copyView(view);
8260
+ if (model.zoom.x) next.x = zoomRange(view.x, sc.pxToX(x), factor);
8261
+ if (model.zoom.y) next.y = zoomRange(view.y, sc.pxToY(y), factor);
8262
+ setViewInternal(next, true);
8263
+ };
8264
+ const resetZoom = () => {
8265
+ if (!zoomed) return;
8266
+ setViewInternal(copyView(model.base), true);
8267
+ };
8268
+ const legendAt = (x, y) => getScene()?.legend?.entries.find((e) => x >= e.box.x && x <= e.box.x + e.box.width && y >= e.box.y && y <= e.box.y + e.box.height) ?? null;
8269
+ const toggleSeries = (id) => {
8270
+ if (hidden.has(id)) hidden.delete(id);
8271
+ else hidden.add(id);
8272
+ rebuild();
8273
+ };
8274
+ const startPinch = () => {
8275
+ const [a, b] = [...pointers.values()];
8276
+ gesture = {
8277
+ kind: "pinch",
8278
+ view: copyView(view),
8279
+ distance: Math.max(1, Math.hypot(a.x - b.x, a.y - b.y)),
8280
+ midX: (a.x + b.x) / 2,
8281
+ midY: (a.y + b.y) / 2
8282
+ };
8283
+ setHover(null);
8284
+ };
8285
+ const pointerDown = (x, y, o = {}) => {
8286
+ if (destroyed) return;
8287
+ const id = o.id ?? 0;
8288
+ const touch = !!o.touch;
8289
+ pointers.set(id, {
8290
+ x,
8291
+ y,
8292
+ startX: x,
8293
+ startY: y,
8294
+ touch,
8295
+ moved: false
8296
+ });
8297
+ const it = interaction();
8298
+ if (pointers.size === 2) {
8299
+ if (it && (model.zoom.x || model.zoom.y) && gesture?.kind !== "point") startPinch();
8300
+ return;
8301
+ }
8302
+ if (pointers.size > 2 || !it) {
8303
+ if (!it && touch) {
8304
+ const event = hitAt(x, y, true);
8305
+ setHover(event ? {
8306
+ event,
8307
+ x,
8308
+ y
8309
+ } : null);
8310
+ }
8311
+ return;
8312
+ }
8313
+ if (it.dragPoints) {
8314
+ const item = hitAt(x, y, touch)?.items.find((i) => model.series[i.seriesIndex].type === "scatter");
8315
+ if (item) {
8316
+ gesture = {
8317
+ kind: "point",
8318
+ item,
8319
+ x,
8320
+ y
8321
+ };
8322
+ return;
8323
+ }
8324
+ }
8325
+ if (zoomed && it.pan && inPlot(x, y)) {
8326
+ gesture = {
8327
+ kind: "pan",
8328
+ view: copyView(view),
8329
+ x,
8330
+ y
8331
+ };
8332
+ return;
8333
+ }
8334
+ gesture = null;
8335
+ if (touch) {
8336
+ const event = hitAt(x, y, true);
8337
+ setHover(event ? {
8338
+ event,
8339
+ x,
8340
+ y
8341
+ } : null);
8342
+ }
8343
+ };
8344
+ const pointerMove = (x, y, o = {}) => {
8345
+ if (destroyed) return;
8346
+ const id = o.id ?? 0;
8347
+ const p = pointers.get(id);
8348
+ if (p) {
8349
+ p.x = x;
8350
+ p.y = y;
8351
+ if (!p.moved && Math.hypot(x - p.startX, y - p.startY) > (p.touch ? TOUCH_SLOP : TAP_SLOP)) p.moved = true;
8352
+ }
8353
+ if (gesture?.kind === "pinch" && pointers.size >= 2) {
8354
+ const [a, b] = [...pointers.values()];
8355
+ const distance = Math.max(1, Math.hypot(a.x - b.x, a.y - b.y));
8356
+ const midX = (a.x + b.x) / 2;
8357
+ const midY = (a.y + b.y) / 2;
8358
+ const sc = scales();
8359
+ if (!sc) return;
8360
+ const start = createScales(sc.plot, gesture.view, model.x.reverse, model.y.reverse);
8361
+ const factor = gesture.distance / distance;
8362
+ const next = copyView(gesture.view);
8363
+ if (model.zoom.x) {
8364
+ next.x = zoomRange(gesture.view.x, start.pxToX(gesture.midX), factor);
8365
+ const shift = (midX - gesture.midX) * start.xPerPx * factor;
8366
+ next.x = panRange(next.x, model.x.reverse ? shift : -shift);
8367
+ }
8368
+ if (model.zoom.y) {
8369
+ next.y = zoomRange(gesture.view.y, start.pxToY(gesture.midY), factor);
8370
+ const shift = (midY - gesture.midY) * start.yPerPx * factor;
8371
+ next.y = panRange(next.y, model.y.reverse ? -shift : shift);
8372
+ }
8373
+ setViewInternal(next, true);
8374
+ return;
8375
+ }
8376
+ if (gesture?.kind === "point" && p) {
8377
+ if (!p.moved) return;
8378
+ gesture.x = x;
8379
+ gesture.y = y;
8380
+ const at = dataAt(x, y);
8381
+ invalidate();
8382
+ if (at) emit("drag", {
8383
+ item: gesture.item,
8384
+ x: at.x,
8385
+ y: at.y
8386
+ });
8387
+ return;
8388
+ }
8389
+ if (gesture?.kind === "pan" && p) {
8390
+ if (!p.moved) return;
8391
+ const sc = scales();
8392
+ if (!sc) return;
8393
+ const dx = x - gesture.x;
8394
+ const dy = y - gesture.y;
8395
+ const next = copyView(gesture.view);
8396
+ if (model.zoom.x) next.x = panRange(gesture.view.x, -dx * sc.xPerPx * (model.x.reverse ? -1 : 1));
8397
+ if (model.zoom.y) next.y = panRange(gesture.view.y, dy * sc.yPerPx * (model.y.reverse ? -1 : 1));
8398
+ setViewInternal(next, true);
8399
+ return;
8400
+ }
8401
+ if (pointers.size > 1) return;
8402
+ if (!p || p.touch || !o.touch) {
8403
+ const event = hitAt(x, y, !!p?.touch || !!o.touch);
8404
+ if (event || !p?.touch) setHover(event ? {
8405
+ event,
8406
+ x,
8407
+ y
8408
+ } : null);
8409
+ }
8410
+ };
8411
+ const pointerUp = (x, y, o = {}) => {
8412
+ if (destroyed) return;
8413
+ const id = o.id ?? 0;
8414
+ const p = pointers.get(id);
8415
+ pointers.delete(id);
8416
+ const current = gesture;
8417
+ if (current?.kind === "pinch") {
8418
+ if (pointers.size < 2) gesture = null;
8419
+ return;
8420
+ }
8421
+ gesture = null;
8422
+ if (!p) return;
8423
+ if (current?.kind === "point") {
8424
+ if (p.moved) {
8425
+ const at = dataAt(x, y);
8426
+ invalidate();
8427
+ if (at) emit("drop", {
8428
+ item: current.item,
8429
+ x: at.x,
8430
+ y: at.y
8431
+ });
8432
+ return;
8433
+ }
8434
+ } else if (current?.kind === "pan" && p.moved) {
8435
+ invalidate();
8436
+ return;
8437
+ }
8438
+ if (p.moved) {
8439
+ if (p.touch) invalidate();
8440
+ return;
8441
+ }
8442
+ const now = Date.now();
8443
+ if (p.touch && now - lastTap.time < DOUBLE_TAP_MS && Math.hypot(x - lastTap.x, y - lastTap.y) < 24 && zoomed) {
8444
+ lastTap = {
8445
+ time: 0,
8446
+ x,
8447
+ y
8448
+ };
8449
+ resetZoom();
8450
+ return;
8451
+ }
8452
+ lastTap = {
8453
+ time: now,
8454
+ x,
8455
+ y
8456
+ };
8457
+ const legend = legendAt(x, y);
8458
+ if (legend) {
8459
+ if (getScene()?.legend?.toggle) toggleSeries(legend.id);
8460
+ return;
8461
+ }
8462
+ const hit = hitAt(x, y, p.touch);
8463
+ if (hit) {
8464
+ if (p.touch) setHover({
8465
+ event: hit,
8466
+ x,
8467
+ y
8468
+ });
8469
+ emit("click", hit);
8470
+ return;
8471
+ }
8472
+ if (p.touch) setHover(null);
8473
+ if (inPlot(x, y)) {
8474
+ const at = dataAt(x, y);
8475
+ if (at) emit("plotClick", at);
8476
+ }
8477
+ };
8478
+ const pointerCancel = (o = {}) => {
8479
+ pointers.delete(o.id ?? 0);
8480
+ if (gesture?.kind === "point" || pointers.size < 2) gesture = null;
8481
+ invalidate();
8482
+ };
8483
+ model = buildModel(options, theme, hidden, cache);
8484
+ rebuild();
8485
+ return {
8486
+ setOptions(next) {
8487
+ if (destroyed) return;
8488
+ const paletteChanged = (next.palette ?? []).join() !== (options.palette ?? []).join();
8489
+ options = next;
8490
+ if (paletteChanged) theme = createTheme(themeInput, options.palette);
8491
+ rebuild();
8492
+ },
8493
+ setTheme(next) {
8494
+ if (destroyed) return;
8495
+ themeInput = next;
8496
+ theme = createTheme(themeInput, options.palette);
8497
+ rebuild();
8498
+ },
8499
+ setSize(w, h) {
8500
+ if (w === width && h === height) return;
8501
+ width = Math.max(0, w);
8502
+ height = Math.max(0, h);
8503
+ invalidate();
8504
+ },
8505
+ getScene,
8506
+ pointerDown,
8507
+ pointerMove,
8508
+ pointerUp,
8509
+ pointerCancel,
8510
+ pointerLeave() {
8511
+ if (!gesture && hover) setHover(null);
8512
+ },
8513
+ zoomAt,
8514
+ resetZoom,
8515
+ getView: () => copyView(view),
8516
+ setView(next) {
8517
+ if (destroyed) return;
8518
+ setViewInternal({
8519
+ x: next.x ?? view.x,
8520
+ y: next.y ?? view.y
8521
+ }, false);
8522
+ },
8523
+ toggleSeries,
8524
+ clearHover() {
8525
+ if (hover) setHover(null);
8526
+ },
8527
+ getPlotRect() {
8528
+ const p = getScene()?.layout.plot;
8529
+ return p ? { ...p } : null;
8530
+ },
8531
+ toPixel(x, y) {
8532
+ const sc = scales();
8533
+ return sc ? {
8534
+ x: sc.xToPx(x),
8535
+ y: sc.yToPx(y)
8536
+ } : null;
8537
+ },
8538
+ fromPixel(x, y) {
8539
+ const sc = scales();
8540
+ return sc ? {
8541
+ x: sc.pxToX(x),
8542
+ y: sc.pxToY(y)
8543
+ } : null;
8544
+ },
8545
+ on(type, listener) {
8546
+ let set = listeners[type];
8547
+ if (!set) {
8548
+ set = /* @__PURE__ */ new Set();
8549
+ listeners[type] = set;
8550
+ }
8551
+ set.add(listener);
8552
+ return () => {
8553
+ set.delete(listener);
8554
+ };
8555
+ },
8556
+ destroy() {
8557
+ destroyed = true;
8558
+ pointers.clear();
8559
+ for (const key of Object.keys(listeners)) delete listeners[key];
8560
+ }
8561
+ };
8562
+ };
8563
+ //#endregion
8564
+ //#region ../charts/src/engine/renderers/types.ts
8565
+ /** Missing values are written as this sentinel (NaN is unreliable in shaders) */
8566
+ var GAP = 3e38;
8567
+ //#endregion
8568
+ //#region ../charts/src/engine/items.ts
8569
+ var rel = (value, origin) => Number.isFinite(value) ? value - origin : GAP;
8570
+ var points = (x, y, count, o) => {
8571
+ const out = new Float32Array(count * 2);
8572
+ for (let i = 0; i < count; i++) {
8573
+ out[i * 2] = rel(x[i], o.x);
8574
+ out[i * 2 + 1] = Number.isFinite(y[i]) ? y[i] - o.y : GAP;
8575
+ }
8576
+ return out;
8577
+ };
8578
+ var DRAW_ORDER = {
8579
+ area: 0,
8580
+ bar: 1,
8581
+ line: 2,
8582
+ scatter: 3
8583
+ };
8584
+ /** Render items of the visible series, back to front */
8585
+ var buildItems = (model, origin, version) => {
8586
+ const items = [];
8587
+ /** Outlines of the areas are drawn with the lines, above the bars */
8588
+ const outlines = [];
8589
+ const ordered = model.series.filter((s) => !s.hidden).sort((a, b) => DRAW_ORDER[a.type] - DRAW_ORDER[b.type] || a.index - b.index);
8590
+ for (const s of ordered) {
8591
+ const { x, y, count, sorted } = s.cols;
8592
+ if ((s.type === "line" || s.type === "scatter") && outlines.length) items.push(...outlines.splice(0));
8593
+ switch (s.type) {
8594
+ case "line":
8595
+ case "area": {
8596
+ const pts = points(x, y, count, origin);
8597
+ if (s.type === "area") items.push({
8598
+ kind: "area",
8599
+ key: `${s.key}:area`,
8600
+ version,
8601
+ color: s.color,
8602
+ points: pts,
8603
+ count,
8604
+ baseline: model.baseline - origin.y,
8605
+ opacity: s.opacity,
8606
+ sorted
8607
+ });
8608
+ (s.type === "area" ? outlines : items).push({
8609
+ kind: "line",
8610
+ key: `${s.key}:line`,
8611
+ version,
8612
+ color: s.color,
8613
+ points: pts,
8614
+ count,
8615
+ width: s.lineWidth,
8616
+ sorted
8617
+ });
8618
+ break;
8619
+ }
8620
+ case "bar": {
8621
+ const base = s.barBase ?? new Float64Array(count);
8622
+ const top = s.barTop ?? y;
8623
+ const instances = new Float32Array(count * 3);
8624
+ for (let i = 0; i < count; i++) {
8625
+ const valid = Number.isFinite(top[i]) && Number.isFinite(base[i]);
8626
+ instances[i * 3] = rel(x[i] + s.barOffset, origin.x);
8627
+ instances[i * 3 + 1] = valid ? base[i] - origin.y : GAP;
8628
+ instances[i * 3 + 2] = valid ? top[i] - origin.y : GAP;
8629
+ }
8630
+ items.push({
8631
+ kind: "bar",
8632
+ key: `${s.key}:bar`,
8633
+ version,
8634
+ color: s.color,
8635
+ instances,
8636
+ count,
8637
+ halfWidth: s.barHalfWidth,
8638
+ sorted,
8639
+ radius: model.series.some((o) => o !== s && !o.hidden && o.type === "bar" && o.barOffset === s.barOffset) ? 0 : 3
8640
+ });
8641
+ break;
8642
+ }
8643
+ default: {
8644
+ const buffer = /* @__PURE__ */ new ArrayBuffer(count * 16);
8645
+ const f = new Float32Array(buffer);
8646
+ const u = new Uint32Array(buffer);
8647
+ const seriesColor = packColor(s.color);
8648
+ const sizes = s.cols.size;
8649
+ for (let i = 0; i < count; i++) {
8650
+ const valid = Number.isFinite(y[i]) && Number.isFinite(x[i]);
8651
+ f[i * 4] = valid ? x[i] - origin.x : GAP;
8652
+ f[i * 4 + 1] = valid ? y[i] - origin.y : GAP;
8653
+ const size = sizes ? sizes[i] : NaN;
8654
+ f[i * 4 + 2] = Number.isFinite(size) && size > 0 ? size : s.pointSize;
8655
+ const pc = s.pointColors?.[i];
8656
+ u[i * 4 + 3] = pc ? packColor(pc) : seriesColor;
8657
+ }
8658
+ items.push({
8659
+ kind: "scatter",
8660
+ key: `${s.key}:scatter`,
8661
+ version,
8662
+ color: s.color,
8663
+ instances: buffer,
8664
+ count,
8665
+ opacity: s.opacity,
8666
+ stroke: count <= 5e3 ? 1.25 : 0
8667
+ });
8668
+ break;
8669
+ }
8670
+ }
8671
+ }
8672
+ items.push(...outlines);
8673
+ return items;
8674
+ };
8675
+ var rgba = (c, alpha) => `rgba(${Math.round(c[0] * 255)},${Math.round(c[1] * 255)},${Math.round(c[2] * 255)},${c[3] * alpha})`;
8676
+ var unpack = (packed) => [
8677
+ (packed & 255) / 255,
8678
+ (packed >>> 8 & 255) / 255,
8679
+ (packed >>> 16 & 255) / 255,
8680
+ (packed >>> 24 & 255) / 255
8681
+ ];
8682
+ var isGap = (v) => !Number.isFinite(v) || Math.abs(v) >= 15e37;
8683
+ /** First point index whose relative x is >= value (sorted, interleaved) */
8684
+ var lowerBoundX = (points, count, value) => {
8685
+ let lo = 0;
8686
+ let hi = count;
8687
+ while (lo < hi) {
8688
+ const mid = lo + hi >>> 1;
8689
+ if (points[mid * 2] < value) lo = mid + 1;
8690
+ else hi = mid;
8691
+ }
8692
+ return lo;
8693
+ };
8694
+ /**
8695
+ * Data layer drawn with any 2D context (browser canvases, mini-program
8696
+ * canvases, OffscreenCanvas). `scratchCanvas` creates the canvas used to
8697
+ * rasterize very large scatter sets; without it they are drawn as one
8698
+ * square per occupied pixel cell.
8699
+ */
8700
+ var createCanvas2dPainter = (ctx, scratchCanvas) => {
8701
+ let scratch = null;
8702
+ const mapper = (frame) => {
8703
+ const { xScale, xOffset, yScale, yOffset } = frame.transform;
8704
+ const w = frame.width;
8705
+ const h = frame.height;
8706
+ return {
8707
+ px: (x) => ((x * xScale + xOffset) * .5 + .5) * w,
8708
+ py: (y) => (1 - ((y * yScale + yOffset) * .5 + .5)) * h,
8709
+ /** Visible relative x range */
8710
+ xRange: () => {
8711
+ const a = (-1 - xOffset) / xScale;
8712
+ const b = (1 - xOffset) / xScale;
8713
+ return a < b ? [a, b] : [b, a];
8714
+ }
8715
+ };
8716
+ };
8717
+ /** Points actually drawn: decimated when there are many per pixel */
8718
+ const visiblePoints = (item, frame) => {
8719
+ if (!item.sorted || item.count <= frame.width * 2) return {
8720
+ points: item.points,
8721
+ length: item.count
8722
+ };
8723
+ const m = mapper(frame);
8724
+ const [x0, x1] = m.xRange();
8725
+ const start = Math.max(0, lowerBoundX(item.points, item.count, x0) - 1);
8726
+ const end = Math.min(item.count, lowerBoundX(item.points, item.count, x1) + 1);
8727
+ const result = decimateMinMax(item.points, start, end, m.px, GAP * .5);
8728
+ return {
8729
+ points: result.points,
8730
+ length: result.length
8731
+ };
8732
+ };
8733
+ const drawLine = (item, frame) => {
8734
+ const m = mapper(frame);
8735
+ const { points, length } = visiblePoints(item, frame);
8736
+ ctx.beginPath();
8737
+ let pen = false;
8738
+ for (let i = 0; i < length; i++) {
8739
+ const x = points[i * 2];
8740
+ const y = points[i * 2 + 1];
8741
+ if (isGap(x) || isGap(y)) {
8742
+ pen = false;
8743
+ continue;
8744
+ }
8745
+ if (pen) ctx.lineTo(m.px(x), m.py(y));
8746
+ else ctx.moveTo(m.px(x), m.py(y));
8747
+ pen = true;
8748
+ }
8749
+ ctx.lineWidth = item.width * frame.dpr;
8750
+ ctx.lineJoin = "round";
8751
+ ctx.lineCap = "round";
8752
+ ctx.strokeStyle = rgba(item.color, 1);
8753
+ ctx.stroke();
8754
+ };
8755
+ const drawArea = (item, frame) => {
8756
+ const m = mapper(frame);
8757
+ const { points, length } = visiblePoints(item, frame);
8758
+ const base = m.py(item.baseline);
8759
+ const gradient = ctx.createLinearGradient(0, 0, 0, base);
8760
+ gradient.addColorStop(0, rgba(item.color, item.opacity));
8761
+ gradient.addColorStop(1, rgba(item.color, item.opacity * .3));
8762
+ ctx.fillStyle = gradient;
8763
+ ctx.beginPath();
8764
+ let runStart = -1;
8765
+ let lastX = 0;
8766
+ const close = () => {
8767
+ if (runStart < 0) return;
8768
+ ctx.lineTo(lastX, base);
8769
+ ctx.closePath();
8770
+ runStart = -1;
8771
+ };
8772
+ for (let i = 0; i < length; i++) {
8773
+ const x = points[i * 2];
8774
+ const y = points[i * 2 + 1];
8775
+ if (isGap(x) || isGap(y)) {
8776
+ close();
8777
+ continue;
8778
+ }
8779
+ const px = m.px(x);
8780
+ if (runStart < 0) {
8781
+ runStart = i;
8782
+ ctx.moveTo(px, base);
8783
+ }
8784
+ ctx.lineTo(px, m.py(y));
8785
+ lastX = px;
8786
+ }
8787
+ close();
8788
+ ctx.fill();
8789
+ };
8790
+ const drawBars = (item, frame) => {
8791
+ const m = mapper(frame);
8792
+ const half = Math.max(Math.abs(item.halfWidth * frame.transform.xScale) * .5 * frame.width, .5);
8793
+ const r = item.radius * frame.dpr;
8794
+ ctx.fillStyle = rgba(item.color, 1);
8795
+ ctx.beginPath();
8796
+ const v = item.instances;
8797
+ for (let i = 0; i < item.count; i++) {
8798
+ const x = v[i * 3];
8799
+ const y0 = v[i * 3 + 1];
8800
+ const y1 = v[i * 3 + 2];
8801
+ if (isGap(x) || isGap(y0) || isGap(y1)) continue;
8802
+ const cx = m.px(x);
8803
+ const a = m.py(y0);
8804
+ const b = m.py(y1);
8805
+ const top = Math.min(a, b);
8806
+ const height = Math.abs(a - b);
8807
+ const radius = Math.min(r, half, height / 2);
8808
+ if (radius > .5 && typeof ctx.roundRect === "function") ctx.roundRect(cx - half, top, half * 2, height, radius);
8809
+ else ctx.rect(cx - half, top, half * 2, height);
8810
+ }
8811
+ ctx.fill();
8812
+ };
8813
+ /** One square per occupied cell (the last point of a cell wins, like the GPU) */
8814
+ const drawScatterCells = (item, frame) => {
8815
+ const m = mapper(frame);
8816
+ const w = frame.width;
8817
+ const h = frame.height;
8818
+ const f = new Float32Array(item.instances, 0, item.count * 4);
8819
+ const u = new Uint32Array(item.instances, 0, item.count * 4);
8820
+ let cell = 0;
8821
+ for (let i = 0; i < Math.min(item.count, 64); i++) cell = Math.max(cell, f[i * 4 + 2]);
8822
+ cell = Math.max(1, Math.round((cell || 2) * frame.dpr * .8));
8823
+ const cols = Math.ceil(w / cell);
8824
+ const rows = Math.ceil(h / cell);
8825
+ const owner = new Int32Array(cols * rows).fill(-1);
8826
+ for (let i = 0; i < item.count; i++) {
8827
+ const x = f[i * 4];
8828
+ const y = f[i * 4 + 1];
8829
+ if (isGap(x) || isGap(y) || !(f[i * 4 + 2] > 0)) continue;
8830
+ const cx = Math.floor(m.px(x) / cell);
8831
+ const cy = Math.floor(m.py(y) / cell);
8832
+ if (cx < 0 || cy < 0 || cx >= cols || cy >= rows) continue;
8833
+ owner[cy * cols + cx] = i;
8834
+ }
8835
+ const groups = /* @__PURE__ */ new Map();
8836
+ for (let c = 0; c < owner.length; c++) {
8837
+ const i = owner[c];
8838
+ if (i < 0) continue;
8839
+ const packed = u[i * 4 + 3];
8840
+ let list = groups.get(packed);
8841
+ if (!list) groups.set(packed, list = []);
8842
+ list.push(c);
8843
+ }
8844
+ for (const [packed, cells] of groups) {
8845
+ ctx.fillStyle = rgba(unpack(packed), Math.max(item.opacity, .6));
8846
+ for (const c of cells) ctx.fillRect(c % cols * cell, Math.floor(c / cols) * cell, cell, cell);
8847
+ }
8848
+ };
8849
+ const drawScatterPixels = (item, frame) => {
8850
+ const m = mapper(frame);
8851
+ const w = frame.width;
8852
+ const h = frame.height;
8853
+ scratch ??= scratchCanvas?.() ?? null;
8854
+ if (!scratch) {
8855
+ drawScatterCells(item, frame);
8856
+ return;
8857
+ }
8858
+ scratch.width = w;
8859
+ scratch.height = h;
8860
+ const sctx = scratch.getContext("2d");
8861
+ if (!sctx) return;
8862
+ const image = sctx.createImageData(w, h);
8863
+ const data = image.data;
8864
+ const f = new Float32Array(item.instances, 0, item.count * 4);
8865
+ const u = new Uint32Array(item.instances, 0, item.count * 4);
8866
+ for (let i = 0; i < item.count; i++) {
8867
+ const x = f[i * 4];
8868
+ const y = f[i * 4 + 1];
8869
+ const size = f[i * 4 + 2];
8870
+ if (isGap(x) || isGap(y) || !(size > 0)) continue;
8871
+ const cx = m.px(x);
8872
+ const cy = m.py(y);
8873
+ const s = Math.max(1, Math.round(size * frame.dpr * .8));
8874
+ const x0 = Math.round(cx - s / 2);
8875
+ const y0 = Math.round(cy - s / 2);
8876
+ const packed = u[i * 4 + 3];
8877
+ const alpha = (packed >>> 24 & 255) / 255 * Math.max(item.opacity, .6);
8878
+ const r = packed & 255;
8879
+ const g = packed >>> 8 & 255;
8880
+ const b = packed >>> 16 & 255;
8881
+ for (let py = Math.max(0, y0); py < Math.min(h, y0 + s); py++) for (let px = Math.max(0, x0); px < Math.min(w, x0 + s); px++) {
8882
+ const o = (py * w + px) * 4;
8883
+ const da = data[o + 3] / 255;
8884
+ const outA = alpha + da * (1 - alpha);
8885
+ data[o] = (r * alpha + data[o] * da * (1 - alpha)) / outA;
8886
+ data[o + 1] = (g * alpha + data[o + 1] * da * (1 - alpha)) / outA;
8887
+ data[o + 2] = (b * alpha + data[o + 2] * da * (1 - alpha)) / outA;
8888
+ data[o + 3] = outA * 255;
8889
+ }
8890
+ }
8891
+ sctx.putImageData(image, 0, 0);
8892
+ ctx.drawImage(scratch, 0, 0);
8893
+ };
8894
+ const drawScatter = (item, frame) => {
8895
+ if (item.count > 2e4) {
8896
+ drawScatterPixels(item, frame);
8897
+ return;
8898
+ }
8899
+ const m = mapper(frame);
8900
+ const f = new Float32Array(item.instances, 0, item.count * 4);
8901
+ const u = new Uint32Array(item.instances, 0, item.count * 4);
8902
+ const groups = /* @__PURE__ */ new Map();
8903
+ for (let i = 0; i < item.count; i++) {
8904
+ const packed = u[i * 4 + 3];
8905
+ let list = groups.get(packed);
8906
+ if (!list) groups.set(packed, list = []);
8907
+ list.push(i);
8908
+ }
8909
+ const stroke = item.stroke * frame.dpr;
8910
+ for (const [packed, list] of groups) {
8911
+ const color = unpack(packed);
8912
+ ctx.beginPath();
8913
+ for (const i of list) {
8914
+ const x = f[i * 4];
8915
+ const y = f[i * 4 + 1];
8916
+ const size = f[i * 4 + 2];
8917
+ if (isGap(x) || isGap(y) || !(size > 0)) continue;
8918
+ const cx = m.px(x);
8919
+ const cy = m.py(y);
8920
+ const r = size * frame.dpr / 2;
8921
+ ctx.moveTo(cx + r, cy);
8922
+ ctx.arc(cx, cy, r, 0, Math.PI * 2);
8923
+ }
8924
+ ctx.fillStyle = rgba(color, item.opacity);
8925
+ ctx.fill();
8926
+ if (stroke > 0) {
8927
+ ctx.beginPath();
8928
+ for (const i of list) {
8929
+ const x = f[i * 4];
8930
+ const y = f[i * 4 + 1];
8931
+ const size = f[i * 4 + 2];
8932
+ if (isGap(x) || isGap(y) || !(size > 0)) continue;
8933
+ const r = Math.max(0, size * frame.dpr / 2 - stroke / 2);
8934
+ const cx = m.px(x);
8935
+ const cy = m.py(y);
8936
+ ctx.moveTo(cx + r, cy);
8937
+ ctx.arc(cx, cy, r, 0, Math.PI * 2);
8938
+ }
8939
+ ctx.lineWidth = stroke;
8940
+ ctx.strokeStyle = rgba(color, 1);
8941
+ ctx.stroke();
8942
+ }
8943
+ }
8944
+ };
8945
+ return {
8946
+ paint(items, frame, left = 0, top = 0) {
8947
+ ctx.save();
8948
+ ctx.setTransform(1, 0, 0, 1, left, top);
8949
+ ctx.beginPath();
8950
+ ctx.rect(0, 0, frame.width, frame.height);
8951
+ ctx.clip();
8952
+ for (const item of items) switch (item.kind) {
8953
+ case "line":
8954
+ if (item.count > 1) drawLine(item, frame);
8955
+ break;
8956
+ case "area":
8957
+ if (item.count > 1) drawArea(item, frame);
8958
+ break;
8959
+ case "bar":
8960
+ drawBars(item, frame);
8961
+ break;
8962
+ default: drawScatter(item, frame);
8963
+ }
8964
+ ctx.restore();
8965
+ },
8966
+ destroy() {
8967
+ scratch = null;
8968
+ }
8969
+ };
8970
+ };
8971
+ //#endregion
8972
+ //#region ../charts/src/engine/canvas.ts
8973
+ var mid = (r) => (r[0] + r[1]) / 2;
8974
+ var roundedRect = (ctx, x, y, w, h, r) => {
8975
+ ctx.beginPath();
8976
+ ctx.moveTo(x + r, y);
8977
+ ctx.lineTo(x + w - r, y);
8978
+ ctx.arcTo(x + w, y, x + w, y + r, r);
8979
+ ctx.lineTo(x + w, y + h - r);
8980
+ ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
8981
+ ctx.lineTo(x + r, y + h);
8982
+ ctx.arcTo(x, y + h, x, y + h - r, r);
8983
+ ctx.lineTo(x, y + r);
8984
+ ctx.arcTo(x, y, x + r, y, r);
8985
+ ctx.closePath();
8986
+ };
8987
+ /** Draws a scene (legend, axes, data, labels, hover) on a 2D context */
8988
+ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2dPainter(ctx)) => {
8989
+ const { width, height, theme, model, view, layout } = scene;
8990
+ const { plot, scales } = layout;
8991
+ const dpr = pixelRatio;
8992
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
8993
+ ctx.clearRect(0, 0, Math.ceil(width * dpr), Math.ceil(height * dpr));
8994
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
8995
+ drawBackground(ctx, {
8996
+ width,
8997
+ height,
8998
+ scales,
8999
+ x: model.x,
9000
+ y: model.y,
9001
+ xTicks: layout.xTicks,
9002
+ yTicks: layout.yTicks,
9003
+ theme,
9004
+ annotations: scene.annotations
9005
+ });
9006
+ if (scene.legend) {
9007
+ ctx.font = font(theme, 12);
9008
+ ctx.textBaseline = "middle";
9009
+ ctx.textAlign = "left";
9010
+ for (const e of scene.legend.entries) {
9011
+ const cy = e.box.y + e.box.height / 2;
9012
+ ctx.globalAlpha = e.hidden ? .45 : 1;
9013
+ ctx.fillStyle = e.color;
9014
+ if (e.shape === "dot") {
9015
+ ctx.beginPath();
9016
+ ctx.arc(e.box.x + 5, cy, 4, 0, Math.PI * 2);
9017
+ ctx.fill();
9018
+ } else if (e.shape === "line") ctx.fillRect(e.box.x, cy - 1, 10, 2);
9019
+ else ctx.fillRect(e.box.x + 1, cy - 4, 8, 8);
9020
+ ctx.fillStyle = toCss(theme.textMuted);
9021
+ ctx.fillText(e.name, e.box.x + 14, cy);
9022
+ if (e.hidden) {
9023
+ const w = e.box.width - 22;
9024
+ ctx.fillRect(e.box.x + 14, cy, w, 1);
9025
+ }
9026
+ }
9027
+ ctx.globalAlpha = 1;
9028
+ }
9029
+ const scale = (range, o, reverse) => {
9030
+ const s = 2 / (range[1] - range[0]);
9031
+ const offset = (o - range[0]) * s - 1;
9032
+ return reverse ? [-s, -offset] : [s, offset];
9033
+ };
9034
+ const [xScale, xOffset] = scale(view.x, origin.x, model.x.reverse);
9035
+ const [yScale, yOffset] = scale(view.y, origin.y, model.y.reverse);
9036
+ painter.paint(items, {
9037
+ transform: {
9038
+ xScale,
9039
+ xOffset,
9040
+ yScale,
9041
+ yOffset
9042
+ },
9043
+ width: Math.max(1, Math.round(plot.width * dpr)),
9044
+ height: Math.max(1, Math.round(plot.height * dpr)),
9045
+ dpr
9046
+ }, Math.round(plot.x * dpr), Math.round(plot.y * dpr));
9047
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
9048
+ drawForeground(ctx, {
9049
+ width,
9050
+ height,
9051
+ scales,
9052
+ theme,
9053
+ annotations: scene.annotations,
9054
+ pointLabels: [],
9055
+ clear: false
9056
+ });
9057
+ if (scene.pointLabels.length) {
9058
+ ctx.save();
9059
+ ctx.font = font(theme);
9060
+ ctx.textAlign = "left";
9061
+ ctx.textBaseline = "middle";
9062
+ ctx.lineWidth = 3;
9063
+ ctx.lineJoin = "round";
9064
+ ctx.strokeStyle = toCss(theme.background, .9);
9065
+ ctx.fillStyle = toCss(theme.text, .85);
9066
+ for (const { label, box } of scene.pointLabels) {
9067
+ ctx.strokeText(label.text, box.x, box.y + box.height / 2);
9068
+ ctx.fillText(label.text, box.x, box.y + box.height / 2);
9069
+ }
9070
+ ctx.restore();
9071
+ }
9072
+ const hover = scene.hover;
9073
+ if (hover) {
9074
+ if (hover.crosshairX !== null) {
9075
+ ctx.save();
9076
+ ctx.strokeStyle = toCss(theme.textMuted, .55);
9077
+ ctx.lineWidth = 1;
9078
+ ctx.setLineDash([3, 3]);
9079
+ ctx.beginPath();
9080
+ const cx = Math.round(hover.crosshairX) + .5;
9081
+ ctx.moveTo(cx, plot.y);
9082
+ ctx.lineTo(cx, plot.y + plot.height);
9083
+ ctx.stroke();
9084
+ ctx.restore();
9085
+ }
9086
+ for (const mark of hover.marks) {
9087
+ if (mark.kind === "bar") {
9088
+ ctx.fillStyle = toCss(theme.text, .08);
9089
+ ctx.fillRect(mark.x - 2, mark.y - 2, mark.width + 4, mark.height + 2);
9090
+ continue;
9091
+ }
9092
+ ctx.beginPath();
9093
+ ctx.arc(mark.x, mark.y, mark.size / 2, 0, Math.PI * 2);
9094
+ ctx.fillStyle = mark.color;
9095
+ ctx.fill();
9096
+ ctx.lineWidth = 2;
9097
+ ctx.strokeStyle = toCss(theme.background);
9098
+ ctx.stroke();
9099
+ }
9100
+ }
9101
+ if (scene.dragging) {
9102
+ const d = scene.dragging;
9103
+ ctx.beginPath();
9104
+ ctx.arc(d.x, d.y, d.size / 2, 0, Math.PI * 2);
9105
+ ctx.fillStyle = d.color;
9106
+ ctx.globalAlpha = .85;
9107
+ ctx.fill();
9108
+ ctx.globalAlpha = 1;
9109
+ ctx.lineWidth = 2;
9110
+ ctx.strokeStyle = toCss(theme.background);
9111
+ ctx.stroke();
9112
+ }
9113
+ const tip = hover?.tooltip;
9114
+ if (tip) {
9115
+ const { box, lineHeight, padding } = tip;
9116
+ ctx.save();
9117
+ ctx.shadowColor = "rgba(15, 23, 42, 0.18)";
9118
+ ctx.shadowBlur = 16;
9119
+ ctx.shadowOffsetY = 6;
9120
+ roundedRect(ctx, box.x, box.y, box.width, box.height, 8);
9121
+ ctx.fillStyle = toCss(theme.background);
9122
+ ctx.fill();
9123
+ ctx.restore();
9124
+ roundedRect(ctx, box.x + .5, box.y + .5, box.width - 1, box.height - 1, 8);
9125
+ ctx.strokeStyle = toCss(theme.axis);
9126
+ ctx.lineWidth = 1;
9127
+ ctx.stroke();
9128
+ ctx.textBaseline = "middle";
9129
+ let y = box.y + padding + lineHeight / 2;
9130
+ const left = box.x + padding + 2;
9131
+ const right = box.x + box.width - padding - 2;
9132
+ if (tip.text) {
9133
+ ctx.font = font(theme, 12);
9134
+ ctx.fillStyle = toCss(theme.text);
9135
+ ctx.textAlign = "left";
9136
+ for (const line of tip.text) {
9137
+ ctx.fillText(line, left, y);
9138
+ y += lineHeight;
9139
+ }
9140
+ } else {
9141
+ const { content } = tip;
9142
+ let x = left;
9143
+ if (content.titleColor) {
9144
+ ctx.fillStyle = content.titleColor;
9145
+ ctx.beginPath();
9146
+ ctx.arc(x + 4, y, 4, 0, Math.PI * 2);
9147
+ ctx.fill();
9148
+ x += 14;
9149
+ }
9150
+ ctx.font = font(theme, 12, 600);
9151
+ ctx.fillStyle = toCss(theme.text);
9152
+ ctx.textAlign = "left";
9153
+ ctx.fillText(content.title, x, y);
9154
+ y += lineHeight;
9155
+ for (const row of content.rows) {
9156
+ x = left;
9157
+ if (row.color) {
9158
+ ctx.fillStyle = row.color;
9159
+ ctx.beginPath();
9160
+ ctx.arc(x + 4, y, 4, 0, Math.PI * 2);
9161
+ ctx.fill();
9162
+ x += 14;
9163
+ }
9164
+ ctx.font = font(theme, 12);
9165
+ ctx.textAlign = "left";
9166
+ ctx.fillStyle = toCss(theme.textMuted);
9167
+ ctx.fillText(row.name, x, y);
9168
+ ctx.font = font(theme, 12, 600);
9169
+ ctx.textAlign = "right";
9170
+ ctx.fillStyle = toCss(theme.text);
9171
+ ctx.fillText(row.value, right, y);
9172
+ y += lineHeight;
9173
+ }
9174
+ }
9175
+ }
9176
+ };
9177
+ /**
9178
+ * Creates a chart drawn on a 2D canvas: line, area, bar and scatter series,
9179
+ * annotations, legend and tooltip, tap / drag / pinch gestures. Works
9180
+ * without a DOM (mini-programs); see `createChart` for the GPU version of
9181
+ * the web.
9182
+ */
9183
+ var createCanvasChart = (config) => {
9184
+ const { canvas } = config;
9185
+ const ctx = canvas.getContext("2d");
9186
+ let width = config.width;
9187
+ let height = config.height;
9188
+ let dpr = config.pixelRatio ?? 1;
9189
+ let destroyed = false;
9190
+ let frameId = null;
9191
+ let items = [];
9192
+ let itemsModel = null;
9193
+ let origin = {
9194
+ x: 0,
9195
+ y: 0
9196
+ };
9197
+ let version = 0;
9198
+ let fontSet = "";
9199
+ const measureText = (text, f) => {
9200
+ if (!ctx) return text.length * 6.5;
9201
+ if (f !== fontSet) {
9202
+ ctx.font = f;
9203
+ fontSet = f;
9204
+ }
9205
+ return ctx.measureText(text).width;
9206
+ };
9207
+ const painter = ctx ? createCanvas2dPainter(ctx) : null;
9208
+ const g = globalThis;
9209
+ const render = () => {
9210
+ frameId = null;
9211
+ if (destroyed || !ctx || !painter) return;
9212
+ const scene = controller.getScene();
9213
+ if (!scene) return;
9214
+ const pw = Math.max(1, Math.round(width * dpr));
9215
+ const ph = Math.max(1, Math.round(height * dpr));
9216
+ if (canvas.width !== pw) canvas.width = pw;
9217
+ if (canvas.height !== ph) canvas.height = ph;
9218
+ fontSet = "";
9219
+ if (itemsModel !== scene.model) {
9220
+ itemsModel = scene.model;
9221
+ origin = {
9222
+ x: mid(scene.model.base.x),
9223
+ y: mid(scene.model.base.y)
9224
+ };
9225
+ items = buildItems(scene.model, origin, ++version);
9226
+ }
9227
+ drawScene(ctx, scene, items, origin, dpr, painter);
9228
+ fontSet = "";
9229
+ };
9230
+ const schedule = () => {
9231
+ if (destroyed || frameId !== null) return;
9232
+ if (canvas.requestAnimationFrame) frameId = canvas.requestAnimationFrame(render);
9233
+ else if (g.requestAnimationFrame) frameId = g.requestAnimationFrame(render);
9234
+ else frameId = setTimeout(render, 16);
9235
+ };
9236
+ const controller = createChartController({
9237
+ options: config.options,
9238
+ theme: config.theme,
9239
+ measureText,
9240
+ onInvalidate: schedule
9241
+ });
9242
+ controller.setSize(width, height);
9243
+ const touchOptions = (t, i) => ({
9244
+ id: t.identifier ?? i,
9245
+ touch: true
9246
+ });
9247
+ return {
9248
+ setOptions: (o) => controller.setOptions(o),
9249
+ setTheme: (t) => controller.setTheme(t),
9250
+ resize(w, h, ratio) {
9251
+ width = w;
9252
+ height = h;
9253
+ if (ratio) dpr = ratio;
9254
+ controller.setSize(w, h);
9255
+ schedule();
9256
+ },
9257
+ render() {
9258
+ if (frameId !== null) {
9259
+ if (canvas.cancelAnimationFrame) canvas.cancelAnimationFrame(frameId);
9260
+ else if (g.cancelAnimationFrame) g.cancelAnimationFrame(frameId);
9261
+ else clearTimeout(frameId);
9262
+ }
9263
+ render();
9264
+ },
9265
+ touchStart(touches) {
9266
+ touches.forEach((t, i) => controller.pointerDown(t.x, t.y, touchOptions(t, i)));
9267
+ },
9268
+ touchMove(touches) {
9269
+ touches.forEach((t, i) => controller.pointerMove(t.x, t.y, touchOptions(t, i)));
9270
+ },
9271
+ touchEnd(touches) {
9272
+ touches.forEach((t, i) => controller.pointerUp(t.x, t.y, touchOptions(t, i)));
9273
+ },
9274
+ touchCancel(touches = [{
9275
+ x: 0,
9276
+ y: 0
9277
+ }]) {
9278
+ touches.forEach((t, i) => controller.pointerCancel(touchOptions(t, i)));
9279
+ },
9280
+ pointerDown: (x, y, o) => controller.pointerDown(x, y, o),
9281
+ pointerMove: (x, y, o) => controller.pointerMove(x, y, o),
9282
+ pointerUp: (x, y, o) => controller.pointerUp(x, y, o),
9283
+ pointerLeave: () => controller.pointerLeave(),
9284
+ zoomAt: (x, y, f) => controller.zoomAt(x, y, f),
9285
+ resetZoom: () => controller.resetZoom(),
9286
+ getView: () => controller.getView(),
9287
+ setView: (v) => controller.setView(v),
9288
+ toggleSeries: (id) => controller.toggleSeries(id),
9289
+ clearHover: () => controller.clearHover(),
9290
+ getPlotRect: () => controller.getPlotRect(),
9291
+ toPixel: (x, y) => controller.toPixel(x, y),
9292
+ fromPixel: (x, y) => controller.fromPixel(x, y),
9293
+ getController: () => controller,
9294
+ on: (type, listener) => controller.on(type, listener),
9295
+ destroy() {
9296
+ if (destroyed) return;
9297
+ destroyed = true;
9298
+ if (frameId !== null) {
9299
+ if (canvas.cancelAnimationFrame) canvas.cancelAnimationFrame(frameId);
9300
+ else if (g.cancelAnimationFrame) g.cancelAnimationFrame(frameId);
9301
+ else clearTimeout(frameId);
9302
+ }
9303
+ painter?.destroy();
9304
+ controller.destroy();
9305
+ }
9306
+ };
9307
+ };
9308
+ //#endregion
9309
+ //#region ../charts/src/engine/presets.ts
9310
+ /** Gives the series without a `type` the type of the component */
9311
+ var withSeriesType = (series, type, stack) => series.map((s) => ({
9312
+ ...s,
9313
+ type: s.type ?? type,
9314
+ ...stack !== void 0 && (s.type ?? type) === "bar" ? { stack: s.stack ?? stack } : {}
9315
+ }));
9316
+ /** Series of a LineChart (`area` fills them) */
9317
+ var lineSeries = (series, area = false) => withSeriesType(series, area ? "area" : "line");
9318
+ /** Series of a BarChart (`stacked` stacks them) */
9319
+ var barSeries = (series, stacked = false) => withSeriesType(series, "bar", stacked ? "stack" : void 0);
9320
+ /** Series of a ScatterChart */
9321
+ var scatterSeries = (series) => withSeriesType(series, "scatter");
9322
+ var DEFAULT_QUADRANT_COLORS = {
9323
+ topLeft: "var(--danger-color, #ef4444)",
9324
+ topRight: "var(--primary-color, #4f46e5)",
9325
+ bottomLeft: "var(--warning-color, #f59e0b)",
9326
+ bottomRight: "var(--text-secondary-color, #64748b)"
9327
+ };
9328
+ var DIVIDER = "var(--border-strong-color, var(--border-color, #cbd5e1))";
9329
+ var splits = (config) => {
9330
+ const [x0, x1] = config.xDomain ?? [0, 10];
9331
+ const [y0, y1] = config.yDomain ?? [0, 10];
9332
+ return {
9333
+ x0,
9334
+ x1,
9335
+ y0,
9336
+ y1,
9337
+ xs: config.xSplit ?? (x0 + x1) / 2,
9338
+ ys: config.ySplit ?? (y0 + y1) / 2
9339
+ };
9340
+ };
9341
+ /** Quadrant of a data position, as seen on screen */
9342
+ var quadrantOf = (config, x, y) => {
9343
+ const { xs, ys } = splits(config);
9344
+ const right = config.reverseX ? x < xs : x >= xs;
9345
+ return y >= ys ? right ? "topRight" : "topLeft" : right ? "bottomRight" : "bottomLeft";
9346
+ };
9347
+ /** Engine options of a quadrant matrix */
9348
+ var quadrantChartOptions = (config, base = {}) => {
9349
+ const { x0, x1, y0, y1, xs, ys } = splits(config);
9350
+ const reverseX = !!config.reverseX;
9351
+ const color = (corner) => config.quadrants?.[corner]?.color ?? DEFAULT_QUADRANT_COLORS[corner];
9352
+ const series = [{
9353
+ type: "scatter",
9354
+ name: config.name ?? "",
9355
+ pointSize: config.pointSize ?? 12,
9356
+ showLabels: config.showLabels ?? true,
9357
+ opacity: .9,
9358
+ data: config.points.map((p) => ({
9359
+ x: p.x,
9360
+ y: p.y,
9361
+ label: p.label,
9362
+ size: p.size,
9363
+ color: p.color ?? color(quadrantOf(config, p.x, p.y))
9364
+ }))
9365
+ }];
9366
+ const left = reverseX ? [xs, x1] : [x0, xs];
9367
+ const right = reverseX ? [x0, xs] : [xs, x1];
9368
+ const rect = (corner, [xa, xb], [ya, yb], position) => ({
9369
+ type: "rect",
9370
+ x0: xa,
9371
+ x1: xb,
9372
+ y0: ya,
9373
+ y1: yb,
9374
+ color: color(corner),
9375
+ opacity: .07,
9376
+ label: config.quadrants?.[corner]?.label,
9377
+ labelPosition: position
9378
+ });
9379
+ const ends = config.axisLabels ?? {};
9380
+ const visualLeft = reverseX ? x1 : x0;
9381
+ const visualRight = reverseX ? x0 : x1;
9382
+ const texts = [
9383
+ ...ends.top ? [{
9384
+ type: "text",
9385
+ x: xs,
9386
+ y: y1,
9387
+ text: ends.top,
9388
+ anchor: "top"
9389
+ }] : [],
9390
+ ...ends.bottom ? [{
9391
+ type: "text",
9392
+ x: xs,
9393
+ y: y0,
9394
+ text: ends.bottom,
9395
+ anchor: "bottom"
9396
+ }] : [],
9397
+ ...ends.left ? [{
9398
+ type: "text",
9399
+ x: visualLeft,
9400
+ y: ys,
9401
+ text: ends.left,
9402
+ anchor: "left"
9403
+ }] : [],
9404
+ ...ends.right ? [{
9405
+ type: "text",
9406
+ x: visualRight,
9407
+ y: ys,
9408
+ text: ends.right,
9409
+ anchor: "right"
9410
+ }] : []
9411
+ ];
9412
+ const annotations = [
9413
+ rect("topLeft", left, [ys, y1], "top-left"),
9414
+ rect("topRight", right, [ys, y1], "top-right"),
9415
+ rect("bottomLeft", left, [y0, ys], "bottom-left"),
9416
+ rect("bottomRight", right, [y0, ys], "bottom-right"),
9417
+ {
9418
+ type: "line",
9419
+ axis: "x",
9420
+ value: xs,
9421
+ dash: [],
9422
+ color: DIVIDER
9423
+ },
9424
+ {
9425
+ type: "line",
9426
+ axis: "y",
9427
+ value: ys,
9428
+ dash: [],
9429
+ color: DIVIDER
9430
+ },
9431
+ ...texts,
9432
+ ...base.annotations ?? []
9433
+ ];
9434
+ const showTicks = config.showTicks ?? true;
9435
+ const interaction = base.interaction === false ? false : {
9436
+ zoom: false,
9437
+ ...typeof base.interaction === "object" ? base.interaction : {},
9438
+ ...config.draggable ? { dragPoints: true } : {}
9439
+ };
9440
+ return {
9441
+ ...base,
9442
+ series,
9443
+ annotations,
9444
+ tooltip: base.tooltip ?? (showTicks ? void 0 : { render: (event) => {
9445
+ const item = event.items[0];
9446
+ if (!item) return null;
9447
+ const region = config.quadrants?.[quadrantOf(config, item.x, item.y)]?.label;
9448
+ return [item.label ?? config.name ?? "", region ?? ""].filter(Boolean).join("\n");
9449
+ } }),
9450
+ xAxis: {
9451
+ min: x0,
9452
+ max: x1,
9453
+ title: config.xLabel,
9454
+ reverse: reverseX,
9455
+ nice: false,
9456
+ grid: false,
9457
+ tickCount: 4,
9458
+ visible: showTicks || !!config.xLabel,
9459
+ ...showTicks ? {} : { format: () => "" }
9460
+ },
9461
+ yAxis: {
9462
+ min: y0,
9463
+ max: y1,
9464
+ title: config.yLabel,
9465
+ nice: false,
9466
+ grid: false,
9467
+ tickCount: 4,
9468
+ visible: showTicks || !!config.yLabel,
9469
+ ...showTicks ? {} : { format: () => "" }
9470
+ },
9471
+ legend: base.legend ?? false,
9472
+ padding: base.padding ?? (showTicks ? void 0 : {
9473
+ top: 4,
9474
+ right: 4,
9475
+ bottom: 4,
9476
+ left: 4
9477
+ }),
9478
+ interaction
9479
+ };
9480
+ };
9481
+ //#endregion
9482
+ //#region src/charts.ts
9483
+ var states = /* @__PURE__ */ new WeakMap();
9484
+ var optional$4 = () => ({
9485
+ type: null,
9486
+ value: null
9487
+ });
9488
+ var flag$6 = (value = false) => ({
9489
+ type: Boolean,
9490
+ value
9491
+ });
9492
+ var text$4 = (value = "") => ({
9493
+ type: String,
9494
+ value
9495
+ });
9496
+ var list$2 = () => ({
9497
+ type: Array,
9498
+ value: []
9499
+ });
9500
+ /** `null` / `""` properties mean "not set" (engine default) */
9501
+ var unset = (value) => value === null || value === "" ? void 0 : value;
9502
+ var nonEmpty = (value) => value && value.length ? value : void 0;
9503
+ /** Numbers and digit strings are px, other strings are CSS lengths */
9504
+ var cssSize = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? `${value}px` : typeof value === "string" && value.trim() ? /^\d+(\.\d+)?$/.test(value.trim()) ? `${value.trim()}px` : value.trim() : fallback;
9505
+ var pixelRatio = () => {
9506
+ try {
9507
+ const ratio = Number(windowInfo().pixelRatio);
9508
+ return ratio > 0 ? ratio : 1;
9509
+ } catch {
9510
+ return 1;
9511
+ }
9512
+ };
9513
+ var isRecord = (value) => typeof value === "object" && value !== null;
9514
+ var themeCache = /* @__PURE__ */ new Map();
9515
+ /**
9516
+ * Chart theme of a configuration: the resolved Minerva token values of its
9517
+ * mode, palette, design and custom theme as `--name` variables (the engine
9518
+ * resolves `var(--name, fallback)` colors of the options against them).
9519
+ */
9520
+ function chartTheme(config) {
9521
+ const mode = config?.resolvedMode === "dark" ? "dark" : "light";
9522
+ const theme = config?.theme;
9523
+ const custom = theme === "github-dark" ? githubDark : isRecord(theme) ? "light" in theme && "dark" in theme ? theme[mode] : theme : void 0;
9524
+ const options = {
9525
+ mode,
9526
+ palette: config?.palette ?? null,
9527
+ design: config?.design ?? {},
9528
+ ...isRecord(custom) ? { overrides: custom } : {}
9529
+ };
9530
+ const key = JSON.stringify(options);
9531
+ const cached = themeCache.get(key);
9532
+ if (cached) return cached;
9533
+ const css = resolveTokens(options).css;
9534
+ const variables = {};
9535
+ for (const [name, value] of Object.entries(css)) variables[`--${name}`] = String(value);
9536
+ const result = {
9537
+ variables,
9538
+ ...css["font-family-sans"] ? { fontFamily: String(css["font-family-sans"]) } : {}
9539
+ };
9540
+ if (themeCache.size > 32) themeCache.clear();
9541
+ themeCache.set(key, result);
9542
+ return result;
9543
+ }
9544
+ var stateOf = (self, kind) => {
9545
+ let state = states.get(self);
9546
+ if (!state) {
9547
+ state = {
9548
+ kind,
9549
+ chart: null,
9550
+ config: {},
9551
+ theme: void 0,
9552
+ themeKey: "",
9553
+ ready: false
9554
+ };
9555
+ states.set(self, state);
9556
+ }
9557
+ return state;
9558
+ };
9559
+ var configOf = (self) => typeof self.getConfig === "function" ? self.getConfig() : void 0;
9560
+ var tooltipOption = (value, render) => !render || value === false ? value : {
9561
+ ...isRecord(value) ? value : {},
9562
+ render
9563
+ };
9564
+ var axisOption = (value, format) => format ? {
9565
+ ...value,
9566
+ format
9567
+ } : value;
9568
+ /** Options shared by every chart (everything but the series and axes) */
9569
+ var baseOptions = (self, render) => {
9570
+ const d = self.data;
9571
+ return {
9572
+ legend: unset(d.legend),
9573
+ tooltip: tooltipOption(unset(d.tooltip), render),
9574
+ crosshair: unset(d.crosshair),
9575
+ annotations: nonEmpty(d.annotations),
9576
+ interaction: unset(d.interaction),
9577
+ padding: unset(d.padding),
9578
+ palette: nonEmpty(d.palette),
9579
+ ariaLabel: d.ariaLabel || void 0
9580
+ };
9581
+ };
9582
+ var quadrantConfig = (self) => {
9583
+ const d = self.data;
9584
+ return {
9585
+ points: d.points ?? [],
9586
+ xDomain: unset(d.xDomain),
9587
+ yDomain: unset(d.yDomain),
9588
+ xSplit: unset(d.xSplit),
9589
+ ySplit: unset(d.ySplit),
9590
+ quadrants: unset(d.quadrants),
9591
+ xLabel: d.xLabel || void 0,
9592
+ yLabel: d.yLabel || void 0,
9593
+ axisLabels: unset(d.axisLabels),
9594
+ showTicks: d.showTicks,
9595
+ reverseX: d.reverseX,
9596
+ showLabels: d.showLabels,
9597
+ pointSize: d.pointSize,
9598
+ name: d.name || void 0,
9599
+ draggable: d.draggable
9600
+ };
9601
+ };
9602
+ /** Engine options of the current properties, like the web components */
9603
+ var chartOptions = (self, state) => {
9604
+ const d = self.data;
9605
+ const { config } = state;
9606
+ if (state.kind === "quadrant") {
9607
+ const points = d.points ?? [];
9608
+ const render = config.renderTooltip;
9609
+ return quadrantChartOptions(quadrantConfig(self), baseOptions(self, render ? (event) => {
9610
+ const index = event.items[0]?.index;
9611
+ return index !== void 0 && points[index] ? render(points[index], index) : null;
9612
+ } : void 0));
9613
+ }
9614
+ const { renderTooltip, xAxis, yAxis } = config;
9615
+ const input = d.series ?? [];
9616
+ const series = state.kind === "line" ? lineSeries(input, !!d.area) : state.kind === "bar" ? barSeries(input, !!d.stacked) : state.kind === "scatter" ? scatterSeries(input) : input;
9617
+ return {
9618
+ ...baseOptions(self, renderTooltip),
9619
+ series,
9620
+ xAxis: axisOption(unset(d.xAxis), xAxis?.format),
9621
+ yAxis: axisOption(unset(d.yAxis), yAxis?.format)
9622
+ };
9623
+ };
9624
+ var applyOptions = (self) => {
9625
+ const state = states.get(self);
9626
+ state?.chart?.setOptions(chartOptions(self, state));
9627
+ };
9628
+ var applyTheme = (self) => {
9629
+ const state = states.get(self);
9630
+ if (!state) return;
9631
+ const theme = chartTheme(configOf(self));
9632
+ if (theme === state.theme) return;
9633
+ state.theme = theme;
9634
+ state.chart?.setTheme(theme);
9635
+ };
9636
+ var emptyHover = {
9637
+ items: [],
9638
+ x: null,
9639
+ xLabel: ""
9640
+ };
9641
+ var bindEvents = (self, state, chart) => {
9642
+ chart.on("hover", (event) => self.triggerEvent("hover", event ?? emptyHover));
9643
+ chart.on("zoom", (view) => self.triggerEvent("zoom", view));
9644
+ chart.on("layout", (rect) => self.triggerEvent("layout", rect));
9645
+ if (state.kind !== "quadrant") {
9646
+ chart.on("click", (event) => self.triggerEvent("pointclick", event));
9647
+ chart.on("plotClick", (at) => self.triggerEvent("plotclick", at));
9648
+ chart.on("drag", (event) => self.triggerEvent("pointdrag", event));
9649
+ chart.on("drop", (event) => self.triggerEvent("pointdrop", event));
9650
+ return;
9651
+ }
9652
+ const point = (index) => (self.data.points ?? [])[index];
9653
+ const target = (x, y) => ({
9654
+ x,
9655
+ y,
9656
+ quadrant: quadrantOf(quadrantConfig(self), x, y)
9657
+ });
9658
+ chart.on("click", (event) => {
9659
+ const index = event.items[0]?.index;
9660
+ if (index !== void 0 && point(index)) self.triggerEvent("pointclick", {
9661
+ point: point(index),
9662
+ index
9663
+ });
9664
+ });
9665
+ chart.on("plotClick", (at) => self.triggerEvent("quadrantclick", {
9666
+ quadrant: quadrantOf(quadrantConfig(self), at.x, at.y),
9667
+ x: at.x,
9668
+ y: at.y
9669
+ }));
9670
+ for (const [source, name] of [["drag", "pointdrag"], ["drop", "pointdrop"]]) chart.on(source, (event) => {
9671
+ const index = event.item.index;
9672
+ if (point(index)) self.triggerEvent(name, {
9673
+ point: point(index),
9674
+ index,
9675
+ target: target(event.x, event.y)
9676
+ });
9677
+ });
9678
+ };
9679
+ /** Measures the canvas node, then creates (or resizes) the chart */
9680
+ var measure$1 = (self) => {
9681
+ const state = states.get(self);
9682
+ if (!state) return;
9683
+ self.createSelectorQuery().select(".mn-chart-canvas").fields({
9684
+ node: true,
9685
+ size: true
9686
+ }).exec((result) => {
9687
+ if (states.get(self) !== state) return;
9688
+ const hit = result?.[0];
9689
+ const width = Number(hit?.width), height = Number(hit?.height);
9690
+ if (!hit?.node || !(width > 0) || !(height > 0)) return;
9691
+ const ratio = pixelRatio();
9692
+ if (state.chart) {
9693
+ state.chart.resize(width, height, ratio);
9694
+ return;
9695
+ }
9696
+ if (!state.theme) state.theme = chartTheme(configOf(self));
9697
+ const chart = createCanvasChart({
9698
+ canvas: hit.node,
9699
+ width,
9700
+ height,
9701
+ pixelRatio: ratio,
9702
+ options: chartOptions(self, state),
9703
+ theme: state.theme
9704
+ });
9705
+ state.chart = chart;
9706
+ bindEvents(self, state, chart);
9707
+ });
9708
+ };
9709
+ var touches = (input) => Array.from(input ?? []).filter((t) => t && Number.isFinite(Number(t.x)) && Number.isFinite(Number(t.y))).map((t, i) => ({
9710
+ x: Number(t.x),
9711
+ y: Number(t.y),
9712
+ identifier: t.identifier ?? i
9713
+ }));
9714
+ var COMMON_OPTIONS = [
9715
+ "legend",
9716
+ "tooltip",
9717
+ "crosshair",
9718
+ "annotations",
9719
+ "interaction",
9720
+ "padding",
9721
+ "palette",
9722
+ "ariaLabel"
9723
+ ];
9724
+ var SERIES_OPTIONS = [
9725
+ "series",
9726
+ "xAxis",
9727
+ "yAxis"
9728
+ ];
9729
+ var QUADRANT_OPTIONS = [
9730
+ "points",
9731
+ "xDomain",
9732
+ "yDomain",
9733
+ "xSplit",
9734
+ "ySplit",
9735
+ "quadrants",
9736
+ "xLabel",
9737
+ "yLabel",
9738
+ "axisLabels",
9739
+ "showTicks",
9740
+ "reverseX",
9741
+ "showLabels",
9742
+ "pointSize",
9743
+ "name",
9744
+ "draggable"
9745
+ ];
9746
+ function defineChart(kind) {
9747
+ const kindProperties = kind === "quadrant" ? {
9748
+ points: list$2(),
9749
+ xDomain: optional$4(),
9750
+ yDomain: optional$4(),
9751
+ xSplit: optional$4(),
9752
+ ySplit: optional$4(),
9753
+ quadrants: optional$4(),
9754
+ xLabel: text$4(),
9755
+ yLabel: text$4(),
9756
+ axisLabels: optional$4(),
9757
+ showTicks: flag$6(true),
9758
+ reverseX: flag$6(),
9759
+ showLabels: flag$6(true),
9760
+ pointSize: {
9761
+ type: Number,
9762
+ value: 12
9763
+ },
9764
+ name: text$4(),
9765
+ draggable: flag$6()
9766
+ } : {
9767
+ series: list$2(),
9768
+ xAxis: optional$4(),
9769
+ yAxis: optional$4(),
9770
+ ...kind === "line" ? { area: flag$6() } : {},
9771
+ ...kind === "bar" ? { stacked: flag$6() } : {}
9772
+ };
9773
+ const optionNames = [
9774
+ ...COMMON_OPTIONS,
9775
+ ...kind === "quadrant" ? QUADRANT_OPTIONS : SERIES_OPTIONS,
9776
+ ...kind === "line" ? ["area"] : kind === "bar" ? ["stacked"] : []
9777
+ ];
9778
+ return {
9779
+ template: `<view class="mn-chart" style="display:block;position:relative;width:{{chartWidth}};height:{{chartHeight}}"><canvas type="2d" class="mn-chart-canvas" style="display:block;width:100%;height:100%" disable-scroll="{{disableScroll}}" aria-role="img" aria-label="{{ariaLabel}}" bindtouchstart="onTouchStart" bindtouchmove="onTouchMove" bindtouchend="onTouchEnd" bindtouchcancel="onTouchCancel"></canvas></view>`,
9780
+ definition: {
9781
+ properties: {
9782
+ width: {
9783
+ type: null,
9784
+ value: "100%"
9785
+ },
9786
+ height: {
9787
+ type: null,
9788
+ value: 320
9789
+ },
9790
+ legend: optional$4(),
9791
+ tooltip: optional$4(),
9792
+ crosshair: optional$4(),
9793
+ annotations: list$2(),
9794
+ interaction: optional$4(),
9795
+ padding: optional$4(),
9796
+ palette: list$2(),
9797
+ ariaLabel: text$4(),
9798
+ disableScroll: flag$6(),
9799
+ ...kindProperties
9800
+ },
9801
+ data: {
9802
+ chartWidth: "100%",
9803
+ chartHeight: "320px"
9804
+ },
9805
+ observers: {
9806
+ [optionNames.join(",")]: function() {
9807
+ applyOptions(this);
9808
+ },
9809
+ "width,height": function() {
9810
+ const width = cssSize(this.data.width, "100%"), height = cssSize(this.data.height, "320px");
9811
+ if (width === this.data.chartWidth && height === this.data.chartHeight) return;
9812
+ this.setData({
9813
+ chartWidth: width,
9814
+ chartHeight: height
9815
+ }, () => {
9816
+ if (states.get(this)?.ready) measure$1(this);
9817
+ });
9818
+ },
9819
+ "inheritedTheme,inheritedMode,inheritedPalette": function() {
9820
+ applyTheme(this);
9821
+ }
9822
+ },
9823
+ lifetimes: {
9824
+ attached() {
9825
+ stateOf(this, kind);
9826
+ this.setData({
9827
+ chartWidth: cssSize(this.data.width, "100%"),
9828
+ chartHeight: cssSize(this.data.height, "320px")
9829
+ });
9830
+ },
9831
+ ready() {
9832
+ stateOf(this, kind).ready = true;
9833
+ measure$1(this);
9834
+ },
9835
+ detached() {
9836
+ states.get(this)?.chart?.destroy();
9837
+ states.delete(this);
9838
+ }
9839
+ },
9840
+ methods: {
9841
+ configure(config) {
9842
+ stateOf(this, kind).config = { ...config };
9843
+ applyOptions(this);
9844
+ },
9845
+ resize() {
9846
+ measure$1(this);
9847
+ },
9848
+ resetZoom() {
9849
+ states.get(this)?.chart?.resetZoom();
9850
+ },
9851
+ getView() {
9852
+ return states.get(this)?.chart?.getView() ?? null;
9853
+ },
9854
+ setView(view) {
9855
+ states.get(this)?.chart?.setView(view);
9856
+ },
9857
+ getPlotRect() {
9858
+ return states.get(this)?.chart?.getPlotRect() ?? null;
9859
+ },
9860
+ toPixel(x, y) {
9861
+ return states.get(this)?.chart?.toPixel(x, y) ?? null;
9862
+ },
9863
+ fromPixel(x, y) {
9864
+ return states.get(this)?.chart?.fromPixel(x, y) ?? null;
9865
+ },
9866
+ onTouchStart(event) {
9867
+ const changed = touches(event.changedTouches);
9868
+ states.get(this)?.chart?.touchStart(changed.length ? changed : touches(event.touches));
9869
+ },
9870
+ onTouchMove(event) {
9871
+ const current = touches(event.touches);
9872
+ states.get(this)?.chart?.touchMove(current.length ? current : touches(event.changedTouches));
9873
+ },
9874
+ onTouchEnd(event) {
9875
+ states.get(this)?.chart?.touchEnd(touches(event.changedTouches));
9876
+ },
9877
+ onTouchCancel(event) {
9878
+ const changed = touches(event.changedTouches);
9879
+ states.get(this)?.chart?.touchCancel(changed.length ? changed : void 0);
9880
+ }
9881
+ }
9882
+ }
9883
+ };
9884
+ }
9885
+ /** Any mix of line, area, bar and scatter series (each sets its `type`) */
9886
+ var chart = defineChart("chart");
9887
+ /** Line chart (`area` fills the lines) */
9888
+ var lineChart = defineChart("line");
9889
+ /** Bar chart, grouped or `stacked` */
9890
+ var barChart = defineChart("bar");
9891
+ /** Scatter chart, zooming on both axes */
9892
+ var scatterChart = defineChart("scatter");
9893
+ /** Four-quadrant matrix with labelled, optionally draggable dots */
9894
+ var quadrantChart = defineChart("quadrant");
9895
+ //#endregion
6158
9896
  //#region src/interactions.ts
6159
9897
  var flag$5 = (value = false) => ({
6160
9898
  type: Boolean,
@@ -6241,7 +9979,7 @@ function timeSync(self, preserveDraft = false) {
6241
9979
  disabled: false
6242
9980
  }]
6243
9981
  });
6244
- const displayValue = current ? formatTime(current, format) : "";
9982
+ const displayValue = current ? formatTime$1(current, format) : "";
6245
9983
  self.setData({
6246
9984
  effectiveFormat: format,
6247
9985
  hasSeconds: formatHasSeconds(format),
@@ -10281,7 +14019,12 @@ enhanceConfiguration({
10281
14019
  button,
10282
14020
  input,
10283
14021
  toggle,
10284
- ...nativeControls
14022
+ ...nativeControls,
14023
+ chart,
14024
+ lineChart,
14025
+ barChart,
14026
+ scatterChart,
14027
+ quadrantChart
10285
14028
  ]);
10286
14029
  annotateNativeApi({
10287
14030
  button,
@@ -10357,7 +14100,12 @@ annotateNativeApi({
10357
14100
  confirmDialog,
10358
14101
  confirmProvider,
10359
14102
  toastProvider,
10360
- gridItem
14103
+ gridItem,
14104
+ chart,
14105
+ lineChart,
14106
+ barChart,
14107
+ scatterChart,
14108
+ quadrantChart
10361
14109
  });
10362
14110
  //#endregion
10363
14111
  exports.alert = alert;
@@ -10366,10 +14114,12 @@ exports.autoComplete = autoComplete;
10366
14114
  exports.avatar = avatar;
10367
14115
  exports.avatarGroup = avatarGroup;
10368
14116
  exports.badge = badge;
14117
+ exports.barChart = barChart;
10369
14118
  exports.box = box;
10370
14119
  exports.button = button;
10371
14120
  exports.card = card;
10372
14121
  exports.cascader = cascader;
14122
+ exports.chart = chart;
10373
14123
  exports.checkbox = checkbox;
10374
14124
  exports.codeBlock = codeBlock;
10375
14125
  exports.commandDialog = commandDialog;
@@ -10393,6 +14143,7 @@ exports.iconButton = iconButton;
10393
14143
  exports.input = input;
10394
14144
  exports.jsonField = jsonField;
10395
14145
  exports.keyValueEditor = keyValueEditor;
14146
+ exports.lineChart = lineChart;
10396
14147
  exports.list = list;
10397
14148
  exports.loadingState = loadingState;
10398
14149
  exports.menu = menu;
@@ -10407,12 +14158,14 @@ exports.paletteToggle = paletteToggle;
10407
14158
  exports.popover = popover;
10408
14159
  exports.progressIndicator = progressIndicator;
10409
14160
  exports.prose = prose;
14161
+ exports.quadrantChart = quadrantChart;
10410
14162
  exports.radio = radio;
10411
14163
  exports.radioGroup = radioGroup;
10412
14164
  exports.rating = rating;
10413
14165
  exports.ratingScale = ratingScale;
10414
14166
  exports.requestConfirm = requestConfirm;
10415
14167
  exports.responsiveGrid = responsiveGrid;
14168
+ exports.scatterChart = scatterChart;
10416
14169
  exports.select = select;
10417
14170
  exports.skeleton = skeleton;
10418
14171
  exports.skeletonText = skeletonText;