@pixerate/editor 0.166.0 → 0.168.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 (58) hide show
  1. package/THIRD_PARTY_NOTICES.md +11 -0
  2. package/dist/agent/index.cjs +34 -34
  3. package/dist/agent/index.js +5 -5
  4. package/dist/canvas/index.cjs +6 -6
  5. package/dist/canvas/index.js +2 -2
  6. package/dist/chart/index.cjs +236 -185
  7. package/dist/chart/index.d.cts +1 -0
  8. package/dist/chart/index.d.ts +1 -0
  9. package/dist/chart/index.js +57 -6
  10. package/dist/chart/layout-families.d.cts +8 -0
  11. package/dist/chart/layout-families.d.ts +8 -0
  12. package/dist/chart/maps.d.cts +43 -0
  13. package/dist/chart/maps.d.ts +43 -0
  14. package/dist/chart/spec.d.cts +1 -1
  15. package/dist/chart/spec.d.ts +1 -1
  16. package/dist/chart/types.d.cts +10 -2
  17. package/dist/chart/types.d.ts +10 -2
  18. package/dist/chart-maps/europe.d.cts +7 -0
  19. package/dist/chart-maps/europe.d.ts +7 -0
  20. package/dist/chart-maps/index.cjs +66 -0
  21. package/dist/chart-maps/index.d.cts +1 -0
  22. package/dist/chart-maps/index.d.ts +1 -0
  23. package/dist/chart-maps/index.js +66 -0
  24. package/dist/{chunk-V5L2G22R.cjs → chunk-2F4GAZL5.cjs} +109 -95
  25. package/dist/{chunk-5UNQDC3Q.js → chunk-34UCPHYO.js} +5 -2
  26. package/dist/{chunk-6DM3PUQD.cjs → chunk-CYKWYP6D.cjs} +20 -2
  27. package/dist/{chunk-HXOBOHH2.cjs → chunk-E45AIIWY.cjs} +8 -8
  28. package/dist/{chunk-NQQDGGXY.js → chunk-FKYGM35R.js} +2 -2
  29. package/dist/{chunk-6FYIFGBW.cjs → chunk-GD34ICEX.cjs} +16 -16
  30. package/dist/{chunk-MZFZSVUJ.cjs → chunk-GTF4RYXJ.cjs} +25 -22
  31. package/dist/{chunk-ZGOHKS3X.js → chunk-HCC2LBCW.js} +20 -2
  32. package/dist/{chunk-ITANXMZD.js → chunk-M52UCHVZ.js} +127 -3
  33. package/dist/{chunk-YUFTVNLX.js → chunk-N3ACT6VJ.js} +16 -2
  34. package/dist/{chunk-XNU45TYA.js → chunk-OLCHKGGO.js} +4 -1
  35. package/dist/{chunk-FR432ROA.js → chunk-ORZF4JOO.js} +23 -4
  36. package/dist/{chunk-BPX4Z3N3.cjs → chunk-OUO3DSRT.cjs} +23 -4
  37. package/dist/{chunk-CHLV7UFP.cjs → chunk-SBAPXFPB.cjs} +51 -51
  38. package/dist/{chunk-VB2CY6EG.js → chunk-T62BRXMS.js} +3 -3
  39. package/dist/{chunk-SZWVMB3B.cjs → chunk-VKHJJUBK.cjs} +21 -18
  40. package/dist/{chunk-UUUTEVX6.cjs → chunk-WOIXNDHV.cjs} +172 -48
  41. package/dist/{chunk-DFCAR7AW.js → chunk-ZUPP4NKM.js} +3 -3
  42. package/dist/effects/authoring-session.d.cts +5 -0
  43. package/dist/effects/authoring-session.d.ts +5 -0
  44. package/dist/effects/authoring.d.cts +6 -0
  45. package/dist/effects/authoring.d.ts +6 -0
  46. package/dist/effects/index.cjs +12 -6
  47. package/dist/effects/index.js +10 -4
  48. package/dist/export/index.cjs +4 -4
  49. package/dist/export/index.js +3 -3
  50. package/dist/extensions/index.cjs +7 -7
  51. package/dist/extensions/index.js +6 -6
  52. package/dist/index.cjs +13 -13
  53. package/dist/index.js +7 -7
  54. package/dist/video-editor/index.cjs +2 -2
  55. package/dist/video-editor/index.js +1 -1
  56. package/package.json +11 -1
  57. package/skills/pixerate-chart/SKILL.md +18 -2
  58. package/skills/pixerate-effect-authoring/SKILL.md +11 -4
@@ -12,9 +12,9 @@ var _chunkTTCJPX4Ucjs = require('./chunk-TTCJPX4U.cjs');
12
12
 
13
13
 
14
14
 
15
- var _chunkUUUTEVX6cjs = require('./chunk-UUUTEVX6.cjs');
16
15
 
17
16
 
17
+ var _chunkWOIXNDHVcjs = require('./chunk-WOIXNDHV.cjs');
18
18
 
19
19
 
20
20
 
@@ -45,7 +45,9 @@ var _chunkUUUTEVX6cjs = require('./chunk-UUUTEVX6.cjs');
45
45
 
46
46
 
47
47
 
48
- var _chunkBPX4Z3N3cjs = require('./chunk-BPX4Z3N3.cjs');
48
+
49
+
50
+ var _chunkOUO3DSRTcjs = require('./chunk-OUO3DSRT.cjs');
49
51
 
50
52
 
51
53
 
