@bicharts/chart-host 0.5.47 → 0.5.49

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.
@@ -474,17 +474,17 @@ function y3(n, e) {
474
474
  let A = n[l], C = A3({ ...A, mapKind: e });
475
475
  if (S3(C)) {
476
476
  t[l] = null, o[l] = null, i[l] = null, m2++;
477
- let M2 = K(A);
478
- M2 && !d.has(M2.toLowerCase()) && (d.add(M2.toLowerCase()), R.length < x && R.push(M2));
477
+ let M = K(A);
478
+ M && !d.has(M.toLowerCase()) && (d.add(M.toLowerCase()), R.length < x && R.push(M));
479
479
  } else if (C) {
480
480
  if (t[l] = C.lat, o[l] = C.lon, i[l] = C.precision, S++, g[C.precision]++, (p2 === null || G[C.precision] > G[p2]) && (p2 = C.precision), G[C.precision] > G.city) {
481
- let M2 = K(A);
482
- M2 && !s.has(M2.toLowerCase()) && (s.add(M2.toLowerCase()), f.length < x && f.push(M2));
481
+ let M = K(A);
482
+ M && !s.has(M.toLowerCase()) && (s.add(M.toLowerCase()), f.length < x && f.push(M));
483
483
  }
484
484
  } else {
485
485
  t[l] = null, o[l] = null, i[l] = null;
486
- let M2 = K(A);
487
- M2 && !r.has(M2.toLowerCase()) && (r.add(M2.toLowerCase()), a2.push(M2));
486
+ let M = K(A);
487
+ M && !r.has(M.toLowerCase()) && (r.add(M.toLowerCase()), a2.push(M));
488
488
  }
489
489
  }
490
490
  let c = !n3() && n.some((l) => l.city !== null && l.city !== void 0 && String(l.city).trim() !== "");
