@bicharts/chart-host 0.6.30 → 0.6.32

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.
@@ -142,7 +142,7 @@ var require_papaparse_min = __commonJS({
142
142
  return "greedy" === m2.skipEmptyLines ? "" === e2.join("").trim() : 1 === e2.length && 0 === e2[0].length;
143
143
  }
144
144
  function g4() {
145
- if (p4 && a5 && (k4("Delimiter", "UndetectableDelimiter", "Unable to auto-detect delimiting character; defaulted to '" + v4.DefaultDelimiter + "'"), a5 = false), m2.skipEmptyLines && (p4.data = p4.data.filter(function(e4) {
145
+ if (p4 && a5 && (k3("Delimiter", "UndetectableDelimiter", "Unable to auto-detect delimiting character; defaulted to '" + v4.DefaultDelimiter + "'"), a5 = false), m2.skipEmptyLines && (p4.data = p4.data.filter(function(e4) {
146
146
  return !y6(e4);
147
147
  })), _3()) {
148
148
  let t4 = function(e4, t5) {
@@ -164,7 +164,7 @@ var require_papaparse_min = __commonJS({
164
164
  })(t5) ? parseFloat(t5) : d3.test(t5) ? new Date(t5) : "" === t5 ? null : t5) : t5)(n4 = m2.header ? r5 >= c4.length ? "__parsed_extra" : c4[r5] : n4, s4 = m2.transform ? m2.transform(s4, n4) : s4);
165
165
  "__parsed_extra" === n4 ? (i5[n4] = i5[n4] || [], i5[n4].push(s4)) : i5[n4] = s4;
166
166
  }
167
- return m2.header && (r5 > c4.length ? k4("FieldMismatch", "TooManyFields", "Too many fields: expected " + c4.length + " fields but parsed " + r5, f5 + t4) : r5 < c4.length && k4("FieldMismatch", "TooFewFields", "Too few fields: expected " + c4.length + " fields but parsed " + r5, f5 + t4)), i5;
167
+ return m2.header && (r5 > c4.length ? k3("FieldMismatch", "TooManyFields", "Too many fields: expected " + c4.length + " fields but parsed " + r5, f5 + t4) : r5 < c4.length && k3("FieldMismatch", "TooFewFields", "Too few fields: expected " + c4.length + " fields but parsed " + r5, f5 + t4)), i5;
168
168
  }
169
169
  var r4;
170
170
  p4 && (m2.header || m2.dynamicTyping || m2.transform) && (r4 = 1, !p4.data.length || Array.isArray(p4.data[0]) ? (p4.data = p4.data.map(i4), r4 = p4.data.length) : p4.data = i4(p4.data, 0), m2.header && p4.meta && (p4.meta.fields = c4), f5 += r4);
@@ -172,7 +172,7 @@ var require_papaparse_min = __commonJS({
172
172
  function _3() {
173
173
  return m2.header && 0 === c4.length;
174
174
  }
175
- function k4(e2, t2, i4, r4) {
175
+ function k3(e2, t2, i4, r4) {
176
176
  e2 = { type: e2, code: t2, message: i4 };
177
177
  void 0 !== r4 && (e2.row = r4), p4.errors.push(e2);
178
178
  }
@@ -211,7 +211,7 @@ var require_papaparse_min = __commonJS({
211
211
  return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
212
212
  }
213
213
  function E4(C2) {
214
- var S = (C2 = C2 || {}).delimiter, O3 = C2.newline, x2 = C2.comments, I4 = C2.step, A2 = C2.preview, T4 = C2.fastMode, D3 = null, L2 = false, F3 = null == C2.quoteChar ? '"' : C2.quoteChar, j3 = F3;
214
+ var S = (C2 = C2 || {}).delimiter, O3 = C2.newline, x2 = C2.comments, I4 = C2.step, A2 = C2.preview, T4 = C2.fastMode, D3 = null, L4 = false, F3 = null == C2.quoteChar ? '"' : C2.quoteChar, j3 = F3;
215
215
  if (void 0 !== C2.escapeChar && (j3 = C2.escapeChar), ("string" != typeof S || -1 < v4.BAD_DELIMITERS.indexOf(S)) && (S = ","), x2 === S) throw new Error("Comment character same as delimiter");
216
216
  true === x2 ? x2 = "#" : ("string" != typeof x2 || -1 < v4.BAD_DELIMITERS.indexOf(x2)) && (x2 = false), "\n" !== O3 && "\r" !== O3 && "\r\n" !== O3 && (O3 = "\n");
217
217
  var z4 = 0, M = false;
@@ -225,8 +225,8 @@ var require_papaparse_min = __commonJS({
225
225
  else if (r2) return w3();
226
226
  if (!x2 || d3.substring(0, a5) !== x2) {
227
227
  if (o2) {
228
- if (h4 = [], k4(d3.split(S)), R2(), M) return w3();
229
- } else k4(d3.split(S));
228
+ if (h4 = [], k3(d3.split(S)), R2(), M) return w3();
229
+ } else k3(d3.split(S));
230
230
  if (A2 && A2 <= c4) return h4 = h4.slice(0, A2), w3(true);
231
231
  }
232
232
  }
@@ -262,7 +262,7 @@ var require_papaparse_min = __commonJS({
262
262
  if (A2 && h4.length >= A2) return w3(true);
263
263
  }
264
264
  return E5();
265
- function k4(e2) {
265
+ function k3(e2) {
266
266
  h4.push(e2), f5 = z4;
267
267
  }
268
268
  function v5(e2) {
@@ -270,13 +270,13 @@ var require_papaparse_min = __commonJS({
270
270
  return t2 = -1 !== e2 && (e2 = i2.substring(m2 + 1, e2)) && "" === e2.trim() ? e2.length : t2;
271
271
  }
272
272
  function E5(e2) {
273
- return r2 || (void 0 === e2 && (e2 = i2.substring(z4)), d3.push(e2), z4 = n2, k4(d3), o2 && R2()), w3();
273
+ return r2 || (void 0 === e2 && (e2 = i2.substring(z4)), d3.push(e2), z4 = n2, k3(d3), o2 && R2()), w3();
274
274
  }
275
275
  function b5(e2) {
276
- z4 = e2, k4(d3), d3 = [], g4 = i2.indexOf(O3, z4);
276
+ z4 = e2, k3(d3), d3 = [], g4 = i2.indexOf(O3, z4);
277
277
  }
278
278
  function w3(e2) {
279
- if (C2.header && !t && h4.length && !L2) {
279
+ if (C2.header && !t && h4.length && !L4) {
280
280
  var s4 = h4[0], a6 = /* @__PURE__ */ Object.create(null), o4 = new Set(s4);
281
281
  let n4 = false;
282
282
  for (let r4 = 0; r4 < s4.length; r4++) {
@@ -288,7 +288,7 @@ var require_papaparse_min = __commonJS({
288
288
  } else a6[i4] = 1, s4[r4] = i4;
289
289
  o4.add(i4);
290
290
  }
291
- n4 && console.warn("Duplicate headers found and renamed."), L2 = true;
291
+ n4 && console.warn("Duplicate headers found and renamed."), L4 = true;
292
292
  }
293
293
  return { data: h4, errors: u4, meta: { delimiter: S, linebreak: O3, aborted: M, truncated: !!e2, cursor: f5 + (t || 0), renamedHeaders: D3 } };
294
294
  }
@@ -368,7 +368,7 @@ var require_papaparse_min = __commonJS({
368
368
  function n2(e2, t2, i4) {
369
369
  var r4 = "", n4 = ("string" == typeof e2 && (e2 = JSON.parse(e2)), "string" == typeof t2 && (t2 = JSON.parse(t2)), Array.isArray(e2) && 0 < e2.length), s4 = !Array.isArray(t2[0]);
370
370
  if (n4 && _3) {
371
- for (var a6 = 0; a6 < e2.length; a6++) 0 < a6 && (r4 += m2), r4 += k4(e2[a6], a6);
371
+ for (var a6 = 0; a6 < e2.length; a6++) 0 < a6 && (r4 += m2), r4 += k3(e2[a6], a6);
372
372
  0 < t2.length && (r4 += y6);
373
373
  }
374
374
  for (var o4 = 0; o4 < t2.length; o4++) {
@@ -384,14 +384,14 @@ var require_papaparse_min = __commonJS({
384
384
  for (var p4 = 0; p4 < h5; p4++) {
385
385
  0 < p4 && !d3 && (r4 += m2);
386
386
  var g4 = n4 && s4 ? e2[p4] : p4;
387
- r4 += k4(t2[o4][g4], p4);
387
+ r4 += k3(t2[o4][g4], p4);
388
388
  }
389
389
  o4 < t2.length - 1 && (!i4 || 0 < h5 && !d3) && (r4 += y6);
390
390
  }
391
391
  }
392
392
  return r4;
393
393
  }
394
- function k4(e2, t2) {
394
+ function k3(e2, t2) {
395
395
  var i4, r4, n4;
396
396
  return null == e2 ? "" : e2.constructor === Date ? JSON.stringify(e2).slice(1, 25) : (n4 = false, h4 && "string" == typeof e2 && h4.test(e2) && (e2 = "'" + e2, n4 = true), r4 = (i4 = e2.toString()).replace(u4, o2), (n4 = n4 || true === s2 || "function" == typeof s2 && s2(e2, t2) || Array.isArray(s2) && s2[t2] || ((e4, t4) => {
397
397
  for (var i5 = 0; i5 < t4.length; i5++) if (-1 < e4.indexOf(t4[i5])) return true;
@@ -451,9 +451,9 @@ var CONTAINER_SLOT_UI_STATE = "__lchUiState";
451
451
  var VIEW_ONLY_UI_STATE_KEYS = Object.freeze(["camera", "llmZoom"]);
452
452
  function withoutViewOnlyKeys(bag) {
453
453
  if (!bag || typeof bag !== "object") return bag;
454
- if (!VIEW_ONLY_UI_STATE_KEYS.some((k4) => Object.prototype.hasOwnProperty.call(bag, k4))) return bag;
454
+ if (!VIEW_ONLY_UI_STATE_KEYS.some((k3) => Object.prototype.hasOwnProperty.call(bag, k3))) return bag;
455
455
  const out = { ...bag };
456
- for (const k4 of VIEW_ONLY_UI_STATE_KEYS) delete out[k4];
456
+ for (const k3 of VIEW_ONLY_UI_STATE_KEYS) delete out[k3];
457
457
  return out;
458
458
  }
459
459
  var HOST_CONTAINER_CLASS = "bic-chart-host";
@@ -666,10 +666,10 @@ function censusColourSpread(container, doc) {
666
666
  for (const { rgb } of counted) {
667
667
  marks++;
668
668
  distinct.add(rgb.join(","));
669
- const k4 = cellKey(rgb);
670
- const cur = cells.get(k4);
669
+ const k3 = cellKey(rgb);
670
+ const cur = cells.get(k3);
671
671
  if (cur) cur.n++;
672
- else cells.set(k4, { rgb, n: 1 });
672
+ else cells.set(k3, { rgb, n: 1 });
673
673
  }
674
674
  if (marks < MIN_MARKS || distinct.size < MIN_RAMP_FILLS) return EMPTY;
675
675
  const top = [...cells.values()].sort((a4, b4) => b4.n - a4.n).slice(0, MAX_CELLS);
@@ -748,8 +748,8 @@ function autoRampMinStep(low, high, canvas, classes = AUTO_RAMP_CLASSES, opacity
748
748
  const bg = normHex(canvas);
749
749
  if (!lo || !hi || !bg || classes < 2) return NaN;
750
750
  let prev = null, min = Infinity;
751
- for (let k4 = 0; k4 < classes; k4++) {
752
- const painted = paintedOver(labToHex(mixLab(lo, hi, k4 / (classes - 1))), bg, opacity);
751
+ for (let k3 = 0; k3 < classes; k3++) {
752
+ const painted = paintedOver(labToHex(mixLab(lo, hi, k3 / (classes - 1))), bg, opacity);
753
753
  if (prev) min = Math.min(min, deltaE2000(prev, painted));
754
754
  prev = painted;
755
755
  }
@@ -784,9 +784,9 @@ function resolveAutoColorScale(p2) {
784
784
  let high = { ...A2 };
785
785
  let highHex = labToHex(high);
786
786
  for (let step = 0; step < 80 && autoRampMinStep(lowHex, highHex, canvas) < AUTO_RAMP_MIN_STEP_DELTA_E; step++) {
787
- const L2 = Math.max(4, Math.min(98, high.L + (darkCanvas ? 1 : -1)));
788
- if (L2 === high.L) break;
789
- high = { ...high, L: L2 };
787
+ const L4 = Math.max(4, Math.min(98, high.L + (darkCanvas ? 1 : -1)));
788
+ if (L4 === high.L) break;
789
+ high = { ...high, L: L4 };
790
790
  highHex = labToHex(high);
791
791
  }
792
792
  memoKey = key;
@@ -953,12 +953,12 @@ var byAsset = /* @__PURE__ */ new Map();
953
953
  var _na;
954
954
  function geoAssetFor(geoKind) {
955
955
  if (!geoKind) return null;
956
- const k4 = geoKind.toLowerCase();
957
- if (/^country/.test(k4)) return "world";
958
- if (k4 === "north-america") return "world";
959
- if (k4 === "world") return "world";
960
- if (k4 === "us-state-code" || k4 === "us-state-name") return "us-states";
961
- if (k4 === "us-zip5") return "us-zip3";
956
+ const k3 = geoKind.toLowerCase();
957
+ if (/^country/.test(k3)) return "world";
958
+ if (k3 === "north-america") return "world";
959
+ if (k3 === "world") return "world";
960
+ if (k3 === "us-state-code" || k3 === "us-state-name") return "us-states";
961
+ if (k3 === "us-zip5") return "us-zip3";
962
962
  return null;
963
963
  }
964
964
  var _worldBase;
@@ -1584,7 +1584,7 @@ var wt = new RegExp([String.raw`\bisMeasure\b`, String.raw`\bdataType\b`, String
1584
1584
  /*! @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. */
1585
1585
  var K3 = 2;
1586
1586
  var J4 = 400;
1587
- function B3(e) {
1587
+ function z3(e) {
1588
1588
  return !!E(e);
1589
1589
  }
1590
1590
  function T3(e) {
@@ -1598,8 +1598,8 @@ function T3(e) {
1598
1598
  }
1599
1599
  function v3(e) {
1600
1600
  let n = T3(e);
1601
- if (n.length === 0 || W2(e) < 95) return false;
1602
- let t = n.filter((u2) => B3(u2) && !Y(u2)).length, o = n.filter((u2) => !B3(u2) && !!Y(u2)).length;
1601
+ if (n.length === 0 || B3(e) < 95) return false;
1602
+ let t = n.filter((u2) => z3(u2) && !Y(u2)).length, o = n.filter((u2) => !z3(u2) && !!Y(u2)).length;
1603
1603
  return t >= 1 && t >= o;
1604
1604
  }
1605
1605
  function Y3(e, n) {
@@ -1607,21 +1607,21 @@ function Y3(e, n) {
1607
1607
  let t = E(e);
1608
1608
  return t ? n === "world" ? true : s3.has(t) : false;
1609
1609
  }
1610
- function W2(e) {
1610
+ function B3(e) {
1611
1611
  let n = T3(e);
1612
1612
  if (n.length === 0) return 0;
1613
1613
  let t = 0;
1614
- for (let o of n) B3(o) && t++;
1614
+ for (let o of n) z3(o) && t++;
1615
1615
  return Math.round(t / n.length * 1e3) / 10;
1616
1616
  }
1617
- function k3(e) {
1617
+ function L2(e) {
1618
1618
  let n = T3(e);
1619
1619
  if (n.length === 0) return 0;
1620
1620
  let t = 0;
1621
1621
  for (let o of n) Y(o) && t++;
1622
1622
  return Math.round(t / n.length * 1e3) / 10;
1623
1623
  }
1624
- function $2(e) {
1624
+ function U3(e) {
1625
1625
  let n = /* @__PURE__ */ new Set();
1626
1626
  for (let t of e) {
1627
1627
  if (t == null) continue;
@@ -1630,15 +1630,15 @@ function $2(e) {
1630
1630
  }
1631
1631
  return Array.from(n);
1632
1632
  }
1633
- function U3(e) {
1634
- let n = $2(e);
1633
+ function $2(e) {
1634
+ let n = U3(e);
1635
1635
  if (n.length === 0) return 0;
1636
1636
  let t = 0;
1637
1637
  for (let o of n) Z(o).length > 0 && t++;
1638
1638
  return Math.round(t / n.length * 1e3) / 10;
1639
1639
  }
1640
1640
  function Z3(e, n) {
1641
- return y4(n, rt) ? true : $2(e).some((t) => /^\d{5}(-\d{4})?$/.test(t.replace(/\.0+$/, "")));
1641
+ return y4(n, rt) ? true : U3(e).some((t) => /^\d{5}(-\d{4})?$/.test(t.replace(/\.0+$/, "")));
1642
1642
  }
1643
1643
  function ot(e, n) {
1644
1644
  let t = T3(e);
@@ -1647,21 +1647,21 @@ function ot(e, n) {
1647
1647
  for (let u2 of t) p3(u2, n) && o++;
1648
1648
  return Math.round(o / t.length * 1e3) / 10;
1649
1649
  }
1650
- function z3(e, n) {
1650
+ function W2(e, n) {
1651
1651
  let t = 0;
1652
1652
  for (let o of T3(e)) n(o) && t++;
1653
1653
  return t;
1654
1654
  }
1655
1655
  function it2(e, n) {
1656
1656
  let t = 0;
1657
- for (let o of $2(e)) n(o) && t++;
1657
+ for (let o of U3(e)) n(o) && t++;
1658
1658
  return t;
1659
1659
  }
1660
1660
  function st(e, n, t, o, u2) {
1661
- let a4 = [], s = [], i = {}, h3 = {}, R2 = new Set(e), f4 = (r) => n.map((l) => l[r]);
1661
+ let a4 = [], s = [], i = {}, h3 = {}, x2 = new Set(e), f4 = (r) => n.map((l) => l[r]);
1662
1662
  for (let r of ["city", "country"]) {
1663
1663
  let l = t?.[r];
1664
- l && R2.has(l) && (i[r] = l);
1664
+ l && x2.has(l) && (i[r] = l);
1665
1665
  }
1666
1666
  let ue = new Set(u2 ?? e);
1667
1667
  for (let r of ["lat", "lon"]) {
@@ -1669,31 +1669,31 @@ function st(e, n, t, o, u2) {
1669
1669
  l && ue.has(l) && (i[r] = l);
1670
1670
  }
1671
1671
  let C2 = t?.zip;
1672
- if (C2 && R2.has(C2)) {
1673
- let r = f4(C2), l = U3(r);
1672
+ if (C2 && x2.has(C2)) {
1673
+ let r = f4(C2), l = $2(r);
1674
1674
  l < 95 ? s.push(`zip=${C2} (only ${l}% of values read as ZIPs)`) : Z3(r, C2) ? i.zip = C2 : s.push(`zip=${C2} (all values are 3-4 digits with nothing to say they are postal)`);
1675
1675
  }
1676
1676
  let g3 = t?.state;
1677
- if (g3 && R2.has(g3)) {
1677
+ if (g3 && x2.has(g3)) {
1678
1678
  let r = f4(g3), l = T3(r);
1679
- l.length > 0 && l.every((d2) => Y3(d2, o)) ? s.push(`state=${g3} (every value is "CA", which is both Canada and California)`) : v3(r) ? (s.push(`state=${g3} (every value is a country, not a state)`), i.country || (i.country = g3)) : k3(r) < 95 ? s.push(`state=${g3} (only ${k3(r)}% of values are states/provinces)`) : i.state = g3;
1679
+ l.length > 0 && l.every((d2) => Y3(d2, o)) ? s.push(`state=${g3} (every value is "CA", which is both Canada and California)`) : v3(r) ? (s.push(`state=${g3} (every value is a country, not a state)`), i.country || (i.country = g3)) : L2(r) < 95 ? s.push(`state=${g3} (only ${L2(r)}% of values are states/provinces)`) : i.state = g3;
1680
1680
  }
1681
- let b4 = new Set(Object.values(i).filter(Boolean)), M = e.filter((r) => !b4.has(r) && !r.startsWith("__"));
1681
+ let b4 = new Set(Object.values(i).filter(Boolean)), F3 = e.filter((r) => !b4.has(r) && !r.startsWith("__"));
1682
1682
  if (!i.state) {
1683
1683
  let r = null;
1684
- for (let l of M) {
1684
+ for (let l of F3) {
1685
1685
  let d2 = f4(l);
1686
1686
  if (v3(d2)) continue;
1687
- let p2 = k3(d2);
1687
+ let p2 = L2(d2);
1688
1688
  if (p2 < 95) continue;
1689
- let _2 = z3(d2, (w3) => !!Y(w3)), de2 = z3(d2, (w3) => !!Y(w3) && !Y3(w3, o));
1690
- _2 < K3 && de2 < 1 || (!r || p2 > r.pct) && (r = { name: l, pct: p2 });
1689
+ let k3 = W2(d2, (I4) => !!Y(I4)), de2 = W2(d2, (I4) => !!Y(I4) && !Y3(I4, o));
1690
+ k3 < K3 && de2 < 1 || (!r || p2 > r.pct) && (r = { name: l, pct: p2 });
1691
1691
  }
1692
1692
  r && (i.state = r.name, b4.add(r.name), a4.push(`state=${r.name} (${r.pct}% states/provinces)`));
1693
1693
  }
1694
- if (!i.zip) for (let r of M) {
1694
+ if (!i.zip) for (let r of F3) {
1695
1695
  if (b4.has(r)) continue;
1696
- let l = f4(r), d2 = U3(l);
1696
+ let l = f4(r), d2 = $2(l);
1697
1697
  if (!(d2 < 95) && Z3(l, r) && !(it2(l, (p2) => Z(p2).length > 0) < K3)) {
1698
1698
  i.zip = r, b4.add(r), a4.push(`zip=${r} (${d2}% ZIP codes)`);
1699
1699
  break;
@@ -1702,29 +1702,30 @@ function st(e, n, t, o, u2) {
1702
1702
  let P4 = i.country;
1703
1703
  if (!P4 || !v3(f4(P4))) {
1704
1704
  let r = null;
1705
- for (let l of M) {
1705
+ for (let l of F3) {
1706
1706
  if (b4.has(l) || !v3(f4(l))) continue;
1707
- let d2 = W2(f4(l));
1707
+ let d2 = B3(f4(l));
1708
1708
  (!r || d2 > r.pct) && (r = { name: l, pct: d2 });
1709
1709
  }
1710
- r && (P4 && (s.push(`country=${P4} (only ${W2(f4(P4))}% of values are country identifiers; using ${r.name} instead)`), h3.country = P4), i.country = r.name, b4.add(r.name), a4.push(`country=${r.name}`));
1710
+ r && (P4 && (s.push(`country=${P4} (only ${B3(f4(P4))}% of values are country identifiers; using ${r.name} instead)`), h3.country = P4), i.country = r.name, b4.add(r.name), a4.push(`country=${r.name}`));
1711
1711
  }
1712
1712
  if (!i.city) {
1713
1713
  let r = null;
1714
- for (let l of M) {
1714
+ for (let l of F3) {
1715
1715
  if (b4.has(l)) continue;
1716
1716
  let d2 = f4(l), p2 = ot(d2, o);
1717
- p2 < m3 || z3(d2, (_2) => p3(_2, o)) < K3 || (!r || p2 > r.pct) && (r = { name: l, pct: p2 });
1717
+ p2 < m3 || W2(d2, (k3) => p3(k3, o)) < K3 || (!r || p2 > r.pct) && (r = { name: l, pct: p2 });
1718
1718
  }
1719
1719
  r && (i.city = r.name, a4.push(`city=${r.name} (${r.pct}% known cities)`));
1720
1720
  }
1721
- let H3 = i.country ? f4(i.country) : [], E4 = !!i.country && v3(H3), ce = E4 ? new Set(H3.map((r) => E(r == null ? null : String(r))).filter(Boolean)).size : 0, j3 = E4 && ce >= 2, O3 = !!(i.lat && i.lon) && n.some((r) => {
1721
+ let H3 = i.country ? f4(i.country) : [], _2 = !!i.country && v3(H3), ce = _2 ? new Set(H3.map((r) => E(r == null ? null : String(r))).filter(Boolean)).size : 0, j3 = _2 && ce >= 2, O3 = !!(i.lat && i.lon) && n.some((r) => {
1722
1722
  let l = +String(r[i.lat] ?? "").trim(), d2 = +String(r[i.lon] ?? "").trim();
1723
1723
  return isFinite(l) && isFinite(d2) && l >= -90 && l <= 90 && d2 >= -180 && d2 <= 180 && String(r[i.lat] ?? "").trim() !== "" && String(r[i.lon] ?? "").trim() !== "";
1724
1724
  });
1725
- return i.lat && i.lon && !O3 && s.push(`lat/lon=${i.lat}/${i.lon} (no row holds a usable coordinate pair)`), i.country && !j3 && !(i.city || i.state || i.zip || O3) && s.push(E4 ? `country=${i.country} (every row resolves to the same country - nothing to place apart)` : `country=${i.country} (values are not country identifiers)`), { bind: !!(i.city || i.state || i.zip || j3 || O3) ? i : null, backfilled: a4, refused: s, ...Object.keys(h3).length ? { labelFallback: h3 } : {} };
1725
+ return i.lat && i.lon && !O3 && s.push(`lat/lon=${i.lat}/${i.lon} (no row holds a usable coordinate pair)`), i.country && !j3 && !(i.city || i.state || i.zip || O3) && s.push(_2 ? `country=${i.country} (every row resolves to the same country - nothing to place apart)` : `country=${i.country} (values are not country identifiers)`), { bind: !!(i.city || i.state || i.zip || j3 || O3) ? i : null, backfilled: a4, refused: s, ...Object.keys(h3).length ? { labelFallback: h3 } : {} };
1726
1726
  }
1727
1727
  var St3 = Object.freeze({ integer: "number", decimal: "number", double: "number", datetime: "date", date: "date", boolean: "boolean", string: "text" });
1728
+ var Nt2 = Object.freeze({ RENDER_START: "render-start", RENDER_OK: "render-ok", RENDER_ERROR: "render-error", VIEW: "view", VIEW_VERDICT: "view-verdict" });
1728
1729
 
1729
1730
  // src/payload.ts
1730
1731
  function resolvePointChannel(cols, rowObjs, point) {
@@ -1833,20 +1834,20 @@ function buildRenderPayload(cols, rowObjs, geo, point, destination, opts) {
1833
1834
  a4[c2] = v4 ?? null;
1834
1835
  }
1835
1836
  }
1836
- let k4 = cols.length;
1837
- a4[k4++] = r;
1838
- if (geoIso) a4[k4++] = geoIso[r];
1837
+ let k3 = cols.length;
1838
+ a4[k3++] = r;
1839
+ if (geoIso) a4[k3++] = geoIso[r];
1839
1840
  if (pLat && pLon) {
1840
- a4[k4++] = pLat[r];
1841
- a4[k4++] = pLon[r];
1842
- a4[k4++] = pPrec ? pPrec[r] : null;
1841
+ a4[k3++] = pLat[r];
1842
+ a4[k3++] = pLon[r];
1843
+ a4[k3++] = pPrec ? pPrec[r] : null;
1843
1844
  }
1844
1845
  if (dLat && dLon) {
1845
- a4[k4++] = dLat[r];
1846
- a4[k4++] = dLon[r];
1847
- a4[k4++] = dPrec ? dPrec[r] : null;
1846
+ a4[k3++] = dLat[r];
1847
+ a4[k3++] = dLon[r];
1848
+ a4[k3++] = dPrec ? dPrec[r] : null;
1848
1849
  }
1849
- for (const ac of aliasCols) a4[k4++] = a4[ac.from];
1850
+ for (const ac of aliasCols) a4[k3++] = a4[ac.from];
1850
1851
  out[r] = a4;
1851
1852
  }
1852
1853
  const colsOut = [...cols, { name: "__rowIdx__", dataType: "Integer", isMeasure: false, modelDesc: "" }];
@@ -2050,14 +2051,14 @@ function createMarkResolver(env) {
2050
2051
  return s === "transparent" || s === "none" || so <= 0.01;
2051
2052
  };
2052
2053
  const distToPathCenterline = (el, x2, y5) => {
2053
- const L2 = el.getTotalLength();
2054
- if (!(L2 > 0)) return Number.MAX_VALUE;
2054
+ const L4 = el.getTotalLength();
2055
+ if (!(L4 > 0)) return Number.MAX_VALUE;
2055
2056
  const m = el.getScreenCTM();
2056
2057
  if (!m) return Number.MAX_VALUE;
2057
2058
  let best = Number.MAX_VALUE;
2058
2059
  const N3 = 64;
2059
2060
  for (let i = 0; i <= N3; i++) {
2060
- const pt2 = el.getPointAtLength(L2 * i / N3);
2061
+ const pt2 = el.getPointAtLength(L4 * i / N3);
2061
2062
  const dx = m.a * pt2.x + m.c * pt2.y + m.e - x2;
2062
2063
  const dy = m.b * pt2.x + m.d * pt2.y + m.f - y5;
2063
2064
  const d2 = dx * dx + dy * dy;
@@ -2442,10 +2443,10 @@ function censusValuePlacement(container, data) {
2442
2443
  for (const axis of ["x", "y"]) {
2443
2444
  const keep = [];
2444
2445
  const v4 = [], pos = [];
2445
- dots.forEach((d2, k4) => {
2446
- if (!Number.isFinite(vals[k4])) return;
2447
- keep.push(k4);
2448
- v4.push(log ? Math.log10(vals[k4]) : vals[k4]);
2446
+ dots.forEach((d2, k3) => {
2447
+ if (!Number.isFinite(vals[k3])) return;
2448
+ keep.push(k3);
2449
+ v4.push(log ? Math.log10(vals[k3]) : vals[k3]);
2449
2450
  pos.push(axis === "x" ? d2.x : d2.y);
2450
2451
  });
2451
2452
  const line = robustLine(v4, pos);
@@ -2454,8 +2455,8 @@ function censusValuePlacement(container, data) {
2454
2455
  if (hi - lo < MIN_AXIS_SPAN_PX) continue;
2455
2456
  const mean = pos.reduce((s, p2) => s + p2, 0) / pos.length;
2456
2457
  let ssRes = 0, ssTot = 0;
2457
- const res = pos.map((p2, k4) => {
2458
- const e = p2 - (line.a + line.b * v4[k4]);
2458
+ const res = pos.map((p2, k3) => {
2459
+ const e = p2 - (line.a + line.b * v4[k3]);
2459
2460
  ssRes += e * e;
2460
2461
  ssTot += (p2 - mean) ** 2;
2461
2462
  return e;
@@ -2464,8 +2465,8 @@ function censusValuePlacement(container, data) {
2464
2465
  const fit = 1 - ssRes / ssTot;
2465
2466
  if (fit >= VALUE_AXIS_MIN_FIT && (!best || fit > best.fit)) {
2466
2467
  const full = new Array(dots.length).fill(NaN);
2467
- keep.forEach((k4, j3) => {
2468
- full[k4] = res[j3];
2468
+ keep.forEach((k3, j3) => {
2469
+ full[k3] = res[j3];
2469
2470
  });
2470
2471
  best = { col: c2, axis, fit, res: full, log };
2471
2472
  }
@@ -2475,8 +2476,8 @@ function censusValuePlacement(container, data) {
2475
2476
  if (!best) return EMPTY4;
2476
2477
  let off = 0, measured = 0;
2477
2478
  const radii = [];
2478
- dots.forEach((d2, k4) => {
2479
- const e = best.res[k4];
2479
+ dots.forEach((d2, k3) => {
2480
+ const e = best.res[k3];
2480
2481
  if (!Number.isFinite(e)) return;
2481
2482
  measured++;
2482
2483
  const inRadii = Math.abs(e) / Math.max(d2.r, 1);
@@ -3051,8 +3052,8 @@ var NAMED = {
3051
3052
  };
3052
3053
  function toRGBA(c2) {
3053
3054
  if (typeof c2 !== "string") return null;
3054
- const k4 = c2.trim().toLowerCase();
3055
- if (k4 in NAMED) return NAMED[k4];
3055
+ const k3 = c2.trim().toLowerCase();
3056
+ if (k3 in NAMED) return NAMED[k3];
3056
3057
  return parseRGBA(c2);
3057
3058
  }
3058
3059
  function compositeOver(fg, bg) {
@@ -3102,12 +3103,12 @@ var GLYPH_SAMPLE_N = 3;
3102
3103
  function glyphSampleGrid(box, n = GLYPH_SAMPLE_N) {
3103
3104
  const out = [];
3104
3105
  if (!box || !(box.width > 0) || !(box.height > 0) || !(n >= 1)) return out;
3105
- const k4 = Math.floor(n);
3106
- for (let i = 0; i < k4; i++) {
3107
- for (let j3 = 0; j3 < k4; j3++) {
3106
+ const k3 = Math.floor(n);
3107
+ for (let i = 0; i < k3; i++) {
3108
+ for (let j3 = 0; j3 < k3; j3++) {
3108
3109
  out.push({
3109
- x: box.left + box.width * (i + 0.5) / k4,
3110
- y: box.top + box.height * (j3 + 0.5) / k4
3110
+ x: box.left + box.width * (i + 0.5) / k3,
3111
+ y: box.top + box.height * (j3 + 0.5) / k3
3111
3112
  });
3112
3113
  }
3113
3114
  }
@@ -3322,7 +3323,7 @@ function sessionViewStateProvider(container) {
3322
3323
  load: () => store,
3323
3324
  save: (next) => {
3324
3325
  if (!next || typeof next !== "object") return;
3325
- for (const k4 of Object.keys(store)) delete store[k4];
3326
+ for (const k3 of Object.keys(store)) delete store[k3];
3326
3327
  Object.assign(store, next);
3327
3328
  }
3328
3329
  };
@@ -3851,10 +3852,10 @@ function toSourceRows(rowMap, payloadRowIdxs) {
3851
3852
  }
3852
3853
  function toPayloadRows(rowMap, sourceRowIdxs) {
3853
3854
  const at3 = /* @__PURE__ */ new Map();
3854
- rowMap.forEach((src, k4) => {
3855
- if (!at3.has(src)) at3.set(src, k4);
3855
+ rowMap.forEach((src, k3) => {
3856
+ if (!at3.has(src)) at3.set(src, k3);
3856
3857
  });
3857
- return sourceRowIdxs.map((s) => at3.get(s)).filter((k4) => k4 !== void 0);
3858
+ return sourceRowIdxs.map((s) => at3.get(s)).filter((k3) => k3 !== void 0);
3858
3859
  }
3859
3860
  var sameRows = (a4, b4) => {
3860
3861
  if (a4.length !== b4.length) return false;
package/dist/index.mjs CHANGED
@@ -140,10 +140,64 @@ import {
140
140
  unpinScrolledAxis,
141
141
  valuePlacementFlag,
142
142
  withoutViewOnlyKeys
143
- } from "./chunk-KONJ3DXV.mjs";
143
+ } from "./chunk-P22NUGCZ.mjs";
144
144
  import "./chunk-A2GMXZP7.mjs";
145
145
  import "./chunk-GHODWOAL.mjs";
146
146
 
147
+ // src/optionsVocabulary.ts
148
+ var MAX_MAP_POINTS_MIN = 10;
149
+ var MAX_MAP_POINTS_MAX = 1e5;
150
+ var LIMIT_COUNT_MAX = 1e4;
151
+ var entry = (e2) => Object.freeze({ ...e2, ...e2.values ? { values: Object.freeze([...e2.values]) } : {} });
152
+ var OPTIONS_VOCABULARY = Object.freeze({
153
+ // ---- drawn from on every render, and stated on the request so the model reasons about them ----
154
+ aggregation: entry({ timing: "live-and-next-generate", default: "", values: ["", "sum", "average", "median", "min", "max", "count", "distinct"], wire: "request" }),
155
+ colorScaleLow: entry({ timing: "live-and-next-generate", default: "", wire: "request" }),
156
+ colorScaleHigh: entry({ timing: "live-and-next-generate", default: "", wire: "request" }),
157
+ /** Blank: the host's own colours when it offers them, else the engine's. */
158
+ palette: entry({ timing: "live-and-next-generate", default: "", wire: "request" }),
159
+ /** A HARD offer gate on the server as well as a live cap on what a point map plots. */
160
+ maxMapPoints: entry({ timing: "live-and-next-generate", default: MAX_MAP_POINTS_DEFAULT, min: MAX_MAP_POINTS_MIN, max: MAX_MAP_POINTS_MAX, wire: "clientHints" }),
161
+ // ---- live only ----
162
+ /** 0 means no paging. */
163
+ pageSize: entry({ timing: "live", default: 0, min: 0 }),
164
+ valueAxisBaseline: entry({ timing: "live", default: VALUE_AXIS_BASELINE_DEFAULT, values: ["fit", "zero", "auto"] }),
165
+ seasonalMarkers: entry({ timing: "live", default: SEASONAL_MARKERS_DEFAULT, values: ["auto", "always", "never"] }),
166
+ animAutoPlay: entry({ timing: "live", default: false }),
167
+ animPlaySpeedMs: entry({ timing: "live", default: ANIM_PLAY_SPEED_DEFAULT, min: ANIM_PLAY_SPEED_MIN, max: ANIM_PLAY_SPEED_MAX }),
168
+ /** 0 restarts at once; no upper bound, so a very large value plays once per viewing. */
169
+ animLoopDelaySec: entry({ timing: "live", default: ANIM_LOOP_DELAY_DEFAULT, min: ANIM_LOOP_DELAY_MIN }),
170
+ animStopAtEnd: entry({ timing: "live", default: false }),
171
+ animMaxIdealFrames: entry({ timing: "live", default: ANIM_MAX_IDEAL_FRAMES_DEFAULT, min: ANIM_MAX_IDEAL_FRAMES_MIN, max: ANIM_MAX_IDEAL_FRAMES_MAX }),
172
+ /** "" chooses by the number of periods. */
173
+ animTimelineStyle: entry({ timing: "live", default: "", values: ["", "line", "boxes"] }),
174
+ filtersDuringPlay: entry({ timing: "live", default: false }),
175
+ // ---- the next generated chart ----
176
+ levelOfDetail: entry({ timing: "next-generate", default: "", values: ["", "High", "Medium", "Low"], wire: "clientHints" }),
177
+ favorLimitTo: entry({ timing: "next-generate", default: "", values: ["", "latest", "top / greatest", "bottom / smallest", "most common", "outliers"], wire: "clientHints" }),
178
+ /** 0 asks for no limit, and travels as absent (`wireLimitCount`): any value the server receives is a limit. */
179
+ favorLimitCount: entry({ timing: "next-generate", default: 0, min: 0, max: LIMIT_COUNT_MAX, wire: "clientHints" }),
180
+ /** "1" asks for a title, "0" for none, "" leaves it to the engine. */
181
+ favorTitle: entry({ timing: "next-generate", default: "", values: ["", "1", "0"], wire: "clientHints" }),
182
+ /** Data labels on the marks: "1", "0", or "" for the engine's choice. */
183
+ favorDPValues: entry({ timing: "next-generate", default: "", values: ["", "1", "0"], wire: "clientHints" }),
184
+ legendPlacement: entry({ timing: "next-generate", default: "", values: ["", "outside", "inside", "none"], wire: "clientHints" }),
185
+ /** Free text: the industry the data belongs to. */
186
+ industryContext: entry({ timing: "next-generate", default: "", wire: "clientHints" }),
187
+ /** Free text: a font family for the chart's own text. */
188
+ suggestFontFamily: entry({ timing: "next-generate", default: "", wire: "clientHints" }),
189
+ // ---- after a chart is drawn ----
190
+ visionReview: entry({ timing: "after-render", default: false }),
191
+ saveThumbnails: entry({ timing: "after-render", default: false })
192
+ });
193
+ var LIVE_OPTION_KEYS = Object.freeze(
194
+ Object.keys(OPTIONS_VOCABULARY).filter((k2) => OPTIONS_VOCABULARY[k2].timing === "live" || OPTIONS_VOCABULARY[k2].timing === "live-and-next-generate")
195
+ );
196
+ function wireLimitCount(count) {
197
+ const n2 = typeof count === "number" ? count : count == null || count === "" ? NaN : Number(count);
198
+ return Number.isFinite(n2) && n2 > 0 ? n2 : null;
199
+ }
200
+
147
201
  // src/dateCells.ts
148
202
  var LOCAL_DATE_METHOD = /\.(?:getFullYear|getMonth|getDate|getDay|getHours|getMinutes|setFullYear|setMonth|setDate|setHours|setMinutes|setSeconds|setMilliseconds)\s*\(/;
149
203
  var D3_LOCAL_TIME = /\bd3\s*\.\s*(?:scaleTime|time[A-Z]\w*)\b/;
@@ -2542,14 +2596,19 @@ export {
2542
2596
  LEGIBLE_LIGHTNESS,
2543
2597
  LIFT_SELECTED_CLASS,
2544
2598
  LIGHT_TEXT,
2599
+ LIMIT_COUNT_MAX,
2600
+ LIVE_OPTION_KEYS,
2545
2601
  MARK_CLASS,
2546
2602
  MARK_SELECTED_CLASS,
2547
2603
  MAX_FRAME_GROW_FACTOR,
2548
2604
  MAX_MAP_POINTS_DEFAULT,
2605
+ MAX_MAP_POINTS_MAX,
2606
+ MAX_MAP_POINTS_MIN,
2549
2607
  MIN_CONTRAST,
2550
2608
  MIN_DELTA_E,
2551
2609
  MIN_HIT_BAND_PX,
2552
2610
  MIN_RAMP_FILLS,
2611
+ OPTIONS_VOCABULARY,
2553
2612
  PAGE_MATCH_TOLERANCE,
2554
2613
  PENDING_RECOVERY_FAST_PHASE_MS,
2555
2614
  PENDING_RECOVERY_FIRST_POLL_MS,
@@ -2732,5 +2791,6 @@ export {
2732
2791
  updateRowHighWater,
2733
2792
  valuePlacementFlag,
2734
2793
  vegaSpecReadsDatesInLocalTime,
2794
+ wireLimitCount,
2735
2795
  withoutViewOnlyKeys
2736
2796
  };
package/dist/react.mjs CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  loadGeo,
8
8
  syncMemberSelection,
9
9
  toSourceRows
10
- } from "./chunk-KONJ3DXV.mjs";
10
+ } from "./chunk-P22NUGCZ.mjs";
11
11
  import "./chunk-A2GMXZP7.mjs";
12
12
  import "./chunk-GHODWOAL.mjs";
13
13
 
@@ -1,5 +1,6 @@
1
1
  export { HOST_CONTRACT_VERSION, GEO_POINT_PRECISIONS, MARK_CLASS, LEGEND_MARK_CLASS, AXIS_FILTER_CLASS, ROW_IDX_ATTR, LIFT_SELECTED_CLASS, CONTROL_CLASS, XFILTER_REFRESH_EVENT, CONTAINER_SLOT_ANIM_STOP, CONTAINER_SLOT_XF_CLEAR, CONTAINER_SLOT_INITIAL_XF_MARK, CONTAINER_SLOT_UI_STATE, VIEW_ONLY_UI_STATE_KEYS, withoutViewOnlyKeys, HOST_CONTAINER_CLASS, SELECTION_ACTIVE_CLASS, MARK_SELECTED_CLASS, ACTIVE_TICK_CLASS, DIM_OPACITY_VAR, DIM_OPACITY_DEFAULT, chartOwnsTimeline, periodTickSuppressesFeedback, ANIM_PLAY_SPEED_DEFAULT, ANIM_PLAY_SPEED_MIN, ANIM_PLAY_SPEED_MAX, ANIM_LOOP_DELAY_DEFAULT, ANIM_LOOP_DELAY_MIN, ANIM_MAX_IDEAL_FRAMES_DEFAULT, ANIM_MAX_IDEAL_FRAMES_MIN, ANIM_MAX_IDEAL_FRAMES_MAX, ANIMATION_OPTION_KEYS, COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT, COLOR_SCALE_SELF_CLAMP_PCT_MIN, COLOR_SCALE_SELF_CLAMP_PCT_MAX, FLIP_MODE_DEFAULT, APPROXIMATE_POSITIONS_DEFAULT, VALUE_AXIS_BASELINE_DEFAULT, SEASONAL_MARKERS_DEFAULT, MAX_MAP_POINTS_DEFAULT, type GeoPointPrecision, type GeoMapKind, type TimelineStyle, type FlipMode, type ApproximatePositions, type ValueAxisBaseline, type SeasonalMarkers, type ColorScaleScope, type RenderOptions, type ViewStateProvider, type ChartControlChange, } from "./contract";
2
2
  export { resolveOptions, type ResolveOptionsInput } from "./defaults";
3
+ export { OPTIONS_VOCABULARY, LIVE_OPTION_KEYS, MAX_MAP_POINTS_MIN, MAX_MAP_POINTS_MAX, LIMIT_COUNT_MAX, wireLimitCount, type OptionVocabularyEntry, type OptionTiming, type OptionWire, type OptionKey, } from "./optionsVocabulary";
3
4
  export { loadGeo, geoFromCache, registerGeo, registerGeoAsset, geoAssetFor, clearGeoCache, type GeoAssetName, } from "./geoLazy";
4
5
  /** REPLACE the bundled city gazetteer with another packed table. Rarely needed — see the
5
6
  * note above registerCityTable in shape-core's geoPoint.ts before using it. */
@@ -0,0 +1,77 @@
1
+ /**
2
+ * When a change to an option takes effect.
3
+ * - `live`: the chart on screen repaints with it; no request, no new chart.
4
+ * - `next-generate`: it steers what the engine makes, so it applies to the next generated chart.
5
+ * - `live-and-next-generate`: both - the chart on screen repaints, and the request carries it too.
6
+ * - `after-render`: it governs what happens after a chart is drawn (a review, a thumbnail).
7
+ */
8
+ export type OptionTiming = "live" | "next-generate" | "live-and-next-generate" | "after-render";
9
+ /** Where an option travels on a generate request: the request itself, or its client hints. */
10
+ export type OptionWire = "request" | "clientHints";
11
+ /** The shared facts about one option. */
12
+ export interface OptionVocabularyEntry {
13
+ readonly timing: OptionTiming;
14
+ /** What "not set" means. A host that stores blank or 0 for "the default" resolves to this. */
15
+ readonly default: string | number | boolean;
16
+ /** The least value a reader may set, for a number. */
17
+ readonly min?: number;
18
+ /** The greatest value a reader may set, for a number. Absent: no upper bound. */
19
+ readonly max?: number;
20
+ /** The values a choice accepts, "" being "leave it to the engine" where offered. */
21
+ readonly values?: readonly string[];
22
+ /** Where it travels on a generate request; absent when it never travels. */
23
+ readonly wire?: OptionWire;
24
+ }
25
+ /** Max Map Points: the fewest and the most points a reader may allow a point map. */
26
+ export declare const MAX_MAP_POINTS_MIN = 10;
27
+ export declare const MAX_MAP_POINTS_MAX = 100000;
28
+ /** Favor Limit Count: the most groups a reader may ask a chart to keep. 0 asks for no limit. */
29
+ export declare const LIMIT_COUNT_MAX = 10000;
30
+ /** The options the hosts share, keyed by wire / render-option name. */
31
+ export declare const OPTIONS_VOCABULARY: Readonly<{
32
+ aggregation: OptionVocabularyEntry;
33
+ colorScaleLow: OptionVocabularyEntry;
34
+ colorScaleHigh: OptionVocabularyEntry;
35
+ /** Blank: the host's own colours when it offers them, else the engine's. */
36
+ palette: OptionVocabularyEntry;
37
+ /** A HARD offer gate on the server as well as a live cap on what a point map plots. */
38
+ maxMapPoints: OptionVocabularyEntry;
39
+ /** 0 means no paging. */
40
+ pageSize: OptionVocabularyEntry;
41
+ valueAxisBaseline: OptionVocabularyEntry;
42
+ seasonalMarkers: OptionVocabularyEntry;
43
+ animAutoPlay: OptionVocabularyEntry;
44
+ animPlaySpeedMs: OptionVocabularyEntry;
45
+ /** 0 restarts at once; no upper bound, so a very large value plays once per viewing. */
46
+ animLoopDelaySec: OptionVocabularyEntry;
47
+ animStopAtEnd: OptionVocabularyEntry;
48
+ animMaxIdealFrames: OptionVocabularyEntry;
49
+ /** "" chooses by the number of periods. */
50
+ animTimelineStyle: OptionVocabularyEntry;
51
+ filtersDuringPlay: OptionVocabularyEntry;
52
+ levelOfDetail: OptionVocabularyEntry;
53
+ favorLimitTo: OptionVocabularyEntry;
54
+ /** 0 asks for no limit, and travels as absent (`wireLimitCount`): any value the server receives is a limit. */
55
+ favorLimitCount: OptionVocabularyEntry;
56
+ /** "1" asks for a title, "0" for none, "" leaves it to the engine. */
57
+ favorTitle: OptionVocabularyEntry;
58
+ /** Data labels on the marks: "1", "0", or "" for the engine's choice. */
59
+ favorDPValues: OptionVocabularyEntry;
60
+ legendPlacement: OptionVocabularyEntry;
61
+ /** Free text: the industry the data belongs to. */
62
+ industryContext: OptionVocabularyEntry;
63
+ /** Free text: a font family for the chart's own text. */
64
+ suggestFontFamily: OptionVocabularyEntry;
65
+ visionReview: OptionVocabularyEntry;
66
+ saveThumbnails: OptionVocabularyEntry;
67
+ }>;
68
+ /** A shared option's key. */
69
+ export type OptionKey = keyof typeof OPTIONS_VOCABULARY;
70
+ /** The keys whose change repaints the chart on screen, in table order. */
71
+ export declare const LIVE_OPTION_KEYS: readonly OptionKey[];
72
+ /**
73
+ * THE LIMIT COUNT A REQUEST CARRIES: a positive count, or null - never 0. The server reads any value it
74
+ * receives as the reader's own limit (and 0 as a limit of zero), so "no limit" must arrive as no value.
75
+ * A host places null where it always has; one that omits blank fields maps it to absent.
76
+ */
77
+ export declare function wireLimitCount(count: unknown): number | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.6.30",
3
+ "version": "0.6.32",
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",