@@ -84,7 +86,7 @@ var csvField = (text) => /[",\n]|^\s|\s$/.test(text) ? `"${text.replace(/"/g, '"
84
86
  var treemapName = (name) => !name.includes('"') ? `"${name}"` : !name.includes("'") ? `'${name}'` : `"${name.replace(/"/g, "'")}"`;
85
87
  var yamlText = (text) => /^[\w][\w .,!?()/&+-]*$/.test(text) && !/:\s/.test(text) ? text : JSON.stringify(text);
86
88
  function chartMermaidFamily(spec) {
87
- const family = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, spec);
89
+ const family = _chunkOUO3DSRTcjs.chartFamily.call(void 0, spec);
88
90
  if (family === "sankey" && _optionalChain([spec, 'access', _2 => _2.links, 'optionalAccess', _3 => _3.length])) return "sankey";
89
91
  if (family === "treemap" || family === "sunburst") return "treemap";
90
92
  if (family === "pie" || family === "funnel" || family === "parliament") return "pie";
@@ -137,7 +139,7 @@ function chartToMermaid(spec, options = {}) {
137
139
  lines.push("treemap-beta");
138
140
  if (spec.title) lines.push(`title ${spec.title}`);
139
141
  const first = _nullishCoalesce(visible[0], () => ( spec.series[0]));
140
- const tree = spec.tree.length ? spec.tree : _chunkBPX4Z3N3cjs.chartTreeFromSeries.call(void 0, spec.categories, _nullishCoalesce(_optionalChain([first, 'optionalAccess', _4 => _4.values]), () => ( [])));
142
+ const tree = spec.tree.length ? spec.tree : _chunkOUO3DSRTcjs.chartTreeFromSeries.call(void 0, spec.categories, _nullishCoalesce(_optionalChain([first, 'optionalAccess', _4 => _4.values]), () => ( [])));
141
143
  const write = (nodes, depth) => {
142
144
  for (const n of nodes) {
143
145
  const pad = ind.repeat(depth);
@@ -272,8 +274,8 @@ function chartFromMermaid(text, options = {}) {
272
274
  let title = _nullishCoalesce(frontTitle, () => ( ""));
273
275
  const categories = [];
274
276
  const series = [];
275
- const xAxis = _chunkBPX4Z3N3cjs.defaultChartAxis.call(void 0, false);
276
- const yAxis = _chunkBPX4Z3N3cjs.defaultChartAxis.call(void 0, true);
277
+ const xAxis = _chunkOUO3DSRTcjs.defaultChartAxis.call(void 0, false);
278
+ const yAxis = _chunkOUO3DSRTcjs.defaultChartAxis.call(void 0, true);
277
279
  const radarAxes = [];
278
280
  const pieSlices = [];
279
281
  let legendShow = true;
@@ -435,7 +437,7 @@ function chartFromMermaid(text, options = {}) {
435
437
  input.series = metaSeries.map((extra, i) => ({ ..._nullishCoalesce(base[i], () => ( {})), ..._nullishCoalesce(extra, () => ( {})) }));
436
438
  }
437
439
  }
438
- const { spec, issues: specIssues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, input);
440
+ const { spec, issues: specIssues } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, input);
439
441
  if (!family && !partial && !issues.length) issues.push({ path: "header", message: "The text is empty: expected a chart header (xychart-beta, pie, radar-beta, sankey-beta or treemap-beta)." });
440
442
  return { spec, issues: [...issues, ...specIssues], family, hasMeta: !!meta };
441
443
  }
@@ -465,7 +467,7 @@ function readWholeMermaid(family, all, headerLine, partial, title, issues) {
465
467
  const tree = items.map(toNode);
466
468
  const leaf = (n) => !n.children;
467
469
  const flatOrOneLevel = tree.every(leaf) || tree.every((n) => _optionalChain([n, 'access', _18 => _18.children, 'optionalAccess', _19 => _19.every, 'call', _20 => _20(leaf)]));
468
- return { type: flatOrOneLevel ? "treemap" : "sunburst", title: name, tree, categories: tree.map((n) => n.name), series: [{ id: "series-1", name: "Values", values: tree.map(_chunkBPX4Z3N3cjs.chartTreeTotal) }] };
470
+ return { type: flatOrOneLevel ? "treemap" : "sunburst", title: name, tree, categories: tree.map((n) => n.name), series: [{ id: "series-1", name: "Values", values: tree.map(_chunkOUO3DSRTcjs.chartTreeTotal) }] };
469
471
  }
470
472
  function findMermaidCharts(text) {
471
473
  const lines = text.replace(/^/, "").split(/\r?\n/);
@@ -510,11 +512,11 @@ function findMermaidCharts(text) {
510
512
  }
511
513
 
512
514
  // src/chart/summary.ts
513
- function summarizeChart(spec, size = { width: 640, height: 400 }, scene = _chunkUUUTEVX6cjs.layoutChart.call(void 0, spec, { ...size, selection: null })) {
515
+ function summarizeChart(spec, size = { width: 640, height: 400 }, scene = _chunkWOIXNDHVcjs.layoutChart.call(void 0, spec, { ...size, selection: null })) {
514
516
  const visible = spec.series.filter((s) => !s.hidden);
515
- const series = visible.map((s) => _chunkUUUTEVX6cjs.summarizeChartSeries.call(void 0, s, spec.categories));
516
- const colors = _chunkBPX4Z3N3cjs.chartSpecColorsByCategory.call(void 0, spec) ? spec.categories.map((_, i) => _optionalChain([visible, 'access', _24 => _24[0], 'optionalAccess', _25 => _25.pointColors, 'optionalAccess', _26 => _26[i]]) || _chunkBPX4Z3N3cjs.chartSliceColor.call(void 0, spec, i)) : visible.map((s) => _chunkBPX4Z3N3cjs.chartSeriesColor.call(void 0, spec, spec.series.indexOf(s)));
517
- const check = _chunkBPX4Z3N3cjs.checkChartColors.call(void 0, colors, { surface: scene.theme.surface.startsWith("var(") ? "#ffffff" : scene.theme.surface });
517
+ const series = visible.map((s) => _chunkWOIXNDHVcjs.summarizeChartSeries.call(void 0, s, spec.categories));
518
+ const colors = _chunkOUO3DSRTcjs.chartSpecColorsByCategory.call(void 0, spec) ? spec.categories.map((_, i) => _optionalChain([visible, 'access', _24 => _24[0], 'optionalAccess', _25 => _25.pointColors, 'optionalAccess', _26 => _26[i]]) || _chunkOUO3DSRTcjs.chartSliceColor.call(void 0, spec, i)) : visible.map((s) => _chunkOUO3DSRTcjs.chartSeriesColor.call(void 0, spec, spec.series.indexOf(s)));
519
+ const check = _chunkOUO3DSRTcjs.checkChartColors.call(void 0, colors, { surface: scene.theme.surface.startsWith("var(") ? "#ffffff" : scene.theme.surface });
518
520
  const axis = (s, a) => s ? { min: s.domain[0], max: s.domain[1], ticks: [...s.ticks], ...s.logBase ? { logBase: s.logBase } : {}, ...a.reverse ? { reversed: true } : {} } : void 0;
519
521
  return {
520
522
  type: spec.type,
@@ -529,12 +531,12 @@ function summarizeChart(spec, size = { width: 640, height: 400 }, scene = _chunk
529
531
  description: describeChart(spec, series)
530
532
  };
531
533
  }
532
- function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((s) => _chunkUUUTEVX6cjs.summarizeChartSeries.call(void 0, s, spec.categories))) {
533
- const kind = _chunkBPX4Z3N3cjs.CHART_TYPE_LABELS[spec.type].toLowerCase();
534
+ function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((s) => _chunkWOIXNDHVcjs.summarizeChartSeries.call(void 0, s, spec.categories))) {
535
+ const kind = _chunkOUO3DSRTcjs.CHART_TYPE_LABELS[spec.type].toLowerCase();
534
536
  const parts = [];
535
- const family = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, spec);
537
+ const family = _chunkOUO3DSRTcjs.chartFamily.call(void 0, spec);
536
538
  const format = spec.yAxis.format;
537
- const fmt = (v) => v === null ? "blank" : _chunkUUUTEVX6cjs.formatChartNumber.call(void 0, v, format);
539
+ const fmt = (v) => v === null ? "blank" : _chunkWOIXNDHVcjs.formatChartNumber.call(void 0, v, format);
538
540
  const head = spec.title ? `${spec.title}: a ${kind} chart` : `A ${kind} chart`;
539
541
  if (!series.length || series.every((s) => s.count === 0)) return `${head} with no data.`;
540
542
  if (family === "pie" || family === "funnel" || family === "treemap" || family === "sunburst") {
@@ -544,16 +546,25 @@ function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((
544
546
  parts.push(`${head} of ${s.name} across ${spec.categories.length} categories, totalling ${fmt(s.sum)}.`);
545
547
  parts.push(`The largest is ${s.maxAt} at ${fmt(s.max)}${share(s.max)}; the smallest is ${s.minAt} at ${fmt(s.min)}${share(s.min)}.`);
546
548
  if (spec.tree.length) {
547
- const depth = _chunkBPX4Z3N3cjs.chartTreeDepth.call(void 0, spec.tree);
548
- const items = _chunkBPX4Z3N3cjs.chartTreeToRows.call(void 0, spec.tree).length;
549
+ const depth = _chunkOUO3DSRTcjs.chartTreeDepth.call(void 0, spec.tree);
550
+ const items = _chunkOUO3DSRTcjs.chartTreeToRows.call(void 0, spec.tree).length;
549
551
  parts.push(`The data is grouped ${depth} level${depth === 1 ? "" : "s"} deep with ${items} item${items === 1 ? "" : "s"}.`);
550
552
  }
551
553
  return parts.join(" ");
552
554
  }
555
+ if (family === "choropleth") {
556
+ const s = spec.series.find((x) => !x.hidden);
557
+ const map = _chunkWOIXNDHVcjs.getChartMap.call(void 0, spec.map);
558
+ const matches = map ? _chunkWOIXNDHVcjs.matchChartMapRegions.call(void 0, map, spec.categories) : spec.categories.map(() => null);
559
+ const rows = spec.categories.flatMap((c, i) => matches[i] && s.values[i] !== null ? [{ name: matches[i].name, v: s.values[i] }] : []).sort((a, b) => b.v - a.v);
560
+ const missing = spec.categories.filter((_, i) => !matches[i]).length;
561
+ if (!rows.length) return `${head} of ${_nullishCoalesce(_optionalChain([map, 'optionalAccess', _27 => _27.name]), () => ( spec.map))} with no regions matched.`;
562
+ return `${head} of ${_nullishCoalesce(_optionalChain([map, 'optionalAccess', _28 => _28.name]), () => ( spec.map))} shading ${rows.length} region${rows.length === 1 ? "" : "s"} by ${s.name}: highest ${rows[0].name} (${fmt(rows[0].v)}), lowest ${rows[rows.length - 1].name} (${fmt(rows[rows.length - 1].v)}).${missing ? ` ${missing} categor${missing === 1 ? "y names" : "ies name"} no region.` : ""}`;
563
+ }
553
564
  if (family === "barrace") {
554
565
  const n = spec.categories.length;
555
- const first = _chunkUUUTEVX6cjs.chartRaceRanking.call(void 0, spec, 0)[0];
556
- const last = _chunkUUUTEVX6cjs.chartRaceRanking.call(void 0, spec, n - 1)[0];
566
+ const first = _chunkWOIXNDHVcjs.chartRaceRanking.call(void 0, spec, 0)[0];
567
+ const last = _chunkWOIXNDHVcjs.chartRaceRanking.call(void 0, spec, n - 1)[0];
557
568
  const lead = (e, at) => e ? `${e.name} leads at ${at} with ${fmt(e.value)}` : "";
558
569
  return `${head} of ${series.length} names over ${n} time points (${spec.categories[0]} to ${spec.categories[n - 1]}), showing the top ${Math.min(spec.raceTopN, series.length)}. ${lead(first, spec.categories[0])}; ${lead(last, spec.categories[n - 1])}.`;
559
570
  }
@@ -571,7 +582,7 @@ function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((
571
582
  const total = seats.reduce((t, x) => t + x.n, 0);
572
583
  const majority = _nullishCoalesce(spec.parliamentMajority, () => ( Math.floor(total / 2) + 1));
573
584
  const largest = [...seats].sort((a, b) => b.n - a.n)[0];
574
- const verdict = largest && largest.n >= majority ? `${largest.c} holds a majority with ${largest.n}` : `no group reaches the majority of ${majority}; the largest is ${_optionalChain([largest, 'optionalAccess', _27 => _27.c])} with ${_optionalChain([largest, 'optionalAccess', _28 => _28.n])}`;
585
+ const verdict = largest && largest.n >= majority ? `${largest.c} holds a majority with ${largest.n}` : `no group reaches the majority of ${majority}; the largest is ${_optionalChain([largest, 'optionalAccess', _29 => _29.c])} with ${_optionalChain([largest, 'optionalAccess', _30 => _30.n])}`;
575
586
  return `${head} of ${total} seats across ${seats.length} groups: ${verdict}.`;
576
587
  }
577
588
  if (family === "slope") {
@@ -594,7 +605,7 @@ function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((
594
605
  });
595
606
  const best = [...agree].sort((x, y) => y.share - x.share);
596
607
  const pct = (v) => `${Math.round(v * 100)}%`;
597
- return `${head} of ${spec.categories.length} questions with ${answers.length} answers from ${_optionalChain([answers, 'access', _29 => _29[0], 'optionalAccess', _30 => _30.name])} to ${_optionalChain([answers, 'access', _31 => _31[answers.length - 1], 'optionalAccess', _32 => _32.name])}. Most positive: ${_optionalChain([best, 'access', _33 => _33[0], 'optionalAccess', _34 => _34.c])} (${pct(_nullishCoalesce(_optionalChain([best, 'access', _35 => _35[0], 'optionalAccess', _36 => _36.share]), () => ( 0)))}); least: ${_optionalChain([best, 'access', _37 => _37[best.length - 1], 'optionalAccess', _38 => _38.c])} (${pct(_nullishCoalesce(_optionalChain([best, 'access', _39 => _39[best.length - 1], 'optionalAccess', _40 => _40.share]), () => ( 0)))}).`;
608
+ return `${head} of ${spec.categories.length} questions with ${answers.length} answers from ${_optionalChain([answers, 'access', _31 => _31[0], 'optionalAccess', _32 => _32.name])} to ${_optionalChain([answers, 'access', _33 => _33[answers.length - 1], 'optionalAccess', _34 => _34.name])}. Most positive: ${_optionalChain([best, 'access', _35 => _35[0], 'optionalAccess', _36 => _36.c])} (${pct(_nullishCoalesce(_optionalChain([best, 'access', _37 => _37[0], 'optionalAccess', _38 => _38.share]), () => ( 0)))}); least: ${_optionalChain([best, 'access', _39 => _39[best.length - 1], 'optionalAccess', _40 => _40.c])} (${pct(_nullishCoalesce(_optionalChain([best, 'access', _41 => _41[best.length - 1], 'optionalAccess', _42 => _42.share]), () => ( 0)))}).`;
598
609
  }
599
610
  if (family === "waterfall") {
600
611
  const s = spec.series.find((x) => !x.hidden);
@@ -633,7 +644,7 @@ function describeChart(spec, series = spec.series.filter((s) => !s.hidden).map((
633
644
  }
634
645
  parts.push(...axes);
635
646
  for (const s of spec.series.filter((x) => !x.hidden && (x.errorBars || x.xErrorBars)).slice(0, 8)) {
636
- const bars = [s.errorBars ? _chunkBPX4Z3N3cjs.describeChartErrorBars.call(void 0, s.errorBars) : "", s.xErrorBars ? `x ${_chunkBPX4Z3N3cjs.describeChartErrorBars.call(void 0, s.xErrorBars)}` : ""].filter(Boolean).join(" and ");
647
+ const bars = [s.errorBars ? _chunkOUO3DSRTcjs.describeChartErrorBars.call(void 0, s.errorBars) : "", s.xErrorBars ? `x ${_chunkOUO3DSRTcjs.describeChartErrorBars.call(void 0, s.xErrorBars)}` : ""].filter(Boolean).join(" and ");
637
648
  parts.push(`${s.name} has ${bars}.`);
638
649
  }
639
650
  return parts.join(" ");
@@ -698,7 +709,7 @@ function chartSceneToSvg(scene, options = {}) {
698
709
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${scene.width}" height="${scene.height}" viewBox="0 0 ${scene.width} ${scene.height}" role="img"${label ? ` aria-label="${escape(label)}"` : ""}${labelled ? ` aria-labelledby="${labelled}"` : ""}>${head}${body}</svg>`;
699
710
  }
700
711
  function chartToSvg(spec, options) {
701
- const scene = _chunkUUUTEVX6cjs.layoutChart.call(void 0, spec, { ...options, selection: null });
712
+ const scene = _chunkWOIXNDHVcjs.layoutChart.call(void 0, spec, { ...options, selection: null });
702
713
  return chartSceneToSvg(scene, { ...options, ariaLabel: _nullishCoalesce(options.ariaLabel, () => ( (spec.title || void 0))), description: _nullishCoalesce(options.description, () => ( describeChart(spec))) });
703
714
  }
704
715
  var SVG_NS = "http://www.w3.org/2000/svg";
@@ -736,10 +747,10 @@ var CHART_LAYOUT_PRESETS = [
736
747
  ];
737
748
  function monochromeChartPalette(base, count = 6) {
738
749
  const steps = count <= 1 ? [0] : Array.from({ length: count }, (_, i) => -0.45 + 1.05 * i / (count - 1));
739
- return steps.map((t) => _chunkBPX4Z3N3cjs.shadeChartColor.call(void 0, base, t));
750
+ return steps.map((t) => _chunkOUO3DSRTcjs.shadeChartColor.call(void 0, base, t));
740
751
  }
741
752
  var CHART_COLOR_SCHEMES = [
742
- { id: "default", label: "Default", description: "Ten distinct colours, readable on light and dark backgrounds.", palette: _chunkBPX4Z3N3cjs.DEFAULT_CHART_PALETTE },
753
+ { id: "default", label: "Default", description: "Ten distinct colours, readable on light and dark backgrounds.", palette: _chunkOUO3DSRTcjs.DEFAULT_CHART_PALETTE },
743
754
  { id: "okabe-ito", label: "Okabe\u2013Ito", description: "Eight colours chosen to stay distinct with colour-blindness.", palette: ["#e69f00", "#56b4e9", "#009e73", "#f0e442", "#0072b2", "#d55e00", "#cc79a7", "#000000"] },
744
755
  { id: "office", label: "Office", description: "The six accent colours of the default Office theme.", palette: ["#4472c4", "#ed7d31", "#a5a5a5", "#ffc000", "#5b9bd5", "#70ad47"] },
745
756
  { id: "warm", label: "Warm", description: "Reds, oranges and yellows.", palette: ["#b2182b", "#d6604d", "#f4a582", "#e08214", "#fdb863", "#8c510a"] },
@@ -767,7 +778,7 @@ function chartPresetPatch(options) {
767
778
 
768
779
  // src/chart/controller.ts
769
780
  function pointLists(s) {
770
- const lists = [s.values, s.x, s.sizes, s.pointColors, s.callouts, _optionalChain([s, 'access', _41 => _41.errorBars, 'optionalAccess', _42 => _42.plus]), _optionalChain([s, 'access', _43 => _43.errorBars, 'optionalAccess', _44 => _44.minus]), _optionalChain([s, 'access', _45 => _45.xErrorBars, 'optionalAccess', _46 => _46.plus]), _optionalChain([s, 'access', _47 => _47.xErrorBars, 'optionalAccess', _48 => _48.minus])];
781
+ const lists = [s.values, s.x, s.sizes, s.pointColors, s.callouts, _optionalChain([s, 'access', _43 => _43.errorBars, 'optionalAccess', _44 => _44.plus]), _optionalChain([s, 'access', _45 => _45.errorBars, 'optionalAccess', _46 => _46.minus]), _optionalChain([s, 'access', _47 => _47.xErrorBars, 'optionalAccess', _48 => _48.plus]), _optionalChain([s, 'access', _49 => _49.xErrorBars, 'optionalAccess', _50 => _50.minus])];
771
782
  return lists.filter((l) => Array.isArray(l));
772
783
  }
773
784
  function sameChartJson(a, b) {
@@ -817,14 +828,14 @@ var ChartController = (_class = class {
817
828
  this.history = _nullishCoalesce(options.history, () => ( new (0, _chunkFJ2MSI43cjs.HistoryManager)()));
818
829
  this.onChange = options.onChange;
819
830
  this.raceTicker = _nullishCoalesce(options.raceTicker, () => ( defaultRaceTicker));
820
- const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, _nullishCoalesce(options.spec, () => ( {})));
831
+ const { spec, issues } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, _nullishCoalesce(options.spec, () => ( {})));
821
832
  this.spec = spec;
822
833
  this.issues = issues;
823
834
  this.state = this.computeState();
824
835
  this.connect();
825
836
  }
826
837
  connect() {
827
- _optionalChain([this, 'access', _49 => _49.unsubscribeHistory, 'optionalCall', _50 => _50()]);
838
+ _optionalChain([this, 'access', _51 => _51.unsubscribeHistory, 'optionalCall', _52 => _52()]);
828
839
  this.unsubscribeHistory = this.history.subscribe((h) => {
829
840
  const s = this.state;
830
841
  if (this.applying || s.canUndo === h.canUndo && s.canRedo === h.canRedo && s.undoLabel === h.undoName && s.redoLabel === h.redoName) return;
@@ -854,12 +865,12 @@ var ChartController = (_class = class {
854
865
  computeState() {
855
866
  const h = this.history.getState();
856
867
  const sel = this.selection;
857
- const seriesId = _optionalChain([sel, 'optionalAccess', _51 => _51.kind]) === "series" || _optionalChain([sel, 'optionalAccess', _52 => _52.kind]) === "point" || _optionalChain([sel, 'optionalAccess', _53 => _53.kind]) === "trendline" ? sel.seriesId : null;
868
+ const seriesId = _optionalChain([sel, 'optionalAccess', _53 => _53.kind]) === "series" || _optionalChain([sel, 'optionalAccess', _54 => _54.kind]) === "point" || _optionalChain([sel, 'optionalAccess', _55 => _55.kind]) === "trendline" ? sel.seriesId : null;
858
869
  return {
859
870
  spec: this.spec,
860
871
  selection: sel,
861
872
  selectedSeries: seriesId ? _nullishCoalesce(this.spec.series.find((s) => s.id === seriesId), () => ( null)) : null,
862
- selectedIndex: _optionalChain([sel, 'optionalAccess', _54 => _54.kind]) === "point" || _optionalChain([sel, 'optionalAccess', _55 => _55.kind]) === "category" ? sel.index : null,
873
+ selectedIndex: _optionalChain([sel, 'optionalAccess', _56 => _56.kind]) === "point" || _optionalChain([sel, 'optionalAccess', _57 => _57.kind]) === "category" ? sel.index : null,
863
874
  issues: this.issues,
864
875
  gesture: this.gestureKey,
865
876
  canUndo: h.canUndo,
@@ -874,7 +885,7 @@ var ChartController = (_class = class {
874
885
  notify(specChanged) {
875
886
  this.revision++;
876
887
  this.state = this.computeState();
877
- if (specChanged) _optionalChain([this, 'access', _56 => _56.onChange, 'optionalCall', _57 => _57(this.spec)]);
888
+ if (specChanged) _optionalChain([this, 'access', _58 => _58.onChange, 'optionalCall', _59 => _59(this.spec)]);
878
889
  const state = this.state;
879
890
  this.listeners.forEach((listener) => {
880
891
  try {
@@ -898,7 +909,7 @@ var ChartController = (_class = class {
898
909
  case "category":
899
910
  return sel.index < spec.categories.length ? sel : null;
900
911
  case "trendline":
901
- return _optionalChain([spec, 'access', _58 => _58.series, 'access', _59 => _59.find, 'call', _60 => _60((s) => s.id === sel.seriesId), 'optionalAccess', _61 => _61.trendlines, 'optionalAccess', _62 => _62[sel.index]]) ? sel : null;
912
+ return _optionalChain([spec, 'access', _60 => _60.series, 'access', _61 => _61.find, 'call', _62 => _62((s) => s.id === sel.seriesId), 'optionalAccess', _63 => _63.trendlines, 'optionalAccess', _64 => _64[sel.index]]) ? sel : null;
902
913
  case "title":
903
914
  return spec.title ? sel : null;
904
915
  case "subtitle":
@@ -922,7 +933,7 @@ var ChartController = (_class = class {
922
933
  const hadIssues = this.issues.length > 0;
923
934
  this.issues = [];
924
935
  if (sameChartJson(before, next)) {
925
- const reselect = select !== void 0 && !_chunkUUUTEVX6cjs.sameChartSelection.call(void 0, this.selection, select) && !(select === null && this.selection === null);
936
+ const reselect = select !== void 0 && !_chunkWOIXNDHVcjs.sameChartSelection.call(void 0, this.selection, select) && !(select === null && this.selection === null);
926
937
  if (reselect) this.selection = select;
927
938
  if (reselect || hadIssues) this.notify(false);
928
939
  return;
@@ -945,7 +956,7 @@ var ChartController = (_class = class {
945
956
  }
946
957
  /** A copy of the spec with `edit` applied (series and categories copied as needed). */
947
958
  edited(edit) {
948
- const draft = _chunkBPX4Z3N3cjs.cloneChartSpec.call(void 0, this.spec);
959
+ const draft = _chunkOUO3DSRTcjs.cloneChartSpec.call(void 0, this.spec);
949
960
  edit(draft);
950
961
  return draft;
951
962
  }
@@ -975,7 +986,7 @@ var ChartController = (_class = class {
975
986
  legend: patch.legend ? { ...s.legend, ...patch.legend } : s.legend,
976
987
  version: 1
977
988
  };
978
- const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, merged);
989
+ const { spec, issues } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, merged);
979
990
  if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
980
991
  if (JSON.stringify(spec) === JSON.stringify(s)) return { ok: true };
981
992
  this.commit(_nullishCoalesce(options.label, () => ( updateLabel(patch))), spec);
@@ -1029,7 +1040,7 @@ var ChartController = (_class = class {
1029
1040
  const series = this.getSeries(seriesId);
1030
1041
  if (!series) return this.unknownSeries(seriesId);
1031
1042
  if (!Number.isInteger(index) || index < 0 || index >= this.spec.categories.length) return this.badIndex(index);
1032
- const parsed = _chunkBPX4Z3N3cjs.parseChartValue.call(void 0, value);
1043
+ const parsed = _chunkOUO3DSRTcjs.parseChartValue.call(void 0, value);
1033
1044
  if (parsed === void 0) return this.reject(`"${String(value)}" is not a number; enter a number or leave the cell blank.`, [{ path: `${seriesId}[${index}]`, message: `"${String(value)}" is not a number.` }]);
1034
1045
  if (series.values[index] === parsed) {
1035
1046
  if (this.issues.length) {
@@ -1054,7 +1065,7 @@ var ChartController = (_class = class {
1054
1065
  if (!this.getSeries(cell.seriesId)) issues.push({ path: cell.seriesId, message: this.unknownSeries(cell.seriesId).message });
1055
1066
  else if (!Number.isInteger(cell.index) || cell.index < 0 || cell.index >= this.spec.categories.length) issues.push({ path: `${cell.seriesId}[${cell.index}]`, message: this.badIndex(cell.index).message });
1056
1067
  else {
1057
- const value = _chunkBPX4Z3N3cjs.parseChartValue.call(void 0, cell.value);
1068
+ const value = _chunkOUO3DSRTcjs.parseChartValue.call(void 0, cell.value);
1058
1069
  if (value === void 0) issues.push({ path: `${cell.seriesId}[${cell.index}]`, message: `"${String(cell.value)}" is not a number.` });
1059
1070
  else parsed.push({ seriesId: cell.seriesId, index: cell.index, value });
1060
1071
  }
@@ -1068,12 +1079,12 @@ var ChartController = (_class = class {
1068
1079
  }
1069
1080
  /** Adds a series (values padded to the categories) and selects it. Returns its id. */
1070
1081
  addSeries(input = {}, options = {}) {
1071
- const id = input.id && !this.getSeries(input.id) ? input.id : _chunkBPX4Z3N3cjs.uniqueChartSeriesId.call(void 0, this.spec.series);
1082
+ const id = input.id && !this.getSeries(input.id) ? input.id : _chunkOUO3DSRTcjs.uniqueChartSeriesId.call(void 0, this.spec.series);
1072
1083
  const name = _nullishCoalesce(input.name, () => ( `Series ${this.spec.series.length + 1}`));
1073
1084
  const at = Math.max(0, Math.min(this.spec.series.length, _nullishCoalesce(options.at, () => ( this.spec.series.length))));
1074
1085
  const series = [...this.spec.series];
1075
1086
  series.splice(at, 0, { ...input, id, name, values: _nullishCoalesce(input.values, () => ( [])) });
1076
- const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, { ...this.spec, series });
1087
+ const { spec, issues } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, { ...this.spec, series });
1077
1088
  if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1078
1089
  this.commit(`Add series "${name}"`, spec, { kind: "series", seriesId: id });
1079
1090
  return { ok: true, id };
@@ -1093,7 +1104,7 @@ var ChartController = (_class = class {
1093
1104
  updateSeries(id, patch) {
1094
1105
  const series = this.getSeries(id);
1095
1106
  if (!series) return this.unknownSeries(id);
1096
- const next = _chunkBPX4Z3N3cjs.cloneChartSeries.call(void 0, series);
1107
+ const next = _chunkOUO3DSRTcjs.cloneChartSeries.call(void 0, series);
1097
1108
  if (patch.name !== void 0) next.name = String(patch.name);
1098
1109
  if (patch.color === null || patch.color === "") delete next.color;
1099
1110
  else if (patch.color !== void 0) next.color = patch.color;
@@ -1113,7 +1124,7 @@ var ChartController = (_class = class {
1113
1124
  const series2 = this.spec.series.map((s) => s.id === id ? next : s);
1114
1125
  const renamed = next.name !== series.name && this.spec.highlight.includes(series.name) && !this.spec.categories.includes(series.name);
1115
1126
  const highlight = renamed ? this.spec.highlight.map((h) => h === series.name ? next.name : h) : this.spec.highlight;
1116
- const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, { ...this.spec, series: series2, highlight });
1127
+ const { spec, issues } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, { ...this.spec, series: series2, highlight });
1117
1128
  if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1118
1129
  if (JSON.stringify(spec.series) === JSON.stringify(this.spec.series)) return { ok: true };
1119
1130
  const label = patch.hidden !== void 0 && Object.keys(patch).length === 1 ? `${patch.hidden ? "Hide" : "Show"} "${series.name}"` : patch.name !== void 0 && Object.keys(patch).length === 1 ? "Rename series" : `Change series "${series.name}"`;
@@ -1219,7 +1230,7 @@ var ChartController = (_class = class {
1219
1230
  const width = Math.max(...rows.map((r) => r.length));
1220
1231
  const lastSeries = column + width - 1;
1221
1232
  while (d.series.length <= lastSeries) {
1222
- const id = _chunkBPX4Z3N3cjs.uniqueChartSeriesId.call(void 0, d.series);
1233
+ const id = _chunkOUO3DSRTcjs.uniqueChartSeriesId.call(void 0, d.series);
1223
1234
  d.series.push({ id, name: `Series ${d.series.length + 1}`, values: d.categories.map(() => null) });
1224
1235
  }
1225
1236
  const lastRow = row + rows.length - 1;
@@ -1233,7 +1244,7 @@ var ChartController = (_class = class {
1233
1244
  const index = row + r;
1234
1245
  if (col < 0) d.categories[index] = cell === null || cell === void 0 ? "" : String(cell).trim();
1235
1246
  else {
1236
- const parsed = _chunkBPX4Z3N3cjs.parseChartValue.call(void 0, cell);
1247
+ const parsed = _chunkOUO3DSRTcjs.parseChartValue.call(void 0, cell);
1237
1248
  if (parsed === void 0) issues.push({ path: `${d.series[col].id}[${index}]`, message: `"${String(cell)}" is not a number; it was left blank.` });
1238
1249
  d.series[col].values[index] = _nullishCoalesce(parsed, () => ( null));
1239
1250
  }
@@ -1252,14 +1263,14 @@ var ChartController = (_class = class {
1252
1263
  * colours and types are kept by name.
1253
1264
  */
1254
1265
  importTable(rows, options = {}) {
1255
- const data = _chunkBPX4Z3N3cjs.chartDataFromTable.call(void 0, rows, options);
1266
+ const data = _chunkOUO3DSRTcjs.chartDataFromTable.call(void 0, rows, options);
1256
1267
  if (!data.categories.length || !data.series.length) return this.reject("There is no data to import: expected a header row and at least one row of values.");
1257
1268
  const byName = new Map(this.spec.series.map((s) => [s.name, s]));
1258
1269
  const series = data.series.map((s) => {
1259
1270
  const old = byName.get(s.name);
1260
- return { ...s, ..._optionalChain([old, 'optionalAccess', _63 => _63.color]) ? { color: old.color } : {}, ..._optionalChain([old, 'optionalAccess', _64 => _64.type]) ? { type: old.type } : {}, ...old ? { id: old.id } : {} };
1271
+ return { ...s, ..._optionalChain([old, 'optionalAccess', _65 => _65.color]) ? { color: old.color } : {}, ..._optionalChain([old, 'optionalAccess', _66 => _66.type]) ? { type: old.type } : {}, ...old ? { id: old.id } : {} };
1261
1272
  });
1262
- const { spec } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, { ...this.spec, categories: data.categories, series, tree: [], links: [] });
1273
+ const { spec } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, { ...this.spec, categories: data.categories, series, tree: [], links: [] });
1263
1274
  this.commit("Import data", spec);
1264
1275
  if (data.issues.length) {
1265
1276
  this.issues = data.issues;
@@ -1290,7 +1301,7 @@ var ChartController = (_class = class {
1290
1301
  /** Replaces the grouped data (an empty list goes back to the table, keeping the totals as values). One undo step. */
1291
1302
  setTree(tree, options = {}) {
1292
1303
  const issues = [];
1293
- const next = _chunkBPX4Z3N3cjs.normalizeChartTree.call(void 0, tree, issues);
1304
+ const next = _chunkOUO3DSRTcjs.normalizeChartTree.call(void 0, tree, issues);
1294
1305
  if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1295
1306
  return this.update({ tree: next, links: [] }, { label: _nullishCoalesce(options.label, () => ( (next.length ? "Replace grouped data" : "Ungroup data"))) });
1296
1307
  }
@@ -1300,12 +1311,12 @@ var ChartController = (_class = class {
1300
1311
  */
1301
1312
  setTreeRows(rows, options = {}) {
1302
1313
  const issues = [];
1303
- const next = _chunkBPX4Z3N3cjs.chartTreeFromRows.call(void 0, rows, issues);
1314
+ const next = _chunkOUO3DSRTcjs.chartTreeFromRows.call(void 0, rows, issues);
1304
1315
  if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1305
1316
  const keepColors = (list, prefix) => {
1306
1317
  for (const n of list) {
1307
- const old = _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, this.spec.tree, [...prefix, n.name]);
1308
- if (_optionalChain([old, 'optionalAccess', _65 => _65.color])) n.color = old.color;
1318
+ const old = _chunkOUO3DSRTcjs.findChartTreeNode.call(void 0, this.spec.tree, [...prefix, n.name]);
1319
+ if (_optionalChain([old, 'optionalAccess', _67 => _67.color])) n.color = old.color;
1309
1320
  if (n.children) keepColors(n.children, [...prefix, n.name]);
1310
1321
  }
1311
1322
  };
@@ -1315,16 +1326,16 @@ var ChartController = (_class = class {
1315
1326
  /** Replaces the data with a table of names and values (group, …, item, value); see `chartTreeFromTable`. */
1316
1327
  importTreeTable(rows, options = {}) {
1317
1328
  const issues = [];
1318
- const next = _chunkBPX4Z3N3cjs.chartTreeFromTable.call(void 0, rows, options, issues);
1329
+ const next = _chunkOUO3DSRTcjs.chartTreeFromTable.call(void 0, rows, options, issues);
1319
1330
  if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1320
1331
  if (!next.length) return this.reject('There is no grouped data to import: expected rows of names followed by a value, e.g. "Europe,France,40".');
1321
1332
  return this.update({ tree: next, links: [] }, { label: "Import grouped data" });
1322
1333
  }
1323
1334
  nodeAt(path) {
1324
- const node = _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, this.spec.tree, path);
1335
+ const node = _chunkOUO3DSRTcjs.findChartTreeNode.call(void 0, this.spec.tree, path);
1325
1336
  if (node) return node;
1326
- const known = path.length > 1 ? _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, this.spec.tree, path.slice(0, -1)) : null;
1327
- const siblings = _nullishCoalesce((path.length > 1 ? _optionalChain([known, 'optionalAccess', _66 => _66.children]) : this.spec.tree), () => ( []));
1337
+ const known = path.length > 1 ? _chunkOUO3DSRTcjs.findChartTreeNode.call(void 0, this.spec.tree, path.slice(0, -1)) : null;
1338
+ const siblings = _nullishCoalesce((path.length > 1 ? _optionalChain([known, 'optionalAccess', _68 => _68.children]) : this.spec.tree), () => ( []));
1328
1339
  return fail(
1329
1340
  `There is no node ${JSON.stringify(path)}. ${siblings.length ? `${path.length > 1 && known ? `"${known.name}" contains` : "The top level has"} ${siblings.map((n) => `"${n.name}"`).slice(0, 20).join(", ")}.` : "The chart has no grouped data yet; add nodes with add_chart_tree_node or set_chart_tree."}`
1330
1341
  );
@@ -1339,12 +1350,12 @@ var ChartController = (_class = class {
1339
1350
  siblings = group.children;
1340
1351
  }
1341
1352
  const issues = [];
1342
- const [node] = _chunkBPX4Z3N3cjs.normalizeChartTree.call(void 0, [input], issues, "node");
1353
+ const [node] = _chunkOUO3DSRTcjs.normalizeChartTree.call(void 0, [input], issues, "node");
1343
1354
  if (!node || issues.length) return this.reject(issues.map((i) => i.message).join(" ") || "The node is not valid.", issues);
1344
1355
  if (siblings.some((n) => n.name === node.name)) return this.reject(`"${node.name}" is already there; names under one group must be unique.`);
1345
1356
  const at = Math.max(0, Math.min(siblings.length, _nullishCoalesce(options.at, () => ( siblings.length))));
1346
- const tree = _chunkBPX4Z3N3cjs.cloneChartTree.call(void 0, this.spec.tree);
1347
- const list = parent.length ? _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, tree, parent).children : tree;
1357
+ const tree = _chunkOUO3DSRTcjs.cloneChartTree.call(void 0, this.spec.tree);
1358
+ const list = parent.length ? _chunkOUO3DSRTcjs.findChartTreeNode.call(void 0, tree, parent).children : tree;
1348
1359
  list.splice(at, 0, node);
1349
1360
  const result = this.update({ tree }, { label: `Add "${node.name}"` });
1350
1361
  if (!result.ok) return result;
@@ -1356,16 +1367,16 @@ var ChartController = (_class = class {
1356
1367
  if ("ok" in node) return node;
1357
1368
  if (patch.value !== void 0 && node.children) return this.reject(`"${node.name}" is a group: its value is the sum of its items. Change the items instead.`);
1358
1369
  const name = patch.name !== void 0 ? String(patch.name).trim() : node.name;
1359
- const siblings = (path.length > 1 ? _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, this.spec.tree, path.slice(0, -1)).children : this.spec.tree).filter((n) => n !== node);
1370
+ const siblings = (path.length > 1 ? _chunkOUO3DSRTcjs.findChartTreeNode.call(void 0, this.spec.tree, path.slice(0, -1)).children : this.spec.tree).filter((n) => n !== node);
1360
1371
  if (siblings.some((n) => n.name === name)) return this.reject(`There is already a "${name}" next to "${node.name}"; names under one group must be unique.`);
1361
- const tree = _chunkBPX4Z3N3cjs.cloneChartTree.call(void 0, this.spec.tree);
1362
- const target = _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, tree, path);
1372
+ const tree = _chunkOUO3DSRTcjs.cloneChartTree.call(void 0, this.spec.tree);
1373
+ const target = _chunkOUO3DSRTcjs.findChartTreeNode.call(void 0, tree, path);
1363
1374
  const merged = { ...target, name };
1364
1375
  if (patch.value !== void 0) merged.value = patch.value;
1365
1376
  if (patch.color === null) delete merged.color;
1366
1377
  else if (patch.color !== void 0) merged.color = patch.color;
1367
1378
  const issues = [];
1368
- const [checked] = _chunkBPX4Z3N3cjs.normalizeChartTree.call(void 0, [merged], issues, "node");
1379
+ const [checked] = _chunkOUO3DSRTcjs.normalizeChartTree.call(void 0, [merged], issues, "node");
1369
1380
  if (!checked || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1370
1381
  Object.assign(target, checked);
1371
1382
  if (patch.color === null) delete target.color;
@@ -1377,8 +1388,8 @@ var ChartController = (_class = class {
1377
1388
  removeTreeNode(path) {
1378
1389
  const node = this.nodeAt(path);
1379
1390
  if ("ok" in node) return node;
1380
- const tree = _chunkBPX4Z3N3cjs.cloneChartTree.call(void 0, this.spec.tree);
1381
- const parent = path.length > 1 ? _chunkBPX4Z3N3cjs.findChartTreeNode.call(void 0, tree, path.slice(0, -1)) : null;
1391
+ const tree = _chunkOUO3DSRTcjs.cloneChartTree.call(void 0, this.spec.tree);
1392
+ const parent = path.length > 1 ? _chunkOUO3DSRTcjs.findChartTreeNode.call(void 0, tree, path.slice(0, -1)) : null;
1382
1393
  const list = parent ? parent.children : tree;
1383
1394
  list.splice(
1384
1395
  list.findIndex((n) => n.name === node.name),
@@ -1399,7 +1410,7 @@ var ChartController = (_class = class {
1399
1410
  */
1400
1411
  setLinks(links, options = {}) {
1401
1412
  const issues = [];
1402
- const next = _chunkBPX4Z3N3cjs.normalizeChartLinks.call(void 0, links, issues);
1413
+ const next = _chunkOUO3DSRTcjs.normalizeChartLinks.call(void 0, links, issues);
1403
1414
  if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1404
1415
  const used = new Set(next.flatMap((l) => [l.source, l.target]));
1405
1416
  const sankeyNodes = options.nodes ? [...options.nodes] : this.spec.sankeyNodes.filter((n) => used.has(n));
@@ -1407,7 +1418,7 @@ var ChartController = (_class = class {
1407
1418
  }
1408
1419
  /** Replaces the data with flows from a table of source, target and value columns. */
1409
1420
  importLinksTable(rows, options = {}) {
1410
- const raw = _chunkBPX4Z3N3cjs.chartLinksFromTable.call(void 0, rows, options);
1421
+ const raw = _chunkOUO3DSRTcjs.chartLinksFromTable.call(void 0, rows, options);
1411
1422
  if (!raw.length) return this.reject('There are no flows to import: expected rows of source, target and value, e.g. "Website,Signup,120".');
1412
1423
  return this.setLinks(raw, { label: "Import flows" });
1413
1424
  }
@@ -1417,7 +1428,7 @@ var ChartController = (_class = class {
1417
1428
  }
1418
1429
  /** Adds a flow and returns its index. */
1419
1430
  addLink(link) {
1420
- const result = this.setLinks([...this.spec.links, link], { label: `Add flow ${String(_nullishCoalesce(_optionalChain([link, 'optionalAccess', _67 => _67.source]), () => ( "")))} \u2192 ${String(_nullishCoalesce(_optionalChain([link, 'optionalAccess', _68 => _68.target]), () => ( "")))}` });
1431
+ const result = this.setLinks([...this.spec.links, link], { label: `Add flow ${String(_nullishCoalesce(_optionalChain([link, 'optionalAccess', _69 => _69.source]), () => ( "")))} \u2192 ${String(_nullishCoalesce(_optionalChain([link, 'optionalAccess', _70 => _70.target]), () => ( "")))}` });
1421
1432
  if (!result.ok) return result;
1422
1433
  return { ok: true, index: this.spec.links.length - 1 };
1423
1434
  }
@@ -1471,7 +1482,7 @@ var ChartController = (_class = class {
1471
1482
  /** Why a reference on `axis` at `values` cannot be drawn on this chart, or null. */
1472
1483
  referenceProblem(axis, values) {
1473
1484
  const s = this.spec;
1474
- const family = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, s);
1485
+ const family = _chunkOUO3DSRTcjs.chartFamily.call(void 0, s);
1475
1486
  if (family !== "cartesian" && family !== "xy") return `Reference lines and bands are drawn on bar, line, area, scatter and bubble charts; this is a ${s.type} chart.`;
1476
1487
  if (axis === "x" && family !== "xy") return 'axis "x" needs a scatter or bubble chart with numeric x values; use "y" for the value axis.';
1477
1488
  if (axis === "y2" && (family !== "cartesian" || !s.series.some((x) => !x.hidden && x.axis === "secondary")))
@@ -1490,7 +1501,7 @@ var ChartController = (_class = class {
1490
1501
  /** Adds a reference line (a target, floor or average). Returns its index. */
1491
1502
  addReferenceLine(input) {
1492
1503
  const issues = [];
1493
- const line = _chunkBPX4Z3N3cjs.normalizeChartReferenceLine.call(void 0, input, "referenceLine", issues);
1504
+ const line = _chunkOUO3DSRTcjs.normalizeChartReferenceLine.call(void 0, input, "referenceLine", issues);
1494
1505
  if (!line || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1495
1506
  const problem = this.referenceProblem(line.axis, [line.value]);
1496
1507
  if (problem) return this.reject(problem);
@@ -1505,7 +1516,7 @@ var ChartController = (_class = class {
1505
1516
  const merged = { ...current, ...patch };
1506
1517
  for (const [k, v] of Object.entries(patch)) if (v === null) delete merged[k];
1507
1518
  const issues = [];
1508
- const line = _chunkBPX4Z3N3cjs.normalizeChartReferenceLine.call(void 0, merged, "referenceLine", issues);
1519
+ const line = _chunkOUO3DSRTcjs.normalizeChartReferenceLine.call(void 0, merged, "referenceLine", issues);
1509
1520
  if (!line || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1510
1521
  const problem = this.referenceProblem(line.axis, [line.value]);
1511
1522
  if (problem) return this.reject(problem);
@@ -1520,7 +1531,7 @@ var ChartController = (_class = class {
1520
1531
  /** Adds a reference band (a target range). Returns its index. */
1521
1532
  addReferenceBand(input) {
1522
1533
  const issues = [];
1523
- const band = _chunkBPX4Z3N3cjs.normalizeChartReferenceBand.call(void 0, input, "referenceBand", issues);
1534
+ const band = _chunkOUO3DSRTcjs.normalizeChartReferenceBand.call(void 0, input, "referenceBand", issues);
1524
1535
  if (!band || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1525
1536
  const problem = this.referenceProblem(band.axis, [band.from, band.to]);
1526
1537
  if (problem) return this.reject(problem);
@@ -1535,7 +1546,7 @@ var ChartController = (_class = class {
1535
1546
  const merged = { ...current, ...patch };
1536
1547
  for (const [k, v] of Object.entries(patch)) if (v === null) delete merged[k];
1537
1548
  const issues = [];
1538
- const band = _chunkBPX4Z3N3cjs.normalizeChartReferenceBand.call(void 0, merged, "referenceBand", issues);
1549
+ const band = _chunkOUO3DSRTcjs.normalizeChartReferenceBand.call(void 0, merged, "referenceBand", issues);
1539
1550
  if (!band || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1540
1551
  const problem = this.referenceProblem(band.axis, [band.from, band.to]);
1541
1552
  if (problem) return this.reject(problem);
@@ -1558,7 +1569,7 @@ var ChartController = (_class = class {
1558
1569
  const series = this.getSeries(seriesId);
1559
1570
  if (!series) return this.unknownSeries(seriesId);
1560
1571
  if (!Number.isInteger(index) || index < 0 || index >= this.spec.categories.length) return this.badIndex(index);
1561
- const family = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, this.spec);
1572
+ const family = _chunkOUO3DSRTcjs.chartFamily.call(void 0, this.spec);
1562
1573
  const text = label === null ? "" : String(label).trim();
1563
1574
  if (text && family !== "cartesian" && family !== "xy") return this.reject(`Callouts are drawn on bar, line, area, scatter and bubble charts; this is a ${this.spec.type} chart.`);
1564
1575
  if (text && (series.values[index] === null || series.values[index] === void 0))
@@ -1580,12 +1591,12 @@ var ChartController = (_class = class {
1580
1591
  addTrendline(seriesId, input) {
1581
1592
  const series = this.getSeries(seriesId);
1582
1593
  if (!series) return this.unknownSeries(seriesId);
1583
- if (!_chunkUUUTEVX6cjs.chartSupportsTrendlines.call(void 0, this.spec.type, this.spec.stacking))
1594
+ if (!_chunkWOIXNDHVcjs.chartSupportsTrendlines.call(void 0, this.spec.type, this.spec.stacking))
1584
1595
  return this.reject(`Trendlines need an unstacked bar, line, area, scatter or bubble chart; this is a ${this.spec.stacking !== "none" ? `${this.spec.stacking} ` : ""}${this.spec.type} chart.`);
1585
1596
  const issues = [];
1586
- const line = _chunkBPX4Z3N3cjs.normalizeChartTrendline.call(void 0, input, "trendline", issues);
1597
+ const line = _chunkOUO3DSRTcjs.normalizeChartTrendline.call(void 0, input, "trendline", issues);
1587
1598
  if (!line || issues.length) return this.reject(issues.map((i) => i.message).join(" ") || "The trendline is not valid.", issues);
1588
- const index = _nullishCoalesce(_optionalChain([series, 'access', _69 => _69.trendlines, 'optionalAccess', _70 => _70.length]), () => ( 0));
1599
+ const index = _nullishCoalesce(_optionalChain([series, 'access', _71 => _71.trendlines, 'optionalAccess', _72 => _72.length]), () => ( 0));
1589
1600
  const next = this.edited((d) => {
1590
1601
  const s = d.series.find((x) => x.id === seriesId);
1591
1602
  s.trendlines = [..._nullishCoalesce(s.trendlines, () => ( [])), line];
@@ -1597,12 +1608,12 @@ var ChartController = (_class = class {
1597
1608
  updateTrendline(seriesId, index, patch) {
1598
1609
  const series = this.getSeries(seriesId);
1599
1610
  if (!series) return this.unknownSeries(seriesId);
1600
- const current = _optionalChain([series, 'access', _71 => _71.trendlines, 'optionalAccess', _72 => _72[index]]);
1601
- if (!current) return fail(`"${series.name}" has no trendline ${index}; ${_optionalChain([series, 'access', _73 => _73.trendlines, 'optionalAccess', _74 => _74.length]) ? `expected 0 to ${series.trendlines.length - 1}` : "it has none yet"}.`);
1611
+ const current = _optionalChain([series, 'access', _73 => _73.trendlines, 'optionalAccess', _74 => _74[index]]);
1612
+ if (!current) return fail(`"${series.name}" has no trendline ${index}; ${_optionalChain([series, 'access', _75 => _75.trendlines, 'optionalAccess', _76 => _76.length]) ? `expected 0 to ${series.trendlines.length - 1}` : "it has none yet"}.`);
1602
1613
  const issues = [];
1603
1614
  const merged = { ...current, ...patch };
1604
1615
  for (const [k, v] of Object.entries(patch)) if (v === null) delete merged[k];
1605
- const line = _chunkBPX4Z3N3cjs.normalizeChartTrendline.call(void 0, merged, "trendline", issues);
1616
+ const line = _chunkOUO3DSRTcjs.normalizeChartTrendline.call(void 0, merged, "trendline", issues);
1606
1617
  if (!line || issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1607
1618
  this.commit(
1608
1619
  "Change trendline",
@@ -1615,7 +1626,7 @@ var ChartController = (_class = class {
1615
1626
  removeTrendline(seriesId, index) {
1616
1627
  const series = this.getSeries(seriesId);
1617
1628
  if (!series) return this.unknownSeries(seriesId);
1618
- if (!_optionalChain([series, 'access', _75 => _75.trendlines, 'optionalAccess', _76 => _76[index]])) return fail(`"${series.name}" has no trendline ${index}.`);
1629
+ if (!_optionalChain([series, 'access', _77 => _77.trendlines, 'optionalAccess', _78 => _78[index]])) return fail(`"${series.name}" has no trendline ${index}.`);
1619
1630
  this.commit(
1620
1631
  "Delete trendline",
1621
1632
  this.edited((d) => {
@@ -1630,25 +1641,25 @@ var ChartController = (_class = class {
1630
1641
  trendlinePoints(seriesId) {
1631
1642
  const series = this.getSeries(seriesId);
1632
1643
  if (!series) return [];
1633
- const xy = _chunkBPX4Z3N3cjs.chartFamily.call(void 0, this.spec) === "xy";
1644
+ const xy = _chunkOUO3DSRTcjs.chartFamily.call(void 0, this.spec) === "xy";
1634
1645
  const out = [];
1635
1646
  series.values.forEach((v, i) => {
1636
- const x = xy ? _nullishCoalesce(_optionalChain([series, 'access', _77 => _77.x, 'optionalAccess', _78 => _78[i]]), () => ( (this.spec.type === "bubble" ? i + 1 : null))) : i + 1;
1647
+ const x = xy ? _nullishCoalesce(_optionalChain([series, 'access', _79 => _79.x, 'optionalAccess', _80 => _80[i]]), () => ( (this.spec.type === "bubble" ? i + 1 : null))) : i + 1;
1637
1648
  if (v !== null && x !== null && Number.isFinite(v) && Number.isFinite(x)) out.push([x, v]);
1638
1649
  });
1639
1650
  return out;
1640
1651
  }
1641
1652
  /** The fitted coefficients, R² and equation of a trendline (null for moving averages or unfittable data). */
1642
1653
  trendlineFit(seriesId, index) {
1643
- const line = _optionalChain([this, 'access', _79 => _79.getSeries, 'call', _80 => _80(seriesId), 'optionalAccess', _81 => _81.trendlines, 'optionalAccess', _82 => _82[index]]);
1654
+ const line = _optionalChain([this, 'access', _81 => _81.getSeries, 'call', _82 => _82(seriesId), 'optionalAccess', _83 => _83.trendlines, 'optionalAccess', _84 => _84[index]]);
1644
1655
  if (!line) return null;
1645
- return _chunkUUUTEVX6cjs.fitChartTrendline.call(void 0, line, this.trendlinePoints(seriesId));
1656
+ return _chunkWOIXNDHVcjs.fitChartTrendline.call(void 0, line, this.trendlinePoints(seriesId));
1646
1657
  }
1647
1658
  /** The moving-average points of a trendline (empty for other kinds). */
1648
1659
  trendlineMovingAverage(seriesId, index) {
1649
- const line = _optionalChain([this, 'access', _83 => _83.getSeries, 'call', _84 => _84(seriesId), 'optionalAccess', _85 => _85.trendlines, 'optionalAccess', _86 => _86[index]]);
1660
+ const line = _optionalChain([this, 'access', _85 => _85.getSeries, 'call', _86 => _86(seriesId), 'optionalAccess', _87 => _87.trendlines, 'optionalAccess', _88 => _88[index]]);
1650
1661
  if (!line || line.type !== "moving-average") return [];
1651
- return _chunkUUUTEVX6cjs.chartMovingAverage.call(void 0, this.trendlinePoints(seriesId), _nullishCoalesce(line.period, () => ( 2)));
1662
+ return _chunkWOIXNDHVcjs.chartMovingAverage.call(void 0, this.trendlinePoints(seriesId), _nullishCoalesce(line.period, () => ( 2)));
1652
1663
  }
1653
1664
  // -------------------------------------------------------------------------
1654
1665
  // Reshaping
@@ -1669,7 +1680,7 @@ var ChartController = (_class = class {
1669
1680
  used.add(id);
1670
1681
  return { id, name, values: s.series.map((x) => _nullishCoalesce(x.values[i], () => ( null))) };
1671
1682
  });
1672
- const { spec } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, { ...s, categories: s.series.map((x) => x.name), series });
1683
+ const { spec } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, { ...s, categories: s.series.map((x) => x.name), series });
1673
1684
  this.commit("Switch rows and columns", spec, null);
1674
1685
  return { ok: true };
1675
1686
  }
@@ -1722,13 +1733,13 @@ var ChartController = (_class = class {
1722
1733
  this.notify(false);
1723
1734
  }
1724
1735
  stopRace() {
1725
- _optionalChain([this, 'access', _87 => _87.raceStop, 'optionalCall', _88 => _88()]);
1736
+ _optionalChain([this, 'access', _89 => _89.raceStop, 'optionalCall', _90 => _90()]);
1726
1737
  this.raceStop = null;
1727
1738
  }
1728
1739
  /** Selects a chart element (view state; not an undo step). */
1729
1740
  select(selection) {
1730
1741
  const next = this.validSelection(selection, this.spec);
1731
- if (_chunkUUUTEVX6cjs.sameChartSelection.call(void 0, next, this.selection) || next === null && this.selection === null) return;
1742
+ if (_chunkWOIXNDHVcjs.sameChartSelection.call(void 0, next, this.selection) || next === null && this.selection === null) return;
1732
1743
  this.selection = next;
1733
1744
  this.notify(false);
1734
1745
  }
@@ -1805,14 +1816,14 @@ var ChartController = (_class = class {
1805
1816
  // -------------------------------------------------------------------------
1806
1817
  /** The spec, for saving (a copy). */
1807
1818
  toJSON() {
1808
- return _chunkBPX4Z3N3cjs.cloneChartSpec.call(void 0, this.spec);
1819
+ return _chunkOUO3DSRTcjs.cloneChartSpec.call(void 0, this.spec);
1809
1820
  }
1810
1821
  /**
1811
1822
  * Replaces the chart without an undo step (e.g. when opening a document). Problems are
1812
1823
  * fixed with defaults and reported in `state.issues` (and returned).
1813
1824
  */
1814
1825
  load(input, options = {}) {
1815
- const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, input);
1826
+ const { spec, issues } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, input);
1816
1827
  this.spec = spec;
1817
1828
  this.issues = issues;
1818
1829
  this.selection = this.validSelection(this.selection, spec);
@@ -1832,7 +1843,7 @@ var ChartController = (_class = class {
1832
1843
  * nothing changes and every problem is returned (and shown in `state.issues`).
1833
1844
  */
1834
1845
  replace(input, options = {}) {
1835
- const { spec, issues } = _chunkBPX4Z3N3cjs.normalizeChartSpec.call(void 0, input);
1846
+ const { spec, issues } = _chunkOUO3DSRTcjs.normalizeChartSpec.call(void 0, input);
1836
1847
  if (issues.length) return this.reject(issues.map((i) => i.message).join(" "), issues);
1837
1848
  this.commit(_nullishCoalesce(options.label, () => ( "Replace chart")), spec, this.validSelection(this.selection, spec));
1838
1849
  return { ok: true };
@@ -1848,7 +1859,7 @@ var ChartController = (_class = class {
1848
1859
  /** Stops listening to the history (reconnected by the next `subscribe`). */
1849
1860
  destroy() {
1850
1861
  this.stopRace();
1851
- _optionalChain([this, 'access', _89 => _89.unsubscribeHistory, 'optionalCall', _90 => _90()]);
1862
+ _optionalChain([this, 'access', _91 => _91.unsubscribeHistory, 'optionalCall', _92 => _92()]);
1852
1863
  this.unsubscribeHistory = void 0;
1853
1864
  this.listeners.clear();
1854
1865
  }
@@ -1884,6 +1895,9 @@ function updateLabel(patch) {
1884
1895
  parliamentMajority: "Change majority",
1885
1896
  parliamentLabel: "Edit seat caption",
1886
1897
  raceTopN: "Change bars shown",
1898
+ map: "Change map",
1899
+ mapSteps: "Change colour classes",
1900
+ mapThresholds: "Change class breaks",
1887
1901
  sunburstLabel: "Edit centre caption",
1888
1902
  tree: "Replace grouped data",
1889
1903
  links: "Replace flows",
@@ -1911,7 +1925,7 @@ function layoutSparkline(values, options) {
1911
1925
  const h = Number.isFinite(options.height) ? Math.max(1, options.height) : 1;
1912
1926
  const color = _nullishCoalesce(options.color, () => ( "#4269d0"));
1913
1927
  const negative = _nullishCoalesce(options.negativeColor, () => ( "#e5484d"));
1914
- const theme = { ..._chunkBPX4Z3N3cjs.DEFAULT_CHART_THEME, background: "transparent" };
1928
+ const theme = { ..._chunkOUO3DSRTcjs.DEFAULT_CHART_THEME, background: "transparent" };
1915
1929
  const marks = [];
1916
1930
  const scene = { width: w, height: h, plot: { x: 0, y: 0, width: w, height: h }, marks, percent: false, theme, warnings: [] };
1917
1931
  const vals = values.slice(0, MAX_POINTS).map((v) => v !== null && Number.isFinite(v) ? Math.max(-1e300, Math.min(1e300, v)) : null);
@@ -1944,7 +1958,7 @@ function layoutSparkline(values, options) {
1944
1958
  const flush = () => {
1945
1959
  if (run.length >= 2) {
1946
1960
  const pts = run.length > 4e3 ? run.filter((_, i) => i % (Math.floor(run.length / 2e3) + 1) === 0) : run;
1947
- d += pts.map(([x, y], i) => `${i ? "L" : "M"}${_chunkUUUTEVX6cjs.r2.call(void 0, x)},${_chunkUUUTEVX6cjs.r2.call(void 0, y)}`).join("");
1961
+ d += pts.map(([x, y], i) => `${i ? "L" : "M"}${_chunkWOIXNDHVcjs.r2.call(void 0, x)},${_chunkWOIXNDHVcjs.r2.call(void 0, y)}`).join("");
1948
1962
  }
1949
1963
  run = [];
1950
1964
  };