@@ -588,57 +588,57 @@ function Kn(n, s) {
588
588
 
589
589
  // ../shape-core/dist/index.mjs
590
590
  /*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
591
- var W2 = ["rate", "ratio", "pct", "percent", "percentage", "rating", "share", "score", "index", "nps", "csat", "margin", "yield", "coverage", "utilization", "z[_-]?score", "average", "avg", "mean", "median", "stddev", "variance", "gpa", "percentile", "quantile", "efficiency", "accuracy", "probability", "multiplier", "coefficient", "correlation", "occupancy", "age", "bmi", "temperature", "density", "pressure", "humidity", "ph", "velocity", "speed", "elevation", "altitude", "latency", "throughput", "bandwidth", "iops"];
592
- var X2 = ["pct", "percent", "percentage", "rate", "ratio", "rating", "share", "score", "index", "nps", "csat", "margin", "yield", "coverage", "utilization", "gpa", "percentile", "quantile", "bmi", "density", "pressure", "humidity", "velocity", "efficiency", "occupancy", "latency", "throughput", "bandwidth", "iops"];
593
- var Y2 = ["latitude", "longitude"];
591
+ var X2 = ["rate", "ratio", "pct", "percent", "percentage", "rating", "share", "score", "index", "nps", "csat", "margin", "yield", "coverage", "utilization", "z[_-]?score", "average", "avg", "mean", "median", "stddev", "variance", "gpa", "percentile", "quantile", "efficiency", "accuracy", "probability", "multiplier", "coefficient", "correlation", "occupancy", "age", "bmi", "temperature", "density", "pressure", "humidity", "ph", "velocity", "speed", "elevation", "altitude", "latency", "throughput", "bandwidth", "iops"];
592
+ var Y2 = ["pct", "percent", "percentage", "rate", "ratio", "rating", "share", "score", "index", "nps", "csat", "margin", "yield", "coverage", "utilization", "gpa", "percentile", "quantile", "bmi", "density", "pressure", "humidity", "velocity", "efficiency", "occupancy", "latency", "throughput", "bandwidth", "iops"];
594
593
  var J2 = ["latitude", "longitude"];
595
- var Q2 = /^\s*(sum|count|count\s+distinct|distinct\s+count)\s+of\s+/i;
596
- var Ut = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])/g;
597
- var Zt = new RegExp("\\b(" + W2.join("|") + ")\\b|(" + X2.join("|") + ")$", "i");
598
- var qt = new RegExp("\\b(" + Y2.join("|") + ")\\b|(" + J2.join("|") + ")$", "i");
599
- function M(e) {
600
- return e ? String(e).replace(Q2, "").trim() : "";
594
+ var Q2 = ["latitude", "longitude"];
595
+ var tt = /^\s*(sum|count|count\s+distinct|distinct\s+count)\s+of\s+/i;
596
+ var qt = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])/g;
597
+ var jt = new RegExp("\\b(" + X2.join("|") + ")\\b|(" + Y2.join("|") + ")$", "i");
598
+ var Wt = new RegExp("\\b(" + J2.join("|") + ")\\b|(" + Q2.join("|") + ")$", "i");
599
+ function L2(e) {
600
+ return e ? String(e).replace(tt, "").trim() : "";
601
601
  }
602
- function tt(e) {
603
- return !!e && Q2.test(String(e));
602
+ function et(e) {
603
+ return !!e && tt.test(String(e));
604
604
  }
605
- function jt(e) {
606
- let t = M(e);
607
- return t.length === 0 ? "" : t.replace(Ut, " ");
605
+ function Xt(e) {
606
+ let t = L2(e);
607
+ return t.length === 0 ? "" : t.replace(qt, " ");
608
608
  }
609
- function et(e, t) {
610
- return t ? e.test(jt(t)) || e.test(M(t)) : false;
609
+ function nt(e, t) {
610
+ return t ? e.test(Xt(t)) || e.test(L2(t)) : false;
611
611
  }
612
- function L2(e) {
613
- return et(qt, e);
612
+ function z2(e) {
613
+ return nt(Wt, e);
614
614
  }
615
- function nt(e) {
616
- return et(Zt, e) || L2(e);
615
+ function it(e) {
616
+ return nt(jt, e) || z2(e);
617
617
  }
618
- var it = /int|double|decimal|single|float|number|currency|money/i;
619
- function Wt(e) {
618
+ var ot = /int|double|decimal|single|float|number|currency|money/i;
619
+ function Yt(e) {
620
620
  let t = String(e?.valueNature ?? "").trim().toLowerCase();
621
- return t === "categorical" ? "Categorical" : t === "ordinal" ? "Ordinal" : t === "continuous" || e?.isMeasure === true || it.test(String(e?.dataType ?? "")) ? "Continuous" : "Categorical";
621
+ return t === "categorical" ? "Categorical" : t === "ordinal" ? "Ordinal" : t === "continuous" || e?.isMeasure === true || ot.test(String(e?.dataType ?? "")) ? "Continuous" : "Categorical";
622
622
  }
623
- function Xt(e) {
624
- return e?.isMeasure === true || it.test(String(e?.dataType ?? ""));
623
+ function Jt(e) {
624
+ return e?.isMeasure === true || ot.test(String(e?.dataType ?? ""));
625
625
  }
626
- function z2(e) {
627
- let t = e ?? {}, i = Wt(t);
626
+ function G2(e) {
627
+ let t = e ?? {}, i = Yt(t);
628
628
  if (i !== "Continuous") return { nature: i, additivity: "unknown", basis: "role", suppressed: false };
629
- if (L2(t.name)) return { nature: i, additivity: "positional", basis: "name", suppressed: true };
630
- let r = String(t.additivity ?? "").trim().toLowerCase();
631
- if (!(r === "additive" && tt(t.name))) {
632
- if (r === "additive") return { nature: i, additivity: "additive", basis: "measured", suppressed: false };
633
- if (r === "part_of_whole") return { nature: i, additivity: "part_of_whole", basis: "measured", suppressed: false };
634
- if (r === "intensive_rate") return { nature: i, additivity: "intensive_rate", basis: "measured", suppressed: false };
629
+ if (z2(t.name)) return { nature: i, additivity: "positional", basis: "name", suppressed: true };
630
+ let s = String(t.additivity ?? "").trim().toLowerCase();
631
+ if (!(s === "additive" && et(t.name))) {
632
+ if (s === "additive") return { nature: i, additivity: "additive", basis: "measured", suppressed: false };
633
+ if (s === "part_of_whole") return { nature: i, additivity: "part_of_whole", basis: "measured", suppressed: false };
634
+ if (s === "intensive_rate") return { nature: i, additivity: "intensive_rate", basis: "measured", suppressed: false };
635
635
  }
636
- return t.discourageAggregationAcrossGroups === true ? { nature: i, additivity: "intensive_rate", basis: "host-flag", suppressed: false } : nt(t.name) ? { nature: i, additivity: "intensive_rate", basis: "name", suppressed: false } : { nature: i, additivity: "additive", basis: "default", suppressed: false };
636
+ return t.discourageAggregationAcrossGroups === true ? { nature: i, additivity: "intensive_rate", basis: "host-flag", suppressed: false } : it(t.name) ? { nature: i, additivity: "intensive_rate", basis: "name", suppressed: false } : { nature: i, additivity: "additive", basis: "default", suppressed: false };
637
637
  }
638
- function G2(e) {
639
- let t = z2(e), i = e ?? {};
638
+ function F2(e) {
639
+ let t = G2(e), i = e ?? {};
640
640
  if (t.nature === "Categorical") return ["first", "distinctcount", "count"];
641
- if (t.nature === "Ordinal") return Xt(i) ? ["median", "average", "min", "max", "first", "distinctcount", "count"] : ["first", "distinctcount", "count"];
641
+ if (t.nature === "Ordinal") return Jt(i) ? ["median", "average", "min", "max", "first", "distinctcount", "count"] : ["first", "distinctcount", "count"];
642
642
  switch (t.additivity) {
643
643
  case "positional":
644
644
  return ["min", "max", "count", "distinctcount", "first"];
@@ -648,151 +648,156 @@ function G2(e) {
648
648
  return ["sum", "average", "median", "min", "max", "count", "distinctcount", "first"];
649
649
  }
650
650
  }
651
- function Yt(e) {
652
- return G2(e)[0];
651
+ function Qt(e) {
652
+ return F2(e)[0];
653
653
  }
654
- function Qt(e, t) {
654
+ function ee(e, t) {
655
655
  if (t !== "sum" && t !== "count") return false;
656
656
  if (t === "count") return true;
657
- let i = z2(e);
657
+ let i = G2(e);
658
658
  return i.additivity === "additive" || i.additivity === "part_of_whole" || i.additivity === "unknown";
659
659
  }
660
- var F2 = 2;
661
- var st = 400;
662
- function D2(e) {
660
+ var $2 = 2;
661
+ var at = 400;
662
+ function K2(e) {
663
663
  return !!E(e);
664
664
  }
665
665
  function v2(e) {
666
666
  let t = /* @__PURE__ */ new Set();
667
667
  for (let i of e) {
668
668
  if (i == null) continue;
669
- let r = u(String(i));
670
- if (!V(r) && !t.has(r) && (t.add(r), t.size >= st)) break;
669
+ let s = u(String(i));
670
+ if (!V(s) && !t.has(s) && (t.add(s), t.size >= at)) break;
671
671
  }
672
672
  return Array.from(t);
673
673
  }
674
674
  function h2(e) {
675
675
  let t = v2(e);
676
- if (t.length === 0 || K2(e) < 95) return false;
677
- let i = t.filter((u2) => D2(u2) && !Y(u2)).length, r = t.filter((u2) => !D2(u2) && !!Y(u2)).length;
678
- return i >= 1 && i >= r;
676
+ if (t.length === 0 || B2(e) < 95) return false;
677
+ let i = t.filter((u2) => K2(u2) && !Y(u2)).length, s = t.filter((u2) => !K2(u2) && !!Y(u2)).length;
678
+ return i >= 1 && i >= s;
679
679
  }
680
- function ot(e, t) {
680
+ function rt(e, t) {
681
681
  if (!Y(e)) return false;
682
682
  let i = E(e);
683
683
  return i ? t === "world" ? true : s3.has(i) : false;
684
684
  }
685
- function K2(e) {
685
+ function B2(e) {
686
686
  let t = v2(e);
687
687
  if (t.length === 0) return 0;
688
688
  let i = 0;
689
- for (let r of t) D2(r) && i++;
689
+ for (let s of t) K2(s) && i++;
690
690
  return Math.round(i / t.length * 1e3) / 10;
691
691
  }
692
- function P2(e) {
692
+ function I2(e) {
693
693
  let t = v2(e);
694
694
  if (t.length === 0) return 0;
695
695
  let i = 0;
696
- for (let r of t) Y(r) && i++;
696
+ for (let s of t) Y(s) && i++;
697
697
  return Math.round(i / t.length * 1e3) / 10;
698
698
  }
699
- function H2(e) {
699
+ function V2(e) {
700
700
  let t = /* @__PURE__ */ new Set();
701
701
  for (let i of e) {
702
702
  if (i == null) continue;
703
- let r = String(i).trim();
704
- if (!V(u(r)) && !t.has(r) && (t.add(r), t.size >= st)) break;
703
+ let s = String(i).trim();
704
+ if (!V(u(s)) && !t.has(s) && (t.add(s), t.size >= at)) break;
705
705
  }
706
706
  return Array.from(t);
707
707
  }
708
- function B2(e) {
709
- let t = H2(e);
708
+ function H2(e) {
709
+ let t = V2(e);
710
710
  if (t.length === 0) return 0;
711
711
  let i = 0;
712
- for (let r of t) Z(r).length > 0 && i++;
712
+ for (let s of t) Z(s).length > 0 && i++;
713
713
  return Math.round(i / t.length * 1e3) / 10;
714
714
  }
715
- function rt(e, t) {
716
- return p(t, en) ? true : H2(e).some((i) => /^\d{5}(-\d{4})?$/.test(i.replace(/\.0+$/, "")));
715
+ function st(e, t) {
716
+ return p(t, en) ? true : V2(e).some((i) => /^\d{5}(-\d{4})?$/.test(i.replace(/\.0+$/, "")));
717
717
  }
718
- function te(e, t) {
718
+ function ne(e, t) {
719
719
  let i = v2(e);
720
720
  if (i.length === 0) return 0;
721
- let r = 0;
722
- for (let u2 of i) p3(u2, t) && r++;
723
- return Math.round(r / i.length * 1e3) / 10;
721
+ let s = 0;
722
+ for (let u2 of i) p3(u2, t) && s++;
723
+ return Math.round(s / i.length * 1e3) / 10;
724
724
  }
725
- function $2(e, t) {
725
+ function D2(e, t) {
726
726
  let i = 0;
727
- for (let r of v2(e)) t(r) && i++;
727
+ for (let s of v2(e)) t(s) && i++;
728
728
  return i;
729
729
  }
730
- function ee(e, t) {
730
+ function ie(e, t) {
731
731
  let i = 0;
732
- for (let r of H2(e)) t(r) && i++;
732
+ for (let s of V2(e)) t(s) && i++;
733
733
  return i;
734
734
  }
735
- function ne(e, t, i, r) {
736
- let u2 = [], c = [], o = {}, I2 = {}, R = new Set(e), l = (n) => t.map((s) => s[n]);
737
- for (let n of ["city", "lat", "lon", "country"]) {
738
- let s = i?.[n];
739
- s && R.has(s) && (o[n] = s);
735
+ function oe(e, t, i, s, u2) {
736
+ let x2 = [], c = [], o = {}, R = {}, N2 = new Set(e), l = (n) => t.map((r) => r[n]);
737
+ for (let n of ["city", "country"]) {
738
+ let r = i?.[n];
739
+ r && N2.has(r) && (o[n] = r);
740
+ }
741
+ let ut = new Set(u2 ?? e);
742
+ for (let n of ["lat", "lon"]) {
743
+ let r = i?.[n];
744
+ r && ut.has(r) && (o[n] = r);
740
745
  }
741
746
  let p2 = i?.zip;
742
- if (p2 && R.has(p2)) {
743
- let n = l(p2), s = B2(n);
744
- s < 95 ? c.push(`zip=${p2} (only ${s}% of values read as ZIPs)`) : rt(n, p2) ? o.zip = p2 : c.push(`zip=${p2} (all values are 3-4 digits with nothing to say they are postal)`);
747
+ if (p2 && N2.has(p2)) {
748
+ let n = l(p2), r = H2(n);
749
+ r < 95 ? c.push(`zip=${p2} (only ${r}% of values read as ZIPs)`) : st(n, p2) ? o.zip = p2 : c.push(`zip=${p2} (all values are 3-4 digits with nothing to say they are postal)`);
745
750
  }
746
751
  let f = i?.state;
747
- if (f && R.has(f)) {
748
- let n = l(f), s = v2(n);
749
- s.length > 0 && s.every((a2) => ot(a2, r)) ? c.push(`state=${f} (every value is "CA", which is both Canada and California)`) : h2(n) ? (c.push(`state=${f} (every value is a country, not a state)`), o.country || (o.country = f)) : P2(n) < 95 ? c.push(`state=${f} (only ${P2(n)}% of values are states/provinces)`) : o.state = f;
752
+ if (f && N2.has(f)) {
753
+ let n = l(f), r = v2(n);
754
+ r.length > 0 && r.every((a2) => rt(a2, s)) ? c.push(`state=${f} (every value is "CA", which is both Canada and California)`) : h2(n) ? (c.push(`state=${f} (every value is a country, not a state)`), o.country || (o.country = f)) : I2(n) < 95 ? c.push(`state=${f} (only ${I2(n)}% of values are states/provinces)`) : o.state = f;
750
755
  }
751
- let m2 = new Set(Object.values(o).filter(Boolean)), x2 = e.filter((n) => !m2.has(n) && !n.startsWith("__"));
756
+ let m2 = new Set(Object.values(o).filter(Boolean)), C = e.filter((n) => !m2.has(n) && !n.startsWith("__"));
752
757
  if (!o.state) {
753
758
  let n = null;
754
- for (let s of x2) {
755
- let a2 = l(s);
759
+ for (let r of C) {
760
+ let a2 = l(r);
756
761
  if (h2(a2)) continue;
757
- let d = P2(a2);
762
+ let d = I2(a2);
758
763
  if (d < 95) continue;
759
- let E2 = $2(a2, (C) => !!Y(C)), ut = $2(a2, (C) => !!Y(C) && !ot(C, r));
760
- E2 < F2 && ut < 1 || (!n || d > n.pct) && (n = { name: s, pct: d });
764
+ let E2 = D2(a2, (b2) => !!Y(b2)), ct = D2(a2, (b2) => !!Y(b2) && !rt(b2, s));
765
+ E2 < $2 && ct < 1 || (!n || d > n.pct) && (n = { name: r, pct: d });
761
766
  }
762
- n && (o.state = n.name, m2.add(n.name), u2.push(`state=${n.name} (${n.pct}% states/provinces)`));
767
+ n && (o.state = n.name, m2.add(n.name), x2.push(`state=${n.name} (${n.pct}% states/provinces)`));
763
768
  }
764
- if (!o.zip) for (let n of x2) {
769
+ if (!o.zip) for (let n of C) {
765
770
  if (m2.has(n)) continue;
766
- let s = l(n), a2 = B2(s);
767
- if (!(a2 < 95) && rt(s, n) && !(ee(s, (d) => Z(d).length > 0) < F2)) {
768
- o.zip = n, m2.add(n), u2.push(`zip=${n} (${a2}% ZIP codes)`);
771
+ let r = l(n), a2 = H2(r);
772
+ if (!(a2 < 95) && st(r, n) && !(ie(r, (d) => Z(d).length > 0) < $2)) {
773
+ o.zip = n, m2.add(n), x2.push(`zip=${n} (${a2}% ZIP codes)`);
769
774
  break;
770
775
  }
771
776
  }
772
777
  let A = o.country;
773
778
  if (!A || !h2(l(A))) {
774
779
  let n = null;
775
- for (let s of x2) {
776
- if (m2.has(s) || !h2(l(s))) continue;
777
- let a2 = K2(l(s));
778
- (!n || a2 > n.pct) && (n = { name: s, pct: a2 });
780
+ for (let r of C) {
781
+ if (m2.has(r) || !h2(l(r))) continue;
782
+ let a2 = B2(l(r));
783
+ (!n || a2 > n.pct) && (n = { name: r, pct: a2 });
779
784
  }
780
- n && (A && (c.push(`country=${A} (only ${K2(l(A))}% of values are country identifiers; using ${n.name} instead)`), I2.country = A), o.country = n.name, m2.add(n.name), u2.push(`country=${n.name}`));
785
+ n && (A && (c.push(`country=${A} (only ${B2(l(A))}% of values are country identifiers; using ${n.name} instead)`), R.country = A), o.country = n.name, m2.add(n.name), x2.push(`country=${n.name}`));
781
786
  }
782
787
  if (!o.city) {
783
788
  let n = null;
784
- for (let s of x2) {
785
- if (m2.has(s)) continue;
786
- let a2 = l(s), d = te(a2, r);
787
- d < m3 || $2(a2, (E2) => p3(E2, r)) < F2 || (!n || d > n.pct) && (n = { name: s, pct: d });
789
+ for (let r of C) {
790
+ if (m2.has(r)) continue;
791
+ let a2 = l(r), d = ne(a2, s);
792
+ d < m3 || D2(a2, (E2) => p3(E2, s)) < $2 || (!n || d > n.pct) && (n = { name: r, pct: d });
788
793
  }
789
- n && (o.city = n.name, u2.push(`city=${n.name} (${n.pct}% known cities)`));
794
+ n && (o.city = n.name, x2.push(`city=${n.name} (${n.pct}% known cities)`));
790
795
  }
791
- let V2 = o.country ? l(o.country) : [], N2 = !!o.country && h2(V2), at = N2 ? new Set(V2.map((n) => E(n == null ? null : String(n))).filter(Boolean)).size : 0, U2 = N2 && at >= 2, O2 = !!(o.lat && o.lon) && t.some((n) => {
792
- let s = +String(n[o.lat] ?? "").trim(), a2 = +String(n[o.lon] ?? "").trim();
793
- return isFinite(s) && isFinite(a2) && s >= -90 && s <= 90 && a2 >= -180 && a2 <= 180 && String(n[o.lat] ?? "").trim() !== "" && String(n[o.lon] ?? "").trim() !== "";
796
+ let U2 = o.country ? l(o.country) : [], O2 = !!o.country && h2(U2), lt = O2 ? new Set(U2.map((n) => E(n == null ? null : String(n))).filter(Boolean)).size : 0, Z2 = O2 && lt >= 2, w = !!(o.lat && o.lon) && t.some((n) => {
797
+ let r = +String(n[o.lat] ?? "").trim(), a2 = +String(n[o.lon] ?? "").trim();
798
+ return isFinite(r) && isFinite(a2) && r >= -90 && r <= 90 && a2 >= -180 && a2 <= 180 && String(n[o.lat] ?? "").trim() !== "" && String(n[o.lon] ?? "").trim() !== "";
794
799
  });
795
- return o.lat && o.lon && !O2 && c.push(`lat/lon=${o.lat}/${o.lon} (no row holds a usable coordinate pair)`), o.country && !U2 && !(o.city || o.state || o.zip || O2) && c.push(N2 ? `country=${o.country} (every row resolves to the same country - nothing to place apart)` : `country=${o.country} (values are not country identifiers)`), { bind: !!(o.city || o.state || o.zip || U2 || O2) ? o : null, backfilled: u2, refused: c, ...Object.keys(I2).length ? { labelFallback: I2 } : {} };
800
+ return o.lat && o.lon && !w && c.push(`lat/lon=${o.lat}/${o.lon} (no row holds a usable coordinate pair)`), o.country && !Z2 && !(o.city || o.state || o.zip || w) && c.push(O2 ? `country=${o.country} (every row resolves to the same country - nothing to place apart)` : `country=${o.country} (values are not country identifiers)`), { bind: !!(o.city || o.state || o.zip || Z2 || w) ? o : null, backfilled: x2, refused: c, ...Object.keys(R).length ? { labelFallback: R } : {} };
796
801
  }
797
802
 
798
803
  // src/payload.ts
@@ -807,7 +812,7 @@ function resolvePointChannel(cols, rowObjs, point) {
807
812
  let labelCol;
808
813
  if (bind) {
809
814
  const dims = cols.filter((c) => !c.isMeasure).map((c) => c.name);
810
- const res = ne(dims, rowObjs, bind, point?.mapKind);
815
+ const res = oe(dims, rowObjs, bind, point?.mapKind, cols.map((c) => c.name));
811
816
  bind = res.bind;
812
817
  rolesBackfilled = res.backfilled;
813
818
  rolesRefused = res.refused;
@@ -1572,10 +1577,10 @@ export {
1572
1577
  registerGeoAsset,
1573
1578
  clearGeoCache,
1574
1579
  L3,
1575
- z2 as z,
1576
1580
  G2 as G,
1577
- Yt,
1581
+ F2 as F,
1578
1582
  Qt,
1583
+ ee,
1579
1584
  buildRenderPayload,
1580
1585
  createMarkResolver,
1581
1586
  ensureCrossfilterHitTargets,
package/dist/index.mjs CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  CONTAINER_SLOT_XF_CLEAR,
20
20
  DIM_OPACITY_DEFAULT,
21
21
  DIM_OPACITY_VAR,
22
+ F,
22
23
  FLIP_MODE_DEFAULT,
23
24
  G,
24
25
  GEO_POINT_PRECISIONS,
@@ -32,7 +33,6 @@ import {
32
33
  ROW_IDX_ATTR,
33
34
  SELECTION_ACTIVE_CLASS,
34
35
  XFILTER_REFRESH_EVENT,
35
- Yt,
36
36
  blankRenderFlag,
37
37
  buildRenderPayload,
38
38
  censusMarks,
@@ -41,6 +41,7 @@ import {
41
41
  compileRenderFn,
42
42
  createChartHost,
43
43
  createMarkResolver,
44
+ ee,
44
45
  ensureCrossfilterHitTargets,
45
46
  explainRenderFailure,
46
47
  geoAssetFor,
@@ -52,9 +53,8 @@ import {
52
53
  registerGeoAsset,
53
54
  requiredD3Plugins,
54
55
  resolveOptions,
55
- stripEsmExports,
56
- z
57
- } from "./chunk-JPDIL3HN.mjs";
56
+ stripEsmExports
57
+ } from "./chunk-OSJNZVRA.mjs";
58
58
  import "./chunk-A2GMXZP7.mjs";
59
59
 
60
60
  // src/trivial.ts
@@ -580,6 +580,34 @@ function qualifyGroupHeadingFor(row, state) {
580
580
  }
581
581
  return null;
582
582
  }
583
+ function newQualifyRefusalGroupState() {
584
+ return { poorFit: false, cannotDraw: false };
585
+ }
586
+ function refusalIsSelectable(row) {
587
+ return !!row && row.isVeto !== true;
588
+ }
589
+ function orderRefusalsForDisplay(rows) {
590
+ if (!Array.isArray(rows)) return [];
591
+ const named = rows.filter((r) => !!r && typeof r.name === "string" && r.name.trim() !== "");
592
+ return [...named.filter(refusalIsSelectable), ...named.filter((r) => !refusalIsSelectable(r))];
593
+ }
594
+ function qualifyRefusalHeadingFor(row, state) {
595
+ if (refusalIsSelectable(row)) {
596
+ if (!state.poorFit) {
597
+ state.poorFit = true;
598
+ return "poorFit";
599
+ }
600
+ return null;
601
+ }
602
+ if (!state.cannotDraw) {
603
+ state.cannotDraw = true;
604
+ return "cannotDraw";
605
+ }
606
+ return null;
607
+ }
608
+ function hasRefusalsToShow(rows) {
609
+ return orderRefusalsForDisplay(rows).length > 0;
610
+ }
583
611
 
584
612
  // src/qualifyLaunch.ts
585
613
  var qualifyPick = (chartType) => ({ kind: "pick", chartType });
@@ -659,15 +687,15 @@ function isRealColumn(col) {
659
687
  return !!col && !isSynthetic(col.name);
660
688
  }
661
689
  function isSuppressed(col) {
662
- return z(col).suppressed;
690
+ return G(col).suppressed;
663
691
  }
664
692
  function resolveAgg(col, requested, auto) {
665
693
  const fallback = () => {
666
- const d = Yt(col);
694
+ const d = Qt(col);
667
695
  return d === "first" ? "count" : d;
668
696
  };
669
697
  if (auto) return fallback();
670
- return G(col).indexOf(requested) >= 0 ? requested : fallback();
698
+ return F(col).indexOf(requested) >= 0 ? requested : fallback();
671
699
  }
672
700
  function toNumber(v) {
673
701
  if (v == null || v === "") return null;
@@ -771,7 +799,7 @@ function computeSelectionCard(payload, selectedRowIdxs, opts = {}) {
771
799
  }
772
800
  const value = reduce(selVals, colAgg, selRaw);
773
801
  let sharePct = null;
774
- if (Qt(col, colAgg) && value != null) {
802
+ if (ee(col, colAgg) && value != null) {
775
803
  const allVals = [];
776
804
  const allRaw = [];
777
805
  for (let r = 0; r < rows.length; r++) {
@@ -888,12 +916,15 @@ export {
888
916
  explainRenderFailure,
889
917
  geoAssetFor,
890
918
  geoFromCache,
919
+ hasRefusalsToShow,
891
920
  isBlankRender,
892
921
  launchFavorStyle,
893
922
  launchGenerates,
894
923
  loadGeo,
895
924
  newQualifyGroupState,
925
+ newQualifyRefusalGroupState,
896
926
  normaliseAggregation,
927
+ orderRefusalsForDisplay,
897
928
  periodTickSuppressesFeedback,
898
929
  planTrivialChart,
899
930
  qualifyAuto,
@@ -901,7 +932,9 @@ export {
901
932
  qualifyFailureFallsOpen,
902
933
  qualifyGroupHeadingFor,
903
934
  qualifyPick,
935
+ qualifyRefusalHeadingFor,
904
936
  rasterizeSvgToPngDataUrl,
937
+ refusalIsSelectable,
905
938
  registerCityTable,
906
939
  registerGeo,
907
940
  registerGeoAsset,
package/dist/react.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  createChartHost,
5
5
  geoFromCache,
6
6
  loadGeo
7
- } from "./chunk-JPDIL3HN.mjs";
7
+ } from "./chunk-OSJNZVRA.mjs";
8
8
  import "./chunk-A2GMXZP7.mjs";
9
9
 
10
10
  // src/react.tsx
@@ -11,7 +11,7 @@ export { planTrivialChart, compileTrivialSource, type TrivialPlan, type TrivialS
11
11
  export { captureSvgSnapshot, svgToDataUrl, svgNaturalSize, rasterizeSvgToPngDataUrl, type SnapshotOptions } from "./snapshot";
12
12
  export { shouldReview, buildReviewWire, bareBase64, actionFor, type ReviewGate, type ReviewWire, type ReviewVerdict, type ReviewAction } from "./review";
13
13
  export { askApplyImprovements, type ReviewDialogOptions, type ReviewDialogText } from "./reviewDialog";
14
- export { qualifyGroupHeadingFor, newQualifyGroupState, type QualifyGroupRow, type QualifyGroupState, type QualifyGroupHeading, } from "./qualifyGroups";
14
+ export { qualifyGroupHeadingFor, newQualifyGroupState, type QualifyGroupRow, type QualifyGroupState, type QualifyGroupHeading, orderRefusalsForDisplay, refusalIsSelectable, hasRefusalsToShow, qualifyRefusalHeadingFor, newQualifyRefusalGroupState, type QualifyRefusalRow, type QualifyRefusalGroupState, type QualifyRefusalHeading, } from "./qualifyGroups";
15
15
  export { qualifyPick, qualifyAuto, qualifyCancel, launchGenerates, launchFavorStyle, chooserFitsViewport, shouldOpenChooserOnGenerate, shouldOpenInlineChooserOnGenerate, canConfirmLaunch, confirmLaunch, qualifyFailureFallsOpen, CHOOSER_MIN_WIDTH_PX, CHOOSER_MIN_HEIGHT_PX, type QualifyLaunchOutcome, type ChooserGateInput, } from "./qualifyLaunch";
16
16
  export { computeSelectionCard, normaliseAggregation, type SelectionCardModel, type SelectionCardLine, type SelectionCardOptions, } from "./selectionCard";
17
17
  export { ensureCrossfilterHitTargets, type HitTargetReport } from "./hitTargets";
@@ -29,3 +29,54 @@ export declare function newQualifyGroupState(): QualifyGroupState;
29
29
  * 3. "projected" and 4. "notRecommended" are unchanged from the single-host original.
30
30
  */
31
31
  export declare function qualifyGroupHeadingFor(row: QualifyGroupRow, state: QualifyGroupState): QualifyGroupHeading | null;
32
+ /** One row of a qualify result's `refused` array, in the only shape this logic cares about. */
33
+ export interface QualifyRefusalRow {
34
+ name?: string | null;
35
+ /** The gate's sentence. Absent is a real answer — the blocker rested on a runtime signal. */
36
+ reason?: string | null;
37
+ /** True = a required channel is ABSENT. Absent/false = a threshold we are willing to waive. */
38
+ isVeto?: boolean | null;
39
+ }
40
+ /** Which heading to write BEFORE a refused row, if any. */
41
+ export type QualifyRefusalHeading = "poorFit" | "cannotDraw";
42
+ /** Carried across the refusal loop. One per render. */
43
+ export interface QualifyRefusalGroupState {
44
+ poorFit: boolean;
45
+ cannotDraw: boolean;
46
+ }
47
+ export declare function newQualifyRefusalGroupState(): QualifyRefusalGroupState;
48
+ /**
49
+ * MAY THE READER PICK THIS ONE? The single place that answers it, in either host.
50
+ *
51
+ * DEFAULTS TO YES, and the asymmetry is deliberate. An older server sends no `isVeto` at all, so
52
+ * every row reads selectable and the reader is offered something that may be refused — one wasted
53
+ * click, and the refusal that follows names its own reason. The opposite default would hide charts
54
+ * from readers on exactly the servers that cannot tell us it is wrong to.
55
+ */
56
+ export declare function refusalIsSelectable(row: QualifyRefusalRow | null | undefined): boolean;
57
+ /**
58
+ * The refused rows in RENDER ORDER: everything pickable first, then the vetoes.
59
+ *
60
+ * A STABLE PARTITION, not a sort — within each block the server's alphabetical order survives, so
61
+ * two answers over the same shape stay diffable. Rows without a name are dropped: a control
62
+ * labelled with nothing cannot be chosen and a reason with no subject cannot be read.
63
+ *
64
+ * The two blocks are ordered pickable-first because the reader opened this section to DO something.
65
+ * Putting the inert half above the actionable half makes them scroll past every chart they cannot
66
+ * have to reach the ones they can.
67
+ */
68
+ export declare function orderRefusalsForDisplay<T extends QualifyRefusalRow>(rows: readonly T[] | null | undefined): T[];
69
+ /**
70
+ * The heading (if any) belonging immediately before `row`, MUTATING `state` — same shape as
71
+ * `qualifyGroupHeadingFor` so the two loops read alike.
72
+ *
73
+ * Assumes `rows` came through `orderRefusalsForDisplay`; fed an unpartitioned list it would write
74
+ * a heading at every alternation, which is why the ordering and the headings are one export pair
75
+ * rather than two independent helpers a host can half-adopt.
76
+ */
77
+ export declare function qualifyRefusalHeadingFor(row: QualifyRefusalRow, state: QualifyRefusalGroupState): QualifyRefusalHeading | null;
78
+ /**
79
+ * Is there anything behind "Show all chart types"? A checkbox that reveals nothing is worse than
80
+ * no checkbox: it reads as a broken control rather than an empty category.
81
+ */
82
+ export declare function hasRefusalsToShow(rows: readonly QualifyRefusalRow[] | null | undefined): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.5.47",
3
+ "version": "0.5.49",
4
4
  "description": "Run a BIC-generated D3 chart in any web host: compiles the generated render() function, applies the shared option defaults, resolves mark clicks (through tooltip overlays), owns the selection affordance, and translates row indices between cross-filtered charts. The same contract the BIC Power BI visual implements, minus Power BI. React bindings at @bicharts/chart-host/react.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",