import {
  Accent_default,
  Blues_default,
  BrBG_default,
  BuGn_default,
  BuPu_default,
  Dark2_default,
  Delaunay,
  GnBu_default,
  Greens_default,
  Greys_default,
  InternMap,
  InternSet,
  OrRd_default,
  Oranges_default,
  PRGn_default,
  Paired_default,
  Pastel1_default,
  Pastel2_default,
  PiYG_default,
  PuBuGn_default,
  PuBu_default,
  PuOr_default,
  PuRd_default,
  Purples_default,
  RdBu_default,
  RdGy_default,
  RdPu_default,
  RdYlBu_default,
  RdYlGn_default,
  Reds_default,
  Set1_default,
  Set2_default,
  Set3_default,
  Spectral_default,
  Tableau10_default,
  YlGnBu_default,
  YlGn_default,
  YlOrBr_default,
  YlOrRd_default,
  albersUsa_default,
  albers_default,
  area_default3 as area_default,
  ascending,
  asterisk_default,
  axisBottom,
  axisLeft,
  axisRight,
  axisTop,
  azimuthalEqualArea_default,
  azimuthalEquidistant_default,
  band,
  basisClosed_default2 as basisClosed_default,
  basisOpen_default,
  basis_default2 as basis_default,
  bisect_default,
  blur2,
  blurImage,
  bumpX,
  bumpY,
  bundle_default,
  cardinalClosed_default,
  cardinalOpen_default,
  cardinal_default,
  category10_default,
  catmullRomClosed_default,
  catmullRomOpen_default,
  catmullRom_default,
  centroid_default,
  circle_default3 as circle_default,
  cividis_default,
  clipRectangle,
  cluster_default,
  color,
  conicConformal_default,
  conicEqualArea_default,
  conicEquidistant_default,
  contours_default,
  cool,
  count,
  create_default,
  creator_default,
  cross,
  cross_default,
  cubehelix_default2 as cubehelix_default,
  cumsum,
  density_default,
  descending,
  deviation,
  diamond2_default,
  diamond_default,
  diverging,
  divergingLog,
  divergingPow,
  divergingSymlog,
  equalEarth_default,
  equirectangular_default,
  extent,
  format,
  gnomonic_default,
  graticule10,
  greatest,
  group,
  groupSort,
  hcl_default,
  hsl_default,
  identity,
  implicit,
  inferno,
  lab2 as lab,
  lcg,
  least,
  line_default,
  linear2 as linear,
  linearClosed_default,
  linear_default,
  log,
  magma,
  map,
  max,
  maxIndex,
  mean,
  median,
  mercator_default,
  min,
  minIndex,
  mode,
  monotoneX,
  monotoneY,
  namespaces_default,
  natural_default,
  nice,
  number_default,
  ordinal,
  orthographic_default,
  pairs,
  pathRound,
  path_default,
  piecewise,
  plasma,
  plus_default,
  point,
  pow,
  quantile,
  quantile2,
  quantize_default,
  rainbow_default,
  range,
  rank,
  reverse,
  rgb,
  rgb_default,
  rollup,
  round_default,
  scheme,
  scheme10,
  scheme11,
  scheme12,
  scheme13,
  scheme14,
  scheme15,
  scheme16,
  scheme17,
  scheme18,
  scheme19,
  scheme2,
  scheme20,
  scheme21,
  scheme22,
  scheme23,
  scheme24,
  scheme25,
  scheme26,
  scheme27,
  scheme3,
  scheme4,
  scheme5,
  scheme6,
  scheme7,
  scheme8,
  scheme9,
  second,
  select_default,
  sinebow_default,
  sort,
  square2_default,
  square_default,
  star_default,
  stepAfter,
  stepBefore,
  step_default,
  stereographic_default,
  stratify_default,
  sum,
  symbolsFill,
  symbolsStroke,
  symlog,
  threshold,
  thresholdFreedmanDiaconis,
  thresholdScott,
  thresholdSturges,
  tickIncrement,
  ticks,
  time,
  timeDay,
  timeFriday,
  timeHour,
  timeMinute,
  timeMonday,
  timeMonth,
  timeSaturday,
  timeSunday,
  timeThursday,
  timeTuesday,
  timeWednesday,
  timeYear,
  times_default,
  transform_default,
  transverseMercator_default,
  tree_default,
  triangle2_default,
  triangle_default,
  turbo_default,
  utcDay,
  utcFormat,
  utcFriday,
  utcHour,
  utcMinute,
  utcMonday,
  utcMonth,
  utcSaturday,
  utcSunday,
  utcThursday,
  utcTickInterval,
  utcTime,
  utcTuesday,
  utcWednesday,
  utcYear,
  variance,
  viridis_default,
  warm,
  wye_default
} from "./chunk-P2HMSBME.js";
import {
  format as format2,
  parse
} from "./chunk-5V6XIMG2.js";
import {
  __commonJS,
  __toESM
} from "./chunk-4EOJPDL2.js";

// ../../node_modules/binary-search-bounds/search-bounds.js
var require_search_bounds = __commonJS({
  "../../node_modules/binary-search-bounds/search-bounds.js"(exports, module) {
    "use strict";
    function ge(a, y, c, l, h) {
      var i = h + 1;
      while (l <= h) {
        var m = l + h >>> 1, x = a[m];
        var p = c !== void 0 ? c(x, y) : x - y;
        if (p >= 0) {
          i = m;
          h = m - 1;
        } else {
          l = m + 1;
        }
      }
      return i;
    }
    function gt(a, y, c, l, h) {
      var i = h + 1;
      while (l <= h) {
        var m = l + h >>> 1, x = a[m];
        var p = c !== void 0 ? c(x, y) : x - y;
        if (p > 0) {
          i = m;
          h = m - 1;
        } else {
          l = m + 1;
        }
      }
      return i;
    }
    function lt(a, y, c, l, h) {
      var i = l - 1;
      while (l <= h) {
        var m = l + h >>> 1, x = a[m];
        var p = c !== void 0 ? c(x, y) : x - y;
        if (p < 0) {
          i = m;
          l = m + 1;
        } else {
          h = m - 1;
        }
      }
      return i;
    }
    function le(a, y, c, l, h) {
      var i = l - 1;
      while (l <= h) {
        var m = l + h >>> 1, x = a[m];
        var p = c !== void 0 ? c(x, y) : x - y;
        if (p <= 0) {
          i = m;
          l = m + 1;
        } else {
          h = m - 1;
        }
      }
      return i;
    }
    function eq(a, y, c, l, h) {
      while (l <= h) {
        var m = l + h >>> 1, x = a[m];
        var p = c !== void 0 ? c(x, y) : x - y;
        if (p === 0) {
          return m;
        }
        if (p <= 0) {
          l = m + 1;
        } else {
          h = m - 1;
        }
      }
      return -1;
    }
    function norm(a, y, c, l, h, f) {
      if (typeof c === "function") {
        return f(a, y, c, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0);
      }
      return f(a, y, void 0, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0);
    }
    module.exports = {
      ge: function(a, y, c, l, h) {
        return norm(a, y, c, l, h, ge);
      },
      gt: function(a, y, c, l, h) {
        return norm(a, y, c, l, h, gt);
      },
      lt: function(a, y, c, l, h) {
        return norm(a, y, c, l, h, lt);
      },
      le: function(a, y, c, l, h) {
        return norm(a, y, c, l, h, le);
      },
      eq: function(a, y, c, l, h) {
        return norm(a, y, c, l, h, eq);
      }
    };
  }
});

// ../../node_modules/interval-tree-1d/interval-tree.js
var require_interval_tree = __commonJS({
  "../../node_modules/interval-tree-1d/interval-tree.js"(exports, module) {
    "use strict";
    var bounds = require_search_bounds();
    var NOT_FOUND = 0;
    var SUCCESS = 1;
    var EMPTY = 2;
    module.exports = createWrapper;
    function IntervalTreeNode(mid3, left, right, leftPoints, rightPoints) {
      this.mid = mid3;
      this.left = left;
      this.right = right;
      this.leftPoints = leftPoints;
      this.rightPoints = rightPoints;
      this.count = (left ? left.count : 0) + (right ? right.count : 0) + leftPoints.length;
    }
    var proto = IntervalTreeNode.prototype;
    function copy(a, b) {
      a.mid = b.mid;
      a.left = b.left;
      a.right = b.right;
      a.leftPoints = b.leftPoints;
      a.rightPoints = b.rightPoints;
      a.count = b.count;
    }
    function rebuild(node, intervals) {
      var ntree = createIntervalTree(intervals);
      node.mid = ntree.mid;
      node.left = ntree.left;
      node.right = ntree.right;
      node.leftPoints = ntree.leftPoints;
      node.rightPoints = ntree.rightPoints;
      node.count = ntree.count;
    }
    function rebuildWithInterval(node, interval) {
      var intervals = node.intervals([]);
      intervals.push(interval);
      rebuild(node, intervals);
    }
    function rebuildWithoutInterval(node, interval) {
      var intervals = node.intervals([]);
      var idx = intervals.indexOf(interval);
      if (idx < 0) {
        return NOT_FOUND;
      }
      intervals.splice(idx, 1);
      rebuild(node, intervals);
      return SUCCESS;
    }
    proto.intervals = function(result) {
      result.push.apply(result, this.leftPoints);
      if (this.left) {
        this.left.intervals(result);
      }
      if (this.right) {
        this.right.intervals(result);
      }
      return result;
    };
    proto.insert = function(interval) {
      var weight = this.count - this.leftPoints.length;
      this.count += 1;
      if (interval[1] < this.mid) {
        if (this.left) {
          if (4 * (this.left.count + 1) > 3 * (weight + 1)) {
            rebuildWithInterval(this, interval);
          } else {
            this.left.insert(interval);
          }
        } else {
          this.left = createIntervalTree([interval]);
        }
      } else if (interval[0] > this.mid) {
        if (this.right) {
          if (4 * (this.right.count + 1) > 3 * (weight + 1)) {
            rebuildWithInterval(this, interval);
          } else {
            this.right.insert(interval);
          }
        } else {
          this.right = createIntervalTree([interval]);
        }
      } else {
        var l = bounds.ge(this.leftPoints, interval, compareBegin);
        var r = bounds.ge(this.rightPoints, interval, compareEnd);
        this.leftPoints.splice(l, 0, interval);
        this.rightPoints.splice(r, 0, interval);
      }
    };
    proto.remove = function(interval) {
      var weight = this.count - this.leftPoints;
      if (interval[1] < this.mid) {
        if (!this.left) {
          return NOT_FOUND;
        }
        var rw = this.right ? this.right.count : 0;
        if (4 * rw > 3 * (weight - 1)) {
          return rebuildWithoutInterval(this, interval);
        }
        var r = this.left.remove(interval);
        if (r === EMPTY) {
          this.left = null;
          this.count -= 1;
          return SUCCESS;
        } else if (r === SUCCESS) {
          this.count -= 1;
        }
        return r;
      } else if (interval[0] > this.mid) {
        if (!this.right) {
          return NOT_FOUND;
        }
        var lw = this.left ? this.left.count : 0;
        if (4 * lw > 3 * (weight - 1)) {
          return rebuildWithoutInterval(this, interval);
        }
        var r = this.right.remove(interval);
        if (r === EMPTY) {
          this.right = null;
          this.count -= 1;
          return SUCCESS;
        } else if (r === SUCCESS) {
          this.count -= 1;
        }
        return r;
      } else {
        if (this.count === 1) {
          if (this.leftPoints[0] === interval) {
            return EMPTY;
          } else {
            return NOT_FOUND;
          }
        }
        if (this.leftPoints.length === 1 && this.leftPoints[0] === interval) {
          if (this.left && this.right) {
            var p = this;
            var n = this.left;
            while (n.right) {
              p = n;
              n = n.right;
            }
            if (p === this) {
              n.right = this.right;
            } else {
              var l = this.left;
              var r = this.right;
              p.count -= n.count;
              p.right = n.left;
              n.left = l;
              n.right = r;
            }
            copy(this, n);
            this.count = (this.left ? this.left.count : 0) + (this.right ? this.right.count : 0) + this.leftPoints.length;
          } else if (this.left) {
            copy(this, this.left);
          } else {
            copy(this, this.right);
          }
          return SUCCESS;
        }
        for (var l = bounds.ge(this.leftPoints, interval, compareBegin); l < this.leftPoints.length; ++l) {
          if (this.leftPoints[l][0] !== interval[0]) {
            break;
          }
          if (this.leftPoints[l] === interval) {
            this.count -= 1;
            this.leftPoints.splice(l, 1);
            for (var r = bounds.ge(this.rightPoints, interval, compareEnd); r < this.rightPoints.length; ++r) {
              if (this.rightPoints[r][1] !== interval[1]) {
                break;
              } else if (this.rightPoints[r] === interval) {
                this.rightPoints.splice(r, 1);
                return SUCCESS;
              }
            }
          }
        }
        return NOT_FOUND;
      }
    };
    function reportLeftRange(arr, hi, cb) {
      for (var i = 0; i < arr.length && arr[i][0] <= hi; ++i) {
        var r = cb(arr[i]);
        if (r) {
          return r;
        }
      }
    }
    function reportRightRange(arr, lo, cb) {
      for (var i = arr.length - 1; i >= 0 && arr[i][1] >= lo; --i) {
        var r = cb(arr[i]);
        if (r) {
          return r;
        }
      }
    }
    function reportRange(arr, cb) {
      for (var i = 0; i < arr.length; ++i) {
        var r = cb(arr[i]);
        if (r) {
          return r;
        }
      }
    }
    proto.queryPoint = function(x, cb) {
      if (x < this.mid) {
        if (this.left) {
          var r = this.left.queryPoint(x, cb);
          if (r) {
            return r;
          }
        }
        return reportLeftRange(this.leftPoints, x, cb);
      } else if (x > this.mid) {
        if (this.right) {
          var r = this.right.queryPoint(x, cb);
          if (r) {
            return r;
          }
        }
        return reportRightRange(this.rightPoints, x, cb);
      } else {
        return reportRange(this.leftPoints, cb);
      }
    };
    proto.queryInterval = function(lo, hi, cb) {
      if (lo < this.mid && this.left) {
        var r = this.left.queryInterval(lo, hi, cb);
        if (r) {
          return r;
        }
      }
      if (hi > this.mid && this.right) {
        var r = this.right.queryInterval(lo, hi, cb);
        if (r) {
          return r;
        }
      }
      if (hi < this.mid) {
        return reportLeftRange(this.leftPoints, hi, cb);
      } else if (lo > this.mid) {
        return reportRightRange(this.rightPoints, lo, cb);
      } else {
        return reportRange(this.leftPoints, cb);
      }
    };
    function compareNumbers(a, b) {
      return a - b;
    }
    function compareBegin(a, b) {
      var d = a[0] - b[0];
      if (d) {
        return d;
      }
      return a[1] - b[1];
    }
    function compareEnd(a, b) {
      var d = a[1] - b[1];
      if (d) {
        return d;
      }
      return a[0] - b[0];
    }
    function createIntervalTree(intervals) {
      if (intervals.length === 0) {
        return null;
      }
      var pts = [];
      for (var i = 0; i < intervals.length; ++i) {
        pts.push(intervals[i][0], intervals[i][1]);
      }
      pts.sort(compareNumbers);
      var mid3 = pts[pts.length >> 1];
      var leftIntervals = [];
      var rightIntervals = [];
      var centerIntervals = [];
      for (var i = 0; i < intervals.length; ++i) {
        var s = intervals[i];
        if (s[1] < mid3) {
          leftIntervals.push(s);
        } else if (mid3 < s[0]) {
          rightIntervals.push(s);
        } else {
          centerIntervals.push(s);
        }
      }
      var leftPoints = centerIntervals;
      var rightPoints = centerIntervals.slice();
      leftPoints.sort(compareBegin);
      rightPoints.sort(compareEnd);
      return new IntervalTreeNode(
        mid3,
        createIntervalTree(leftIntervals),
        createIntervalTree(rightIntervals),
        leftPoints,
        rightPoints
      );
    }
    function IntervalTree2(root) {
      this.root = root;
    }
    var tproto = IntervalTree2.prototype;
    tproto.insert = function(interval) {
      if (this.root) {
        this.root.insert(interval);
      } else {
        this.root = new IntervalTreeNode(interval[0], null, null, [interval], [interval]);
      }
    };
    tproto.remove = function(interval) {
      if (this.root) {
        var r = this.root.remove(interval);
        if (r === EMPTY) {
          this.root = null;
        }
        return r !== NOT_FOUND;
      }
      return false;
    };
    tproto.queryPoint = function(p, cb) {
      if (this.root) {
        return this.root.queryPoint(p, cb);
      }
    };
    tproto.queryInterval = function(lo, hi, cb) {
      if (lo <= hi && this.root) {
        return this.root.queryInterval(lo, hi, cb);
      }
    };
    Object.defineProperty(tproto, "count", {
      get: function() {
        if (this.root) {
          return this.root.count;
        }
        return 0;
      }
    });
    Object.defineProperty(tproto, "intervals", {
      get: function() {
        if (this.root) {
          return this.root.intervals([]);
        }
        return [];
      }
    });
    function createWrapper(intervals) {
      if (!intervals || intervals.length === 0) {
        return new IntervalTree2(null);
      }
      return new IntervalTree2(createIntervalTree(intervals));
    }
  }
});

// ../../node_modules/@observablehq/plot/dist/time.js
var timeIntervals = /* @__PURE__ */ new Map([
  ["second", second],
  ["minute", timeMinute],
  ["hour", timeHour],
  ["day", timeDay],
  ["week", timeSunday],
  ["month", timeMonth],
  ["year", timeYear],
  ["monday", timeMonday],
  ["tuesday", timeTuesday],
  ["wednesday", timeWednesday],
  ["thursday", timeThursday],
  ["friday", timeFriday],
  ["saturday", timeSaturday],
  ["sunday", timeSunday]
]);
var utcIntervals = /* @__PURE__ */ new Map([
  ["second", second],
  ["minute", utcMinute],
  ["hour", utcHour],
  ["day", utcDay],
  ["week", utcSunday],
  ["month", utcMonth],
  ["year", utcYear],
  ["monday", utcMonday],
  ["tuesday", utcTuesday],
  ["wednesday", utcWednesday],
  ["thursday", utcThursday],
  ["friday", utcFriday],
  ["saturday", utcSaturday],
  ["sunday", utcSunday]
]);
function maybeTimeInterval(interval) {
  const i = timeIntervals.get(`${interval}`.toLowerCase());
  if (!i)
    throw new Error(`unknown interval: ${interval}`);
  return i;
}
function maybeUtcInterval(interval) {
  const i = utcIntervals.get(`${interval}`.toLowerCase());
  if (!i)
    throw new Error(`unknown interval: ${interval}`);
  return i;
}

// ../../node_modules/@observablehq/plot/dist/options.js
var TypedArray = Object.getPrototypeOf(Uint8Array);
var objectToString = Object.prototype.toString;
function valueof(data, value, type) {
  const valueType = typeof value;
  return valueType === "string" ? map2(data, field(value), type) : valueType === "function" ? map2(data, value, type) : valueType === "number" || value instanceof Date || valueType === "boolean" ? map2(data, constant(value), type) : value && typeof value.transform === "function" ? arrayify(value.transform(data), type) : arrayify(value, type);
}
var field = (name) => (d) => d[name];
var indexOf = (d, i) => i;
var identity2 = { transform: (d) => d };
var one = () => 1;
var yes = () => true;
var string = (x) => x == null ? x : `${x}`;
var number = (x) => x == null ? x : +x;
var boolean = (x) => x == null ? x : !!x;
var first = (x) => x ? x[0] : void 0;
var second2 = (x) => x ? x[1] : void 0;
var third = (x) => x ? x[2] : void 0;
var constant = (x) => () => x;
function percentile(reduce) {
  const p = +`${reduce}`.slice(1) / 100;
  return (I, f) => quantile(I, p, f);
}
function maybeColorChannel(value, defaultValue) {
  if (value === void 0)
    value = defaultValue;
  return value === null ? [void 0, "none"] : isColor(value) ? [void 0, value] : [value, void 0];
}
function maybeNumberChannel(value, defaultValue) {
  if (value === void 0)
    value = defaultValue;
  return value === null || typeof value === "number" ? [void 0, value] : [value, void 0];
}
function maybeKeyword(input, name, allowed) {
  if (input != null)
    return keyword(input, name, allowed);
}
function keyword(input, name, allowed) {
  const i = `${input}`.toLowerCase();
  if (!allowed.includes(i))
    throw new Error(`invalid ${name}: ${input}`);
  return i;
}
function arrayify(data, type) {
  return data == null ? data : type === void 0 ? data instanceof Array || data instanceof TypedArray ? data : Array.from(data) : data instanceof type ? data : type.from(data);
}
function map2(values2, f, type = Array) {
  return values2 instanceof type ? values2.map(f) : type.from(values2, f);
}
function slice(values2, type = Array) {
  return values2 instanceof type ? values2.slice() : type.from(values2);
}
function isTypedArray(values2) {
  return values2 instanceof TypedArray;
}
function isObject(option) {
  return (option == null ? void 0 : option.toString) === objectToString;
}
function isScaleOptions(option) {
  return isObject(option) && (option.type !== void 0 || option.domain !== void 0);
}
function isOptions(option) {
  return isObject(option) && typeof option.transform !== "function";
}
function isDomainSort(sort3) {
  return isOptions(sort3) && sort3.value === void 0 && sort3.channel === void 0;
}
function maybeZero(x, x1, x2, x3 = identity2) {
  if (x1 === void 0 && x2 === void 0) {
    x1 = 0, x2 = x === void 0 ? x3 : x;
  } else if (x1 === void 0) {
    x1 = x === void 0 ? 0 : x;
  } else if (x2 === void 0) {
    x2 = x === void 0 ? 0 : x;
  }
  return [x1, x2];
}
function maybeTuple(x, y) {
  return x === void 0 && y === void 0 ? [first, second2] : [x, y];
}
function maybeZ({ z, fill, stroke } = {}) {
  if (z === void 0)
    [z] = maybeColorChannel(fill);
  if (z === void 0)
    [z] = maybeColorChannel(stroke);
  return z;
}
function range2(data) {
  const n = data.length;
  const r = new Uint32Array(n);
  for (let i = 0; i < n; ++i)
    r[i] = i;
  return r;
}
function where(data, test) {
  return range2(data).filter((i) => test(data[i], i, data));
}
function take(values2, index) {
  return map2(index, (i) => values2[i]);
}
function keyof(value) {
  return value !== null && typeof value === "object" ? value.valueOf() : value;
}
function maybeInput(key, options) {
  if (options[key] !== void 0)
    return options[key];
  switch (key) {
    case "x1":
    case "x2":
      key = "x";
      break;
    case "y1":
    case "y2":
      key = "y";
      break;
  }
  return options[key];
}
function column(source) {
  let value;
  return [
    {
      transform: () => value,
      label: labelof(source)
    },
    (v) => value = v
  ];
}
function maybeColumn(source) {
  return source == null ? [source] : column(source);
}
function labelof(value, defaultValue) {
  return typeof value === "string" ? value : value && value.label !== void 0 ? value.label : defaultValue;
}
function mid(x1, x2) {
  return {
    transform(data) {
      const X1 = x1.transform(data);
      const X2 = x2.transform(data);
      return isTemporal(X1) || isTemporal(X2) ? map2(X1, (_, i) => new Date((+X1[i] + +X2[i]) / 2)) : map2(X1, (_, i) => (+X1[i] + +X2[i]) / 2, Float64Array);
    },
    label: x1.label
  };
}
function maybeInterval(interval) {
  if (interval == null)
    return;
  if (typeof interval === "number") {
    const n = interval;
    return {
      floor: (d) => n * Math.floor(d / n),
      offset: (d) => d + n,
      range: (lo, hi) => range(Math.ceil(lo / n), hi / n).map((x) => n * x)
    };
  }
  if (typeof interval === "string")
    return maybeUtcInterval(interval);
  if (typeof interval.floor !== "function")
    throw new Error("invalid interval; missing floor method");
  if (typeof interval.offset !== "function")
    throw new Error("invalid interval; missing offset method");
  return interval;
}
function maybeValue(value) {
  return value === void 0 || isOptions(value) ? value : { value };
}
function numberChannel(source) {
  return source == null ? null : {
    transform: (data) => valueof(data, source, Float64Array),
    label: labelof(source)
  };
}
function isTuples(data) {
  if (!isIterable(data))
    return false;
  for (const d of data) {
    if (d == null)
      continue;
    return typeof d === "object" && "0" in d && "1" in d;
  }
}
function isIterable(value) {
  return value && typeof value[Symbol.iterator] === "function";
}
function isTextual(values2) {
  for (const value of values2) {
    if (value == null)
      continue;
    return typeof value !== "object" || value instanceof Date;
  }
}
function isOrdinal(values2) {
  for (const value of values2) {
    if (value == null)
      continue;
    const type = typeof value;
    return type === "string" || type === "boolean";
  }
}
function isTemporal(values2) {
  for (const value of values2) {
    if (value == null)
      continue;
    return value instanceof Date;
  }
}
function isTemporalString(values2) {
  for (const value of values2) {
    if (value == null)
      continue;
    return typeof value === "string" && isNaN(value) && parse(value);
  }
}
function isNumericString(values2) {
  for (const value of values2) {
    if (value == null)
      continue;
    if (typeof value !== "string")
      return false;
    if (!value.trim())
      continue;
    return !isNaN(value);
  }
}
function isNumeric(values2) {
  for (const value of values2) {
    if (value == null)
      continue;
    return typeof value === "number";
  }
}
function isFirst(values2, is) {
  for (const value of values2) {
    if (value == null)
      continue;
    return is(value);
  }
}
function isEvery(values2, is) {
  for (const value of values2) {
    if (value == null)
      continue;
    if (!is(value))
      return false;
  }
  return true;
}
function isColor(value) {
  if (typeof value !== "string")
    return false;
  value = value.toLowerCase().trim();
  return value === "none" || value === "currentcolor" || value.startsWith("url(") && value.endsWith(")") || // <funciri>, e.g. pattern or gradient
  value.startsWith("var(") && value.endsWith(")") || // CSS variable
  color(value) !== null;
}
function isNoneish(value) {
  return value == null || isNone(value);
}
function isNone(value) {
  return /^\s*none\s*$/i.test(value);
}
function isRound(value) {
  return /^\s*round\s*$/i.test(value);
}
function maybeFrameAnchor(value = "middle") {
  return keyword(value, "frameAnchor", [
    "middle",
    "top-left",
    "top",
    "top-right",
    "right",
    "bottom-right",
    "bottom",
    "bottom-left",
    "left"
  ]);
}
function order(values2) {
  if (values2 == null)
    return;
  const first2 = values2[0];
  const last = values2[values2.length - 1];
  return descending(first2, last);
}
function inherit(options = {}, ...rest) {
  let o = options;
  for (const defaults21 of rest) {
    for (const key in defaults21) {
      if (o[key] === void 0) {
        const value = defaults21[key];
        if (o === options)
          o = { ...o, [key]: value };
        else
          o[key] = value;
      }
    }
  }
  return o;
}
function Named(things) {
  console.warn("named iterables are deprecated; please use an object instead");
  const names = /* @__PURE__ */ new Set();
  return Object.fromEntries(Array.from(things, (thing) => {
    const { name } = thing;
    if (name == null)
      throw new Error("missing name");
    const key = `${name}`;
    if (key === "__proto__")
      throw new Error(`illegal name: ${key}`);
    if (names.has(key))
      throw new Error(`duplicate name: ${key}`);
    names.add(key);
    return [name, thing];
  }));
}
function maybeNamed(things) {
  return isIterable(things) ? Named(things) : things;
}

// ../../node_modules/@observablehq/plot/dist/scales/index.js
var position = Symbol("position");
var color2 = Symbol("color");
var radius = Symbol("radius");
var length = Symbol("length");
var opacity = Symbol("opacity");
var symbol = Symbol("symbol");
var registry = /* @__PURE__ */ new Map([
  ["x", position],
  ["y", position],
  ["fx", position],
  ["fy", position],
  ["r", radius],
  ["color", color2],
  ["opacity", opacity],
  ["symbol", symbol],
  ["length", length]
]);

// ../../node_modules/@observablehq/plot/dist/defined.js
function defined(x) {
  return x != null && !Number.isNaN(x);
}
function ascendingDefined(a, b) {
  return +defined(b) - +defined(a) || ascending(a, b);
}
function descendingDefined(a, b) {
  return +defined(b) - +defined(a) || descending(a, b);
}
function nonempty(x) {
  return x != null && `${x}` !== "";
}
function finite(x) {
  return isFinite(x) ? x : NaN;
}
function positive(x) {
  return x > 0 && isFinite(x) ? x : NaN;
}
function negative(x) {
  return x < 0 && isFinite(x) ? x : NaN;
}

// ../../node_modules/@observablehq/plot/dist/transforms/basic.js
function basic(options = {}, transform) {
  let { filter: f1, sort: s1, reverse: r1, transform: t1, initializer: i1, ...remainingOptions } = options;
  if (t1 === void 0) {
    if (f1 != null)
      t1 = filterTransform(f1);
    if (s1 != null && !isDomainSort(s1))
      t1 = composeTransform(t1, sortTransform(s1));
    if (r1)
      t1 = composeTransform(t1, reverseTransform);
  }
  if (transform != null && i1 != null)
    throw new Error("transforms cannot be applied after initializers");
  return {
    ...remainingOptions,
    ...(s1 === null || isDomainSort(s1)) && { sort: s1 },
    transform: composeTransform(t1, transform)
  };
}
function initializer(options = {}, initializer2) {
  let { filter: f1, sort: s1, reverse: r1, initializer: i1, ...remainingOptions } = options;
  if (i1 === void 0) {
    if (f1 != null)
      i1 = filterTransform(f1);
    if (s1 != null && !isDomainSort(s1))
      i1 = composeInitializer(i1, sortTransform(s1));
    if (r1)
      i1 = composeInitializer(i1, reverseTransform);
  }
  return {
    ...remainingOptions,
    ...(s1 === null || isDomainSort(s1)) && { sort: s1 },
    initializer: composeInitializer(i1, initializer2)
  };
}
function composeTransform(t1, t2) {
  if (t1 == null)
    return t2 === null ? void 0 : t2;
  if (t2 == null)
    return t1 === null ? void 0 : t1;
  return function(data, facets) {
    ({ data, facets } = t1.call(this, data, facets));
    return t2.call(this, arrayify(data), facets);
  };
}
function composeInitializer(i1, i2) {
  if (i1 == null)
    return i2 === null ? void 0 : i2;
  if (i2 == null)
    return i1 === null ? void 0 : i1;
  return function(data, facets, channels, ...args) {
    let c1, d1, f1, c2, d2, f2;
    ({ data: d1 = data, facets: f1 = facets, channels: c1 } = i1.call(this, data, facets, channels, ...args));
    ({ data: d2 = d1, facets: f2 = f1, channels: c2 } = i2.call(this, d1, f1, { ...channels, ...c1 }, ...args));
    return { data: d2, facets: f2, channels: { ...c1, ...c2 } };
  };
}
function apply(options, t) {
  return (options.initializer != null ? initializer : basic)(options, t);
}
function filter(test, options) {
  return apply(options, filterTransform(test));
}
function filterTransform(value) {
  return (data, facets) => {
    const V = valueof(data, value);
    return { data, facets: facets.map((I) => I.filter((i) => V[i])) };
  };
}
function reverse2(options) {
  return { ...apply(options, reverseTransform), sort: null };
}
function reverseTransform(data, facets) {
  return { data, facets: facets.map((I) => I.slice().reverse()) };
}
function shuffle(options = {}) {
  const { seed, ...remainingOptions } = options;
  return { ...apply(remainingOptions, sortValue(seed == null ? Math.random : lcg(seed))), sort: null };
}
function sort2(order2, options) {
  return {
    ...(isOptions(order2) && order2.channel !== void 0 ? initializer : apply)(options, sortTransform(order2)),
    sort: null
  };
}
function sortTransform(value) {
  return (typeof value === "function" && value.length !== 1 ? sortData : sortValue)(value);
}
function sortData(compare) {
  return (data, facets) => {
    const compareData = (i, j) => compare(data[i], data[j]);
    return { data, facets: facets.map((I) => I.slice().sort(compareData)) };
  };
}
function sortValue(value) {
  let channel, order2;
  ({ channel, value, order: order2 = ascendingDefined } = { ...maybeValue(value) });
  if (typeof order2 !== "function") {
    switch (`${order2}`.toLowerCase()) {
      case "ascending":
        order2 = ascendingDefined;
        break;
      case "descending":
        order2 = descendingDefined;
        break;
      default:
        throw new Error(`invalid order: ${order2}`);
    }
  }
  return (data, facets, channels) => {
    let V;
    if (channel === void 0) {
      V = valueof(data, value);
    } else {
      if (channels === void 0)
        throw new Error("channel sort requires an initializer");
      V = channels[channel];
      if (!V)
        return {};
      V = V.value;
    }
    const compareValue = (i, j) => order2(V[i], V[j]);
    return { data, facets: facets.map((I) => I.slice().sort(compareValue)) };
  };
}

// ../../node_modules/@observablehq/plot/dist/transforms/group.js
function groupZ(outputs, options) {
  return groupn(null, null, outputs, options);
}
function groupX(outputs = { y: "count" }, options = {}) {
  const { x = identity2 } = options;
  if (x == null)
    throw new Error("missing channel: x");
  return groupn(x, null, outputs, options);
}
function groupY(outputs = { x: "count" }, options = {}) {
  const { y = identity2 } = options;
  if (y == null)
    throw new Error("missing channel: y");
  return groupn(null, y, outputs, options);
}
function group2(outputs = { fill: "count" }, options = {}) {
  let { x, y } = options;
  [x, y] = maybeTuple(x, y);
  if (x == null)
    throw new Error("missing channel: x");
  if (y == null)
    throw new Error("missing channel: y");
  return groupn(x, y, outputs, options);
}
function groupn(x, y, {
  data: reduceData = reduceIdentity,
  filter: filter2,
  sort: sort3,
  reverse: reverse3,
  ...outputs
  // output channel definitions
} = {}, inputs = {}) {
  outputs = maybeOutputs(outputs, inputs);
  reduceData = maybeReduce(reduceData, identity2);
  sort3 = sort3 == null ? void 0 : maybeOutput("sort", sort3, inputs);
  filter2 = filter2 == null ? void 0 : maybeEvaluator("filter", filter2, inputs);
  const [GX, setGX] = maybeColumn(x);
  const [GY, setGY] = maybeColumn(y);
  const {
    z,
    fill,
    stroke,
    x1,
    x2,
    // consumed if x is an output
    y1,
    y2,
    // consumed if y is an output
    ...options
  } = inputs;
  const [GZ, setGZ] = maybeColumn(z);
  const [vfill] = maybeColorChannel(fill);
  const [vstroke] = maybeColorChannel(stroke);
  const [GF, setGF] = maybeColumn(vfill);
  const [GS, setGS] = maybeColumn(vstroke);
  return {
    ..."z" in inputs && { z: GZ || z },
    ..."fill" in inputs && { fill: GF || fill },
    ..."stroke" in inputs && { stroke: GS || stroke },
    ...basic(options, (data, facets) => {
      const X = valueof(data, x);
      const Y = valueof(data, y);
      const Z = valueof(data, z);
      const F = valueof(data, vfill);
      const S = valueof(data, vstroke);
      const G = maybeSubgroup(outputs, { z: Z, fill: F, stroke: S });
      const groupFacets = [];
      const groupData = [];
      const GX2 = X && setGX([]);
      const GY2 = Y && setGY([]);
      const GZ2 = Z && setGZ([]);
      const GF2 = F && setGF([]);
      const GS2 = S && setGS([]);
      let i = 0;
      for (const o of outputs)
        o.initialize(data);
      if (sort3)
        sort3.initialize(data);
      if (filter2)
        filter2.initialize(data);
      for (const facet of facets) {
        const groupFacet = [];
        for (const o of outputs)
          o.scope("facet", facet);
        if (sort3)
          sort3.scope("facet", facet);
        if (filter2)
          filter2.scope("facet", facet);
        for (const [f, I] of maybeGroup(facet, G)) {
          for (const [y3, gg] of maybeGroup(I, Y)) {
            for (const [x3, g] of maybeGroup(gg, X)) {
              if (filter2 && !filter2.reduce(g))
                continue;
              groupFacet.push(i++);
              groupData.push(reduceData.reduce(g, data));
              if (X)
                GX2.push(x3);
              if (Y)
                GY2.push(y3);
              if (Z)
                GZ2.push(G === Z ? f : Z[g[0]]);
              if (F)
                GF2.push(G === F ? f : F[g[0]]);
              if (S)
                GS2.push(G === S ? f : S[g[0]]);
              for (const o of outputs)
                o.reduce(g);
              if (sort3)
                sort3.reduce(g);
            }
          }
        }
        groupFacets.push(groupFacet);
      }
      maybeSort(groupFacets, sort3, reverse3);
      return { data: groupData, facets: groupFacets };
    }),
    ...!hasOutput(outputs, "x") && (GX ? { x: GX } : { x1, x2 }),
    ...!hasOutput(outputs, "y") && (GY ? { y: GY } : { y1, y2 }),
    ...Object.fromEntries(outputs.map(({ name, output }) => [name, output]))
  };
}
function hasOutput(outputs, ...names) {
  for (const { name } of outputs) {
    if (names.includes(name)) {
      return true;
    }
  }
  return false;
}
function maybeOutputs(outputs, inputs) {
  const entries = Object.entries(outputs);
  if (inputs.title != null && outputs.title === void 0)
    entries.push(["title", reduceTitle]);
  if (inputs.href != null && outputs.href === void 0)
    entries.push(["href", reduceFirst]);
  return entries.filter(([, reduce]) => reduce !== void 0).map(([name, reduce]) => {
    return reduce === null ? { name, initialize() {
    }, scope() {
    }, reduce() {
    } } : maybeOutput(name, reduce, inputs);
  });
}
function maybeOutput(name, reduce, inputs) {
  const evaluator = maybeEvaluator(name, reduce, inputs);
  const [output, setOutput] = column(evaluator.label);
  let O;
  return {
    name,
    output,
    initialize(data) {
      evaluator.initialize(data);
      O = setOutput([]);
    },
    scope(scope, I) {
      evaluator.scope(scope, I);
    },
    reduce(I, extent3) {
      O.push(evaluator.reduce(I, extent3));
    }
  };
}
function maybeEvaluator(name, reduce, inputs) {
  const input = maybeInput(name, inputs);
  const reducer = maybeReduce(reduce, input);
  let V, context;
  return {
    label: labelof(reducer === reduceCount ? null : input, reducer.label),
    initialize(data) {
      V = input === void 0 ? data : valueof(data, input);
      if (reducer.scope === "data") {
        context = reducer.reduce(range2(data), V);
      }
    },
    scope(scope, I) {
      if (reducer.scope === scope) {
        context = reducer.reduce(I, V);
      }
    },
    reduce(I, extent3) {
      return reducer.scope == null ? reducer.reduce(I, V, extent3) : reducer.reduce(I, V, context, extent3);
    }
  };
}
function maybeGroup(I, X) {
  return X ? sort(group(I, (i) => X[i]), first) : [[, I]];
}
function maybeReduce(reduce, value) {
  if (reduce && typeof reduce.reduce === "function")
    return reduce;
  if (typeof reduce === "function")
    return reduceFunction(reduce);
  if (/^p\d{2}$/i.test(reduce))
    return reduceAccessor(percentile(reduce));
  switch (`${reduce}`.toLowerCase()) {
    case "first":
      return reduceFirst;
    case "last":
      return reduceLast;
    case "count":
      return reduceCount;
    case "distinct":
      return reduceDistinct;
    case "sum":
      return value == null ? reduceCount : reduceSum;
    case "proportion":
      return reduceProportion(value, "data");
    case "proportion-facet":
      return reduceProportion(value, "facet");
    case "deviation":
      return reduceAccessor(deviation);
    case "min":
      return reduceAccessor(min);
    case "min-index":
      return reduceAccessor(minIndex);
    case "max":
      return reduceAccessor(max);
    case "max-index":
      return reduceAccessor(maxIndex);
    case "mean":
      return reduceMaybeTemporalAccessor(mean);
    case "median":
      return reduceMaybeTemporalAccessor(median);
    case "variance":
      return reduceAccessor(variance);
    case "mode":
      return reduceAccessor(mode);
    case "x":
      return reduceX;
    case "x1":
      return reduceX1;
    case "x2":
      return reduceX2;
    case "y":
      return reduceY;
    case "y1":
      return reduceY1;
    case "y2":
      return reduceY2;
  }
  throw new Error(`invalid reduce: ${reduce}`);
}
function maybeSubgroup(outputs, inputs) {
  for (const name in inputs) {
    const value = inputs[name];
    if (value !== void 0 && !outputs.some((o) => o.name === name)) {
      return value;
    }
  }
}
function maybeSort(facets, sort3, reverse3) {
  if (sort3) {
    const S = sort3.output.transform();
    const compare = (i, j) => ascendingDefined(S[i], S[j]);
    facets.forEach((f) => f.sort(compare));
  }
  if (reverse3) {
    facets.forEach((f) => f.reverse());
  }
}
function reduceFunction(f) {
  return {
    reduce(I, X, extent3) {
      return f(take(X, I), extent3);
    }
  };
}
function reduceAccessor(f) {
  return {
    reduce(I, X) {
      return f(I, (i) => X[i]);
    }
  };
}
function reduceMaybeTemporalAccessor(f) {
  return {
    reduce(I, X) {
      const x = f(I, (i) => X[i]);
      return isTemporal(X) ? new Date(x) : x;
    }
  };
}
var reduceIdentity = {
  reduce(I, X) {
    return take(X, I);
  }
};
var reduceFirst = {
  reduce(I, X) {
    return X[I[0]];
  }
};
var reduceTitle = {
  reduce(I, X) {
    const n = 5;
    const groups = sort(rollup(I, (V) => V.length, (i) => X[i]), second2);
    const top = groups.slice(-n).reverse();
    if (top.length < groups.length) {
      const bottom = groups.slice(0, 1 - n);
      top[n - 1] = [`… ${bottom.length.toLocaleString("en-US")} more`, sum(bottom, second2)];
    }
    return top.map(([key, value]) => `${key} (${value.toLocaleString("en-US")})`).join("\n");
  }
};
var reduceLast = {
  reduce(I, X) {
    return X[I[I.length - 1]];
  }
};
var reduceCount = {
  label: "Frequency",
  reduce(I) {
    return I.length;
  }
};
var reduceDistinct = {
  label: "Distinct",
  reduce: (I, X) => {
    const s = new InternSet();
    for (const i of I)
      s.add(X[i]);
    return s.size;
  }
};
var reduceSum = reduceAccessor(sum);
function reduceProportion(value, scope) {
  return value == null ? { scope, label: "Frequency", reduce: (I, V, basis = 1) => I.length / basis } : { scope, reduce: (I, V, basis = 1) => sum(I, (i) => V[i]) / basis };
}
function mid2(x1, x2) {
  const m = (+x1 + +x2) / 2;
  return x1 instanceof Date ? new Date(m) : m;
}
var reduceX = {
  reduce(I, X, { x1, x2 }) {
    return mid2(x1, x2);
  }
};
var reduceY = {
  reduce(I, X, { y1, y2 }) {
    return mid2(y1, y2);
  }
};
var reduceX1 = {
  reduce(I, X, { x1 }) {
    return x1;
  }
};
var reduceX2 = {
  reduce(I, X, { x2 }) {
    return x2;
  }
};
var reduceY1 = {
  reduce(I, X, { y1 }) {
    return y1;
  }
};
var reduceY2 = {
  reduce(I, X, { y2 }) {
    return y2;
  }
};

// ../../node_modules/@observablehq/plot/dist/channel.js
function Channel(data, { scale: scale2, type, value, filter: filter2, hint }) {
  return {
    scale: scale2,
    type,
    value: valueof(data, value),
    label: labelof(value),
    filter: filter2,
    hint
  };
}
function Channels(descriptors, data) {
  return Object.fromEntries(Object.entries(descriptors).map(([name, channel]) => [name, Channel(data, channel)]));
}
function valueObject(channels, scales) {
  return Object.fromEntries(Object.entries(channels).map(([name, { scale: scaleName, value }]) => {
    let scale2;
    if (scaleName !== void 0) {
      scale2 = scales[scaleName];
    }
    return [name, scale2 === void 0 ? value : map2(value, scale2)];
  }));
}
function channelDomain(channels, facetChannels, data, options) {
  const { reverse: defaultReverse, reduce: defaultReduce = true, limit: defaultLimit } = options;
  for (const x in options) {
    if (!registry.has(x))
      continue;
    let { value: y, reverse: reverse3 = defaultReverse, reduce = defaultReduce, limit = defaultLimit } = maybeValue(options[x]);
    if (reverse3 === void 0)
      reverse3 = y === "width" || y === "height";
    if (reduce == null || reduce === false)
      continue;
    const X = findScaleChannel(channels, x) || facetChannels && findScaleChannel(facetChannels, x);
    if (!X)
      throw new Error(`missing channel for scale: ${x}`);
    const XV = X.value;
    const [lo = 0, hi = Infinity] = isIterable(limit) ? limit : limit < 0 ? [limit] : [0, limit];
    if (y == null) {
      X.domain = () => {
        let domain = XV;
        if (reverse3)
          domain = domain.slice().reverse();
        if (lo !== 0 || hi !== Infinity)
          domain = domain.slice(lo, hi);
        return domain;
      };
    } else {
      const YV = y === "data" ? data : y === "height" ? difference(channels, "y1", "y2") : y === "width" ? difference(channels, "x1", "x2") : values(channels, y, y === "y" ? "y2" : y === "x" ? "x2" : void 0);
      const reducer = maybeReduce(reduce === true ? "max" : reduce, YV);
      X.domain = () => {
        let domain = rollup(range2(XV), (I) => reducer.reduce(I, YV), (i) => XV[i]);
        domain = sort(domain, reverse3 ? descendingGroup : ascendingGroup);
        if (lo !== 0 || hi !== Infinity)
          domain = domain.slice(lo, hi);
        return domain.map(first);
      };
    }
  }
}
function findScaleChannel(channels, scale2) {
  for (const name in channels) {
    const channel = channels[name];
    if (channel.scale === scale2)
      return channel;
  }
}
function difference(channels, k1, k2) {
  const X1 = values(channels, k1);
  const X2 = values(channels, k2);
  return map2(X2, (x2, i) => Math.abs(x2 - X1[i]), Float64Array);
}
function values(channels, name, alias) {
  let channel = channels[name];
  if (!channel && alias !== void 0)
    channel = channels[alias];
  if (channel)
    return channel.value;
  throw new Error(`missing channel: ${name}`);
}
function ascendingGroup([ak, av], [bk, bv]) {
  return ascending(av, bv) || ascending(ak, bk);
}
function descendingGroup([ak, av], [bk, bv]) {
  return descending(av, bv) || ascending(ak, bk);
}

// ../../node_modules/@observablehq/plot/dist/scales/schemes.js
var ordinalSchemes = /* @__PURE__ */ new Map([
  // categorical
  ["accent", Accent_default],
  ["category10", category10_default],
  ["dark2", Dark2_default],
  ["paired", Paired_default],
  ["pastel1", Pastel1_default],
  ["pastel2", Pastel2_default],
  ["set1", Set1_default],
  ["set2", Set2_default],
  ["set3", Set3_default],
  ["tableau10", Tableau10_default],
  // diverging
  ["brbg", scheme112(scheme, BrBG_default)],
  ["prgn", scheme112(scheme2, PRGn_default)],
  ["piyg", scheme112(scheme3, PiYG_default)],
  ["puor", scheme112(scheme4, PuOr_default)],
  ["rdbu", scheme112(scheme5, RdBu_default)],
  ["rdgy", scheme112(scheme6, RdGy_default)],
  ["rdylbu", scheme112(scheme7, RdYlBu_default)],
  ["rdylgn", scheme112(scheme8, RdYlGn_default)],
  ["spectral", scheme112(scheme9, Spectral_default)],
  // reversed diverging (for temperature data)
  ["burd", scheme11r(scheme5, RdBu_default)],
  ["buylrd", scheme11r(scheme7, RdYlBu_default)],
  // sequential (single-hue)
  ["blues", scheme92(scheme22, Blues_default)],
  ["greens", scheme92(scheme23, Greens_default)],
  ["greys", scheme92(scheme24, Greys_default)],
  ["oranges", scheme92(scheme27, Oranges_default)],
  ["purples", scheme92(scheme25, Purples_default)],
  ["reds", scheme92(scheme26, Reds_default)],
  // sequential (multi-hue)
  ["turbo", schemei(turbo_default)],
  ["viridis", schemei(viridis_default)],
  ["magma", schemei(magma)],
  ["inferno", schemei(inferno)],
  ["plasma", schemei(plasma)],
  ["cividis", schemei(cividis_default)],
  ["cubehelix", schemei(cubehelix_default)],
  ["warm", schemei(warm)],
  ["cool", schemei(cool)],
  ["bugn", scheme92(scheme10, BuGn_default)],
  ["bupu", scheme92(scheme11, BuPu_default)],
  ["gnbu", scheme92(scheme12, GnBu_default)],
  ["orrd", scheme92(scheme13, OrRd_default)],
  ["pubu", scheme92(scheme15, PuBu_default)],
  ["pubugn", scheme92(scheme14, PuBuGn_default)],
  ["purd", scheme92(scheme16, PuRd_default)],
  ["rdpu", scheme92(scheme17, RdPu_default)],
  ["ylgn", scheme92(scheme19, YlGn_default)],
  ["ylgnbu", scheme92(scheme18, YlGnBu_default)],
  ["ylorbr", scheme92(scheme20, YlOrBr_default)],
  ["ylorrd", scheme92(scheme21, YlOrRd_default)],
  // cyclical
  ["rainbow", schemeicyclical(rainbow_default)],
  ["sinebow", schemeicyclical(sinebow_default)]
]);
function scheme92(scheme28, interpolate) {
  return ({ length: n }) => {
    if (n === 1)
      return [scheme28[3][1]];
    if (n === 2)
      return [scheme28[3][1], scheme28[3][2]];
    n = Math.max(3, Math.floor(n));
    return n > 9 ? quantize_default(interpolate, n) : scheme28[n];
  };
}
function scheme112(scheme28, interpolate) {
  return ({ length: n }) => {
    if (n === 2)
      return [scheme28[3][0], scheme28[3][2]];
    n = Math.max(3, Math.floor(n));
    return n > 11 ? quantize_default(interpolate, n) : scheme28[n];
  };
}
function scheme11r(scheme28, interpolate) {
  return ({ length: n }) => {
    if (n === 2)
      return [scheme28[3][2], scheme28[3][0]];
    n = Math.max(3, Math.floor(n));
    return n > 11 ? quantize_default((t) => interpolate(1 - t), n) : scheme28[n].slice().reverse();
  };
}
function schemei(interpolate) {
  return ({ length: n }) => quantize_default(interpolate, Math.max(2, Math.floor(n)));
}
function schemeicyclical(interpolate) {
  return ({ length: n }) => quantize_default(interpolate, Math.floor(n) + 1).slice(0, -1);
}
function ordinalScheme(scheme28) {
  const s = `${scheme28}`.toLowerCase();
  if (!ordinalSchemes.has(s))
    throw new Error(`unknown ordinal scheme: ${s}`);
  return ordinalSchemes.get(s);
}
function ordinalRange(scheme28, length2) {
  const s = ordinalScheme(scheme28);
  const r = typeof s === "function" ? s({ length: length2 }) : s;
  return r.length !== length2 ? r.slice(0, length2) : r;
}
function maybeBooleanRange(domain, scheme28 = "greys") {
  const range3 = /* @__PURE__ */ new Set();
  const [f, t] = ordinalRange(scheme28, 2);
  for (const value of domain) {
    if (value == null)
      continue;
    if (value === true)
      range3.add(t);
    else if (value === false)
      range3.add(f);
    else
      return;
  }
  return [...range3];
}
var quantitativeSchemes = /* @__PURE__ */ new Map([
  // diverging
  ["brbg", BrBG_default],
  ["prgn", PRGn_default],
  ["piyg", PiYG_default],
  ["puor", PuOr_default],
  ["rdbu", RdBu_default],
  ["rdgy", RdGy_default],
  ["rdylbu", RdYlBu_default],
  ["rdylgn", RdYlGn_default],
  ["spectral", Spectral_default],
  // reversed diverging (for temperature data)
  ["burd", (t) => RdBu_default(1 - t)],
  ["buylrd", (t) => RdYlBu_default(1 - t)],
  // sequential (single-hue)
  ["blues", Blues_default],
  ["greens", Greens_default],
  ["greys", Greys_default],
  ["purples", Purples_default],
  ["reds", Reds_default],
  ["oranges", Oranges_default],
  // sequential (multi-hue)
  ["turbo", turbo_default],
  ["viridis", viridis_default],
  ["magma", magma],
  ["inferno", inferno],
  ["plasma", plasma],
  ["cividis", cividis_default],
  ["cubehelix", cubehelix_default],
  ["warm", warm],
  ["cool", cool],
  ["bugn", BuGn_default],
  ["bupu", BuPu_default],
  ["gnbu", GnBu_default],
  ["orrd", OrRd_default],
  ["pubugn", PuBuGn_default],
  ["pubu", PuBu_default],
  ["purd", PuRd_default],
  ["rdpu", RdPu_default],
  ["ylgnbu", YlGnBu_default],
  ["ylgn", YlGn_default],
  ["ylorbr", YlOrBr_default],
  ["ylorrd", YlOrRd_default],
  // cyclical
  ["rainbow", rainbow_default],
  ["sinebow", sinebow_default]
]);
function quantitativeScheme(scheme28) {
  const s = `${scheme28}`.toLowerCase();
  if (!quantitativeSchemes.has(s))
    throw new Error(`unknown quantitative scheme: ${s}`);
  return quantitativeSchemes.get(s);
}
var divergingSchemes = /* @__PURE__ */ new Set([
  "brbg",
  "prgn",
  "piyg",
  "puor",
  "rdbu",
  "rdgy",
  "rdylbu",
  "rdylgn",
  "spectral",
  "burd",
  "buylrd"
]);
function isDivergingScheme(scheme28) {
  return scheme28 != null && divergingSchemes.has(`${scheme28}`.toLowerCase());
}

// ../../node_modules/@observablehq/plot/dist/scales/quantitative.js
var flip = (i) => (t) => i(1 - t);
var unit = [0, 1];
var interpolators = /* @__PURE__ */ new Map([
  // numbers
  ["number", number_default],
  // color spaces
  ["rgb", rgb_default],
  ["hsl", hsl_default],
  ["hcl", hcl_default],
  ["lab", lab]
]);
function Interpolator(interpolate) {
  const i = `${interpolate}`.toLowerCase();
  if (!interpolators.has(i))
    throw new Error(`unknown interpolator: ${i}`);
  return interpolators.get(i);
}
function ScaleQ(key, scale2, channels, { type, nice: nice2, clamp, zero, domain = inferAutoDomain(key, channels), unknown, round: round2, scheme: scheme28, interval, range: range3 = registry.get(key) === radius ? inferRadialRange(channels, domain) : registry.get(key) === length ? inferLengthRange(channels, domain) : registry.get(key) === opacity ? unit : void 0, interpolate = registry.get(key) === color2 ? scheme28 == null && range3 !== void 0 ? rgb_default : quantitativeScheme(scheme28 !== void 0 ? scheme28 : type === "cyclical" ? "rainbow" : "turbo") : round2 ? round_default : number_default, reverse: reverse3 }) {
  interval = maybeInterval(interval);
  if (type === "cyclical" || type === "sequential")
    type = "linear";
  reverse3 = !!reverse3;
  if (typeof interpolate !== "function") {
    interpolate = Interpolator(interpolate);
  }
  if (interpolate.length === 1) {
    if (reverse3) {
      interpolate = flip(interpolate);
      reverse3 = false;
    }
    if (range3 === void 0) {
      range3 = Float64Array.from(domain, (_, i) => i / (domain.length - 1));
      if (range3.length === 2)
        range3 = unit;
    }
    scale2.interpolate((range3 === unit ? constant : interpolatePiecewise)(interpolate));
  } else {
    scale2.interpolate(interpolate);
  }
  if (zero) {
    const [min2, max2] = extent(domain);
    if (min2 > 0 || max2 < 0) {
      domain = slice(domain);
      if (order(domain) !== Math.sign(min2))
        domain[domain.length - 1] = 0;
      else
        domain[0] = 0;
    }
  }
  if (reverse3)
    domain = reverse(domain);
  scale2.domain(domain).unknown(unknown);
  if (nice2)
    scale2.nice(nice2 === true ? void 0 : nice2), domain = scale2.domain();
  if (range3 !== void 0)
    scale2.range(range3);
  if (clamp)
    scale2.clamp(clamp);
  return { type, domain, range: range3, scale: scale2, interpolate, interval };
}
function ScaleLinear(key, channels, options) {
  return ScaleQ(key, linear(), channels, options);
}
function ScaleSqrt(key, channels, options) {
  return ScalePow(key, channels, { ...options, exponent: 0.5 });
}
function ScalePow(key, channels, { exponent = 1, ...options }) {
  return ScaleQ(key, pow().exponent(exponent), channels, { ...options, type: "pow" });
}
function ScaleLog(key, channels, { base = 10, domain = inferLogDomain(channels), ...options }) {
  return ScaleQ(key, log().base(base), channels, { ...options, domain });
}
function ScaleSymlog(key, channels, { constant: constant2 = 1, ...options }) {
  return ScaleQ(key, symlog().constant(constant2), channels, options);
}
function ScaleQuantile(key, channels, {
  range: range3,
  quantiles = range3 === void 0 ? 5 : (range3 = [...range3]).length,
  // deprecated; use n instead
  n = quantiles,
  scheme: scheme28 = "rdylbu",
  domain = inferQuantileDomain(channels),
  interpolate,
  reverse: reverse3
}) {
  if (range3 === void 0) {
    range3 = interpolate !== void 0 ? quantize_default(interpolate, n) : registry.get(key) === color2 ? ordinalRange(scheme28, n) : void 0;
  }
  if (domain.length > 0) {
    domain = quantile2(domain, range3 === void 0 ? { length: n } : range3).quantiles();
  }
  return ScaleThreshold(key, channels, { domain, range: range3, reverse: reverse3 });
}
function ScaleQuantize(key, channels, { range: range3, n = range3 === void 0 ? 5 : (range3 = [...range3]).length, scheme: scheme28 = "rdylbu", domain = inferAutoDomain(key, channels), unknown, interpolate, reverse: reverse3 }) {
  const [min2, max2] = extent(domain);
  let thresholds;
  if (range3 === void 0) {
    thresholds = ticks(min2, max2, n);
    if (thresholds[0] <= min2)
      thresholds.splice(0, 1);
    if (thresholds[thresholds.length - 1] >= max2)
      thresholds.pop();
    n = thresholds.length + 1;
    range3 = interpolate !== void 0 ? quantize_default(interpolate, n) : registry.get(key) === color2 ? ordinalRange(scheme28, n) : void 0;
  } else {
    thresholds = quantize_default(number_default(min2, max2), n + 1).slice(1, -1);
    if (min2 instanceof Date)
      thresholds = thresholds.map((x) => new Date(x));
  }
  if (order(arrayify(domain)) < 0)
    thresholds.reverse();
  return ScaleThreshold(key, channels, { domain: thresholds, range: range3, reverse: reverse3, unknown });
}
function ScaleThreshold(key, channels, {
  domain = [0],
  // explicit thresholds in ascending order
  unknown,
  scheme: scheme28 = "rdylbu",
  interpolate,
  range: range3 = interpolate !== void 0 ? quantize_default(interpolate, domain.length + 1) : registry.get(key) === color2 ? ordinalRange(scheme28, domain.length + 1) : void 0,
  reverse: reverse3
}) {
  const sign = order(arrayify(domain));
  if (!pairs(domain).every(([a, b]) => isOrdered(a, b, sign)))
    throw new Error(`the ${key} scale has a non-monotonic domain`);
  if (reverse3)
    range3 = reverse(range3);
  return {
    type: "threshold",
    scale: threshold(sign < 0 ? reverse(domain) : domain, range3 === void 0 ? [] : range3).unknown(unknown),
    domain,
    range: range3
  };
}
function isOrdered(a, b, sign) {
  const s = descending(a, b);
  return s === 0 || s === sign;
}
function ScaleIdentity() {
  return { type: "identity", scale: identity() };
}
function inferDomain(channels, f = finite) {
  return channels.length ? [
    min(channels, ({ value }) => value === void 0 ? value : min(value, f)),
    max(channels, ({ value }) => value === void 0 ? value : max(value, f))
  ] : [0, 1];
}
function inferAutoDomain(key, channels) {
  const type = registry.get(key);
  return (type === radius || type === opacity || type === length ? inferZeroDomain : inferDomain)(channels);
}
function inferZeroDomain(channels) {
  return [0, channels.length ? max(channels, ({ value }) => value === void 0 ? value : max(value, finite)) : 1];
}
function inferRadialRange(channels, domain) {
  const hint = channels.find(({ radius: radius2 }) => radius2 !== void 0);
  if (hint !== void 0)
    return [0, hint.radius];
  const h25 = quantile(channels, 0.5, ({ value }) => value === void 0 ? NaN : quantile(value, 0.25, positive));
  const range3 = domain.map((d) => 3 * Math.sqrt(d / h25));
  const k = 30 / max(range3);
  return k < 1 ? range3.map((r) => r * k) : range3;
}
function inferLengthRange(channels, domain) {
  const h50 = median(channels, ({ value }) => value === void 0 ? NaN : median(value, Math.abs));
  const range3 = domain.map((d) => 12 * d / h50);
  const k = 60 / max(range3);
  return k < 1 ? range3.map((r) => r * k) : range3;
}
function inferLogDomain(channels) {
  for (const { value } of channels) {
    if (value !== void 0) {
      for (let v of value) {
        v = +v;
        if (v > 0)
          return inferDomain(channels, positive);
        if (v < 0)
          return inferDomain(channels, negative);
      }
    }
  }
  return [1, 10];
}
function inferQuantileDomain(channels) {
  const domain = [];
  for (const { value } of channels) {
    if (value === void 0)
      continue;
    for (const v of value)
      domain.push(v);
  }
  return domain;
}
function interpolatePiecewise(interpolate) {
  return (i, j) => (t) => interpolate(i + t * (j - i));
}

// ../../node_modules/@observablehq/plot/dist/scales/diverging.js
function ScaleD(key, scale2, transform, channels, { type, nice: nice2, clamp, domain = inferDomain(channels), unknown, pivot = 0, scheme: scheme28, range: range3, symmetric = true, interpolate = registry.get(key) === color2 ? scheme28 == null && range3 !== void 0 ? rgb_default : quantitativeScheme(scheme28 !== void 0 ? scheme28 : "rdbu") : number_default, reverse: reverse3 }) {
  pivot = +pivot;
  let [min2, max2] = domain;
  if (descending(min2, max2) < 0)
    [min2, max2] = [max2, min2], reverse3 = !reverse3;
  min2 = Math.min(min2, pivot);
  max2 = Math.max(max2, pivot);
  if (typeof interpolate !== "function") {
    interpolate = Interpolator(interpolate);
  }
  if (range3 !== void 0) {
    interpolate = interpolate.length === 1 ? interpolatePiecewise(interpolate)(...range3) : piecewise(interpolate, range3);
  }
  if (reverse3)
    interpolate = flip(interpolate);
  if (symmetric) {
    const mid3 = transform.apply(pivot);
    const mindelta = mid3 - transform.apply(min2);
    const maxdelta = transform.apply(max2) - mid3;
    if (mindelta < maxdelta)
      min2 = transform.invert(mid3 - maxdelta);
    else if (mindelta > maxdelta)
      max2 = transform.invert(mid3 + mindelta);
  }
  scale2.domain([min2, pivot, max2]).unknown(unknown).interpolator(interpolate);
  if (clamp)
    scale2.clamp(clamp);
  if (nice2)
    scale2.nice(nice2);
  return { type, domain: [min2, max2], pivot, interpolate, scale: scale2 };
}
function ScaleDiverging(key, channels, options) {
  return ScaleD(key, diverging(), transformIdentity, channels, options);
}
function ScaleDivergingSqrt(key, channels, options) {
  return ScaleDivergingPow(key, channels, { ...options, exponent: 0.5 });
}
function ScaleDivergingPow(key, channels, { exponent = 1, ...options }) {
  return ScaleD(key, divergingPow().exponent(exponent = +exponent), transformPow(exponent), channels, {
    ...options,
    type: "diverging-pow"
  });
}
function ScaleDivergingLog(key, channels, { base = 10, pivot = 1, domain = inferDomain(channels, pivot < 0 ? negative : positive), ...options }) {
  return ScaleD(key, divergingLog().base(base = +base), transformLog, channels, { domain, pivot, ...options });
}
function ScaleDivergingSymlog(key, channels, { constant: constant2 = 1, ...options }) {
  return ScaleD(key, divergingSymlog().constant(constant2 = +constant2), transformSymlog(constant2), channels, options);
}
var transformIdentity = {
  apply(x) {
    return x;
  },
  invert(x) {
    return x;
  }
};
var transformLog = {
  apply: Math.log,
  invert: Math.exp
};
var transformSqrt = {
  apply(x) {
    return Math.sign(x) * Math.sqrt(Math.abs(x));
  },
  invert(x) {
    return Math.sign(x) * (x * x);
  }
};
function transformPow(exponent) {
  return exponent === 0.5 ? transformSqrt : {
    apply(x) {
      return Math.sign(x) * Math.pow(Math.abs(x), exponent);
    },
    invert(x) {
      return Math.sign(x) * Math.pow(Math.abs(x), 1 / exponent);
    }
  };
}
function transformSymlog(constant2) {
  return {
    apply(x) {
      return Math.sign(x) * Math.log1p(Math.abs(x / constant2));
    },
    invert(x) {
      return Math.sign(x) * Math.expm1(Math.abs(x)) * constant2;
    }
  };
}

// ../../node_modules/@observablehq/plot/dist/scales/temporal.js
function ScaleT(key, scale2, channels, options) {
  return ScaleQ(key, scale2, channels, options);
}
function ScaleTime(key, channels, options) {
  return ScaleT(key, time(), channels, options);
}
function ScaleUtc(key, channels, options) {
  return ScaleT(key, utcTime(), channels, options);
}

// ../../node_modules/@observablehq/plot/dist/symbols.js
var sqrt3 = Math.sqrt(3);
var sqrt4_3 = 2 / sqrt3;
var symbolHexagon = {
  draw(context, size) {
    const rx = Math.sqrt(size / Math.PI), ry = rx * sqrt4_3, hy = ry / 2;
    context.moveTo(0, ry);
    context.lineTo(rx, hy);
    context.lineTo(rx, -hy);
    context.lineTo(0, -ry);
    context.lineTo(-rx, -hy);
    context.lineTo(-rx, hy);
    context.closePath();
  }
};
var symbols = /* @__PURE__ */ new Map([
  ["asterisk", asterisk_default],
  ["circle", circle_default],
  ["cross", cross_default],
  ["diamond", diamond_default],
  ["diamond2", diamond2_default],
  ["hexagon", symbolHexagon],
  ["plus", plus_default],
  ["square", square_default],
  ["square2", square2_default],
  ["star", star_default],
  ["times", times_default],
  ["triangle", triangle_default],
  ["triangle2", triangle2_default],
  ["wye", wye_default]
]);
function isSymbolObject(value) {
  return value && typeof value.draw === "function";
}
function isSymbol(value) {
  if (isSymbolObject(value))
    return true;
  if (typeof value !== "string")
    return false;
  return symbols.has(value.toLowerCase());
}
function maybeSymbol(symbol2) {
  if (symbol2 == null || isSymbolObject(symbol2))
    return symbol2;
  const value = symbols.get(`${symbol2}`.toLowerCase());
  if (value)
    return value;
  throw new Error(`invalid symbol: ${symbol2}`);
}
function maybeSymbolChannel(symbol2) {
  if (symbol2 == null || isSymbolObject(symbol2))
    return [void 0, symbol2];
  if (typeof symbol2 === "string") {
    const value = symbols.get(`${symbol2}`.toLowerCase());
    if (value)
      return [void 0, value];
  }
  return [symbol2, void 0];
}

// ../../node_modules/@observablehq/plot/dist/scales/ordinal.js
var ordinalImplicit = Symbol("ordinal");
function ScaleO(key, scale2, channels, { type, interval, domain, range: range3, reverse: reverse3, hint }) {
  interval = maybeInterval(interval);
  if (domain === void 0)
    domain = inferDomain2(channels, interval, key);
  if (type === "categorical" || type === ordinalImplicit)
    type = "ordinal";
  if (reverse3)
    domain = reverse(domain);
  scale2.domain(domain);
  if (range3 !== void 0) {
    if (typeof range3 === "function")
      range3 = range3(domain);
    scale2.range(range3);
  }
  return { type, domain, range: range3, scale: scale2, hint, interval };
}
function ScaleOrdinal(key, channels, { type, interval, domain, range: range3, scheme: scheme28, unknown, ...options }) {
  interval = maybeInterval(interval);
  if (domain === void 0)
    domain = inferDomain2(channels, interval, key);
  let hint;
  if (registry.get(key) === symbol) {
    hint = inferSymbolHint(channels);
    range3 = range3 === void 0 ? inferSymbolRange(hint) : map2(range3, maybeSymbol);
  } else if (registry.get(key) === color2) {
    if (range3 === void 0 && (type === "ordinal" || type === ordinalImplicit)) {
      range3 = maybeBooleanRange(domain, scheme28);
      if (range3 !== void 0)
        scheme28 = void 0;
    }
    if (scheme28 === void 0 && range3 === void 0) {
      scheme28 = type === "ordinal" ? "turbo" : "tableau10";
    }
    if (scheme28 !== void 0) {
      if (range3 !== void 0) {
        const interpolate = quantitativeScheme(scheme28);
        const t0 = range3[0], d = range3[1] - range3[0];
        range3 = ({ length: n }) => quantize_default((t) => interpolate(t0 + d * t), n);
      } else {
        range3 = ordinalScheme(scheme28);
      }
    }
  }
  if (unknown === implicit)
    throw new Error("implicit unknown is not supported");
  return ScaleO(key, ordinal().unknown(unknown), channels, { ...options, type, domain, range: range3, hint });
}
function ScalePoint(key, channels, { align = 0.5, padding = 0.5, ...options }) {
  return maybeRound(point().align(align).padding(padding), channels, options, key);
}
function ScaleBand(key, channels, { align = 0.5, padding = 0.1, paddingInner = padding, paddingOuter = key === "fx" || key === "fy" ? 0 : padding, ...options }) {
  return maybeRound(band().align(align).paddingInner(paddingInner).paddingOuter(paddingOuter), channels, options, key);
}
function maybeRound(scale2, channels, options, key) {
  let { round: round2 } = options;
  if (round2 !== void 0)
    scale2.round(round2 = !!round2);
  scale2 = ScaleO(key, scale2, channels, options);
  scale2.round = round2;
  return scale2;
}
function inferDomain2(channels, interval, key) {
  const values2 = new InternSet();
  for (const { value, domain } of channels) {
    if (domain !== void 0)
      return domain();
    if (value === void 0)
      continue;
    for (const v of value)
      values2.add(v);
  }
  if (interval !== void 0) {
    const [min2, max2] = extent(values2).map(interval.floor, interval);
    return interval.range(min2, interval.offset(max2));
  }
  if (values2.size > 1e4 && registry.get(key) === position)
    throw new Error("implicit ordinal position domain has more than 10,000 values");
  return sort(values2, ascendingDefined);
}
function inferHint(channels, key) {
  let value;
  for (const { hint } of channels) {
    const candidate = hint == null ? void 0 : hint[key];
    if (candidate === void 0)
      continue;
    if (value === void 0)
      value = candidate;
    else if (value !== candidate)
      return;
  }
  return value;
}
function inferSymbolHint(channels) {
  return {
    fill: inferHint(channels, "fill"),
    stroke: inferHint(channels, "stroke")
  };
}
function inferSymbolRange(hint) {
  return isNoneish(hint.fill) ? symbolsStroke : symbolsFill;
}

// ../../node_modules/@observablehq/plot/dist/warnings.js
var warnings = 0;
function consumeWarnings() {
  const w = warnings;
  warnings = 0;
  return w;
}
function warn(message) {
  console.warn(message);
  ++warnings;
}

// ../../node_modules/@observablehq/plot/dist/scales.js
function Scales(channelsByScale, { inset: globalInset = 0, insetTop: globalInsetTop = globalInset, insetRight: globalInsetRight = globalInset, insetBottom: globalInsetBottom = globalInset, insetLeft: globalInsetLeft = globalInset, round: round2, nice: nice2, clamp, zero, align, padding, projection, ...options } = {}) {
  const scales = {};
  for (const [key, channels] of channelsByScale) {
    const scaleOptions = options[key];
    const scale2 = Scale(key, channels, {
      round: registry.get(key) === position ? round2 : void 0,
      nice: nice2,
      clamp,
      zero,
      align,
      padding,
      projection,
      ...scaleOptions
    });
    if (scale2) {
      let {
        percent,
        transform,
        inset,
        insetTop = inset !== void 0 ? inset : key === "y" ? globalInsetTop : 0,
        // not fy
        insetRight = inset !== void 0 ? inset : key === "x" ? globalInsetRight : 0,
        // not fx
        insetBottom = inset !== void 0 ? inset : key === "y" ? globalInsetBottom : 0,
        // not fy
        insetLeft = inset !== void 0 ? inset : key === "x" ? globalInsetLeft : 0
        // not fx
      } = scaleOptions || {};
      if (transform == null)
        transform = void 0;
      else if (typeof transform !== "function")
        throw new Error("invalid scale transform; not a function");
      scale2.percent = !!percent;
      scale2.transform = transform;
      if (key === "x" || key === "fx") {
        scale2.insetLeft = +insetLeft;
        scale2.insetRight = +insetRight;
      } else if (key === "y" || key === "fy") {
        scale2.insetTop = +insetTop;
        scale2.insetBottom = +insetBottom;
      }
      scales[key] = scale2;
    }
  }
  return scales;
}
function ScaleFunctions(scales) {
  return Object.fromEntries(Object.entries(scales).map(([name, { scale: scale2 }]) => [name, scale2]));
}
function autoScaleRange({ x, y, fx, fy }, dimensions) {
  if (fx)
    autoScaleRangeX(fx, dimensions);
  if (fy)
    autoScaleRangeY(fy, dimensions);
  if (x)
    autoScaleRangeX(x, fx ? { width: fx.scale.bandwidth() } : dimensions);
  if (y)
    autoScaleRangeY(y, fy ? { height: fy.scale.bandwidth() } : dimensions);
}
function autoScaleRangeX(scale2, dimensions) {
  if (scale2.range === void 0) {
    const { insetLeft, insetRight } = scale2;
    const { width, marginLeft = 0, marginRight = 0 } = dimensions;
    const left = marginLeft + insetLeft;
    const right = width - marginRight - insetRight;
    scale2.range = [left, Math.max(left, right)];
    if (!isOrdinalScale(scale2))
      scale2.range = piecewiseRange(scale2);
    scale2.scale.range(scale2.range);
  }
  autoScaleRound(scale2);
}
function autoScaleRangeY(scale2, dimensions) {
  if (scale2.range === void 0) {
    const { insetTop, insetBottom } = scale2;
    const { height, marginTop = 0, marginBottom = 0 } = dimensions;
    const top = marginTop + insetTop;
    const bottom = height - marginBottom - insetBottom;
    scale2.range = [Math.max(top, bottom), top];
    if (!isOrdinalScale(scale2))
      scale2.range = piecewiseRange(scale2);
    else
      scale2.range.reverse();
    scale2.scale.range(scale2.range);
  }
  autoScaleRound(scale2);
}
function autoScaleRound(scale2) {
  if (scale2.round === void 0 && isBandScale(scale2) && roundError(scale2) <= 30) {
    scale2.scale.round(true);
  }
}
function roundError({ scale: scale2 }) {
  const n = scale2.domain().length;
  const [start, stop] = scale2.range();
  const paddingInner = scale2.paddingInner ? scale2.paddingInner() : 1;
  const paddingOuter = scale2.paddingOuter ? scale2.paddingOuter() : scale2.padding();
  const m = n - paddingInner;
  const step = Math.abs(stop - start) / Math.max(1, m + paddingOuter * 2);
  return (step - Math.floor(step)) * m;
}
function piecewiseRange(scale2) {
  const length2 = scale2.scale.domain().length + isThresholdScale(scale2);
  if (!(length2 > 2))
    return scale2.range;
  const [start, end] = scale2.range;
  return Array.from({ length: length2 }, (_, i) => start + i / (length2 - 1) * (end - start));
}
function normalizeScale(key, scale2, hint) {
  return Scale(key, hint === void 0 ? void 0 : [{ hint }], { ...scale2 });
}
function Scale(key, channels = [], options = {}) {
  const type = inferScaleType(key, channels, options);
  if (options.type === void 0 && options.domain === void 0 && options.range === void 0 && options.interval == null && key !== "fx" && key !== "fy" && isOrdinalScale({ type })) {
    const values2 = channels.map(({ value }) => value).filter((value) => value !== void 0);
    if (values2.some(isTemporal))
      warn(`Warning: some data associated with the ${key} scale are dates. Dates are typically associated with a "utc" or "time" scale rather than a "${formatScaleType(type)}" scale. If you are using a bar mark, you probably want a rect mark with the interval option instead; if you are using a group transform, you probably want a bin transform instead. If you want to treat this data as ordinal, you can specify the interval of the ${key} scale (e.g., d3.utcDay), or you can suppress this warning by setting the type of the ${key} scale to "${formatScaleType(type)}".`);
    else if (values2.some(isTemporalString))
      warn(`Warning: some data associated with the ${key} scale are strings that appear to be dates (e.g., YYYY-MM-DD). If these strings represent dates, you should parse them to Date objects. Dates are typically associated with a "utc" or "time" scale rather than a "${formatScaleType(type)}" scale. If you are using a bar mark, you probably want a rect mark with the interval option instead; if you are using a group transform, you probably want a bin transform instead. If you want to treat this data as ordinal, you can suppress this warning by setting the type of the ${key} scale to "${formatScaleType(type)}".`);
    else if (values2.some(isNumericString))
      warn(`Warning: some data associated with the ${key} scale are strings that appear to be numbers. If these strings represent numbers, you should parse or coerce them to numbers. Numbers are typically associated with a "linear" scale rather than a "${formatScaleType(type)}" scale. If you want to treat this data as ordinal, you can specify the interval of the ${key} scale (e.g., 1 for integers), or you can suppress this warning by setting the type of the ${key} scale to "${formatScaleType(type)}".`);
  }
  options.type = type;
  switch (type) {
    case "diverging":
    case "diverging-sqrt":
    case "diverging-pow":
    case "diverging-log":
    case "diverging-symlog":
    case "cyclical":
    case "sequential":
    case "linear":
    case "sqrt":
    case "threshold":
    case "quantile":
    case "pow":
    case "log":
    case "symlog":
      options = coerceType(channels, options, coerceNumbers);
      break;
    case "identity":
      switch (registry.get(key)) {
        case position:
          options = coerceType(channels, options, coerceNumbers);
          break;
        case symbol:
          options = coerceType(channels, options, coerceSymbols);
          break;
      }
      break;
    case "utc":
    case "time":
      options = coerceType(channels, options, coerceDates);
      break;
  }
  switch (type) {
    case "diverging":
      return ScaleDiverging(key, channels, options);
    case "diverging-sqrt":
      return ScaleDivergingSqrt(key, channels, options);
    case "diverging-pow":
      return ScaleDivergingPow(key, channels, options);
    case "diverging-log":
      return ScaleDivergingLog(key, channels, options);
    case "diverging-symlog":
      return ScaleDivergingSymlog(key, channels, options);
    case "categorical":
    case "ordinal":
    case ordinalImplicit:
      return ScaleOrdinal(key, channels, options);
    case "cyclical":
    case "sequential":
    case "linear":
      return ScaleLinear(key, channels, options);
    case "sqrt":
      return ScaleSqrt(key, channels, options);
    case "threshold":
      return ScaleThreshold(key, channels, options);
    case "quantile":
      return ScaleQuantile(key, channels, options);
    case "quantize":
      return ScaleQuantize(key, channels, options);
    case "pow":
      return ScalePow(key, channels, options);
    case "log":
      return ScaleLog(key, channels, options);
    case "symlog":
      return ScaleSymlog(key, channels, options);
    case "utc":
      return ScaleUtc(key, channels, options);
    case "time":
      return ScaleTime(key, channels, options);
    case "point":
      return ScalePoint(key, channels, options);
    case "band":
      return ScaleBand(key, channels, options);
    case "identity":
      return registry.get(key) === position ? ScaleIdentity() : { type: "identity" };
    case void 0:
      return;
    default:
      throw new Error(`unknown scale type: ${type}`);
  }
}
function formatScaleType(type) {
  return typeof type === "symbol" ? type.description : type;
}
var typeProjection = { toString: () => "projection" };
function inferScaleType(key, channels, { type, domain, range: range3, scheme: scheme28, pivot, projection }) {
  if (key === "fx" || key === "fy")
    return "band";
  if ((key === "x" || key === "y") && projection != null)
    type = typeProjection;
  for (const { type: t } of channels) {
    if (t === void 0)
      continue;
    else if (type === void 0)
      type = t;
    else if (type !== t)
      throw new Error(`scale incompatible with channel: ${type} !== ${t}`);
  }
  if (type === typeProjection)
    return;
  if (type !== void 0)
    return type;
  if (domain === void 0 && !channels.some(({ value }) => value !== void 0))
    return;
  const kind = registry.get(key);
  if (kind === color2 && range3 === void 0 && scheme28 === void 0 && isAll(domain, channels, isColor))
    return "identity";
  if (kind === symbol && range3 === void 0 && isAll(domain, channels, isSymbol))
    return "identity";
  if (kind === radius)
    return "sqrt";
  if (kind === opacity || kind === length)
    return "linear";
  if (kind === symbol)
    return "ordinal";
  if ((domain || range3 || []).length > 2)
    return asOrdinalType(kind);
  if (domain !== void 0) {
    if (isOrdinal(domain))
      return asOrdinalType(kind);
    if (isTemporal(domain))
      return "utc";
    if (kind === color2 && (pivot != null || isDivergingScheme(scheme28)))
      return "diverging";
    return "linear";
  }
  const values2 = channels.map(({ value }) => value).filter((value) => value !== void 0);
  if (values2.some(isOrdinal))
    return asOrdinalType(kind);
  if (values2.some(isTemporal))
    return "utc";
  if (kind === color2 && (pivot != null || isDivergingScheme(scheme28)))
    return "diverging";
  return "linear";
}
function asOrdinalType(kind) {
  switch (kind) {
    case position:
      return "point";
    case color2:
      return ordinalImplicit;
    default:
      return "ordinal";
  }
}
function isAll(domain, channels, is) {
  return domain !== void 0 ? isFirst(domain, is) && isEvery(domain, is) : channels.some(({ value }) => value !== void 0 && isFirst(value, is)) && channels.every(({ value }) => value === void 0 || isEvery(value, is));
}
function isTemporalScale({ type }) {
  return type === "time" || type === "utc";
}
function isOrdinalScale({ type }) {
  return type === "ordinal" || type === "point" || type === "band" || type === ordinalImplicit;
}
function isThresholdScale({ type }) {
  return type === "threshold";
}
function isBandScale({ type }) {
  return type === "point" || type === "band";
}
function scaleOrder({ range: range3, domain = range3 }) {
  return Math.sign(order(domain)) * Math.sign(order(range3));
}
function isCollapsed(scale2) {
  if (scale2 === void 0)
    return true;
  const domain = scale2.domain();
  const value = scale2(domain[0]);
  for (let i = 1, n = domain.length; i < n; ++i) {
    if (scale2(domain[i]) - value) {
      return false;
    }
  }
  return true;
}
function coerceType(channels, { domain, ...options }, coerceValues) {
  for (const c of channels) {
    if (c.value !== void 0) {
      c.value = coerceValues(c.value);
    }
  }
  return {
    domain: domain === void 0 ? domain : coerceValues(domain),
    ...options
  };
}
function coerceSymbols(values2) {
  return map2(values2, maybeSymbol);
}
function coerceDates(values2) {
  return map2(values2, coerceDate);
}
function coerceNumbers(values2) {
  return isTypedArray(values2) ? values2 : map2(values2, coerceNumber, Float64Array);
}
function coerceNumber(x) {
  return x == null ? NaN : +x;
}
function coerceDate(x) {
  return x instanceof Date && !isNaN(x) ? x : typeof x === "string" ? parse(x) : x == null || isNaN(x = +x) ? void 0 : new Date(x);
}
function scale(options = {}) {
  let scale2;
  for (const key in options) {
    if (!registry.has(key))
      continue;
    if (!isScaleOptions(options[key]))
      continue;
    if (scale2 !== void 0)
      throw new Error("ambiguous scale definition; multiple scales found");
    scale2 = exposeScale(normalizeScale(key, options[key]));
  }
  if (scale2 === void 0)
    throw new Error("invalid scale definition; no scale found");
  return scale2;
}
function exposeScales(scaleDescriptors) {
  return (key) => {
    if (!registry.has(key = `${key}`))
      throw new Error(`unknown scale: ${key}`);
    return key in scaleDescriptors ? exposeScale(scaleDescriptors[key]) : void 0;
  };
}
function exposeScale({ scale: scale2, type, domain, range: range3, label, interpolate, interval, transform, percent, pivot }) {
  if (type === "identity")
    return { type: "identity", apply: (d) => d, invert: (d) => d };
  const unknown = scale2.unknown ? scale2.unknown() : void 0;
  return {
    type,
    domain: slice(domain),
    ...range3 !== void 0 && { range: slice(range3) },
    ...transform !== void 0 && { transform },
    ...percent && { percent },
    ...label !== void 0 && { label },
    ...unknown !== void 0 && { unknown },
    ...interval !== void 0 && { interval },
    // quantitative
    ...interpolate !== void 0 && { interpolate },
    ...scale2.clamp && { clamp: scale2.clamp() },
    // diverging (always asymmetric; we never want to apply the symmetric transform twice)
    ...pivot !== void 0 && { pivot, symmetric: false },
    // log, diverging-log
    ...scale2.base && { base: scale2.base() },
    // pow, diverging-pow
    ...scale2.exponent && { exponent: scale2.exponent() },
    // symlog, diverging-symlog
    ...scale2.constant && { constant: scale2.constant() },
    // band, point
    ...scale2.align && { align: scale2.align(), round: scale2.round() },
    ...scale2.padding && (scale2.paddingInner ? { paddingInner: scale2.paddingInner(), paddingOuter: scale2.paddingOuter() } : { padding: scale2.padding() }),
    ...scale2.bandwidth && { bandwidth: scale2.bandwidth(), step: scale2.step() },
    // utilities
    apply: (t) => scale2(t),
    ...scale2.invert && { invert: (t) => scale2.invert(t) }
  };
}

// ../../node_modules/@observablehq/plot/dist/projection.js
var pi = Math.PI;
var tau = 2 * pi;
var defaultAspectRatio = 0.618;
function Projection({ projection, inset: globalInset = 0, insetTop = globalInset, insetRight = globalInset, insetBottom = globalInset, insetLeft = globalInset } = {}, dimensions) {
  if (projection == null)
    return;
  if (typeof projection.stream === "function")
    return projection;
  let options;
  let domain;
  let clip = "frame";
  if (isObject(projection)) {
    let inset;
    ({
      type: projection,
      domain,
      inset,
      insetTop = inset !== void 0 ? inset : insetTop,
      insetRight = inset !== void 0 ? inset : insetRight,
      insetBottom = inset !== void 0 ? inset : insetBottom,
      insetLeft = inset !== void 0 ? inset : insetLeft,
      clip = clip,
      ...options
    } = projection);
    if (projection == null)
      return;
  }
  if (typeof projection !== "function")
    ({ type: projection } = namedProjection(projection));
  const { width, height, marginLeft, marginRight, marginTop, marginBottom } = dimensions;
  const dx = width - marginLeft - marginRight - insetLeft - insetRight;
  const dy = height - marginTop - marginBottom - insetTop - insetBottom;
  projection = projection == null ? void 0 : projection({ width: dx, height: dy, clip, ...options });
  if (projection == null)
    return;
  clip = maybePostClip(clip, marginLeft, marginTop, width - marginRight, height - marginBottom);
  let tx = marginLeft + insetLeft;
  let ty = marginTop + insetTop;
  let transform;
  if (domain != null) {
    const [[x0, y0], [x1, y1]] = path_default(projection).bounds(domain);
    const k = Math.min(dx / (x1 - x0), dy / (y1 - y0));
    if (k > 0) {
      tx -= (k * (x0 + x1) - dx) / 2;
      ty -= (k * (y0 + y1) - dy) / 2;
      transform = transform_default({
        point(x, y) {
          this.stream.point(x * k + tx, y * k + ty);
        }
      });
    } else {
      warn(`Warning: the projection could not be fit to the specified domain; using the default scale.`);
    }
  }
  transform ?? (transform = tx === 0 && ty === 0 ? identity3() : transform_default({
    point(x, y) {
      this.stream.point(x + tx, y + ty);
    }
  }));
  return { stream: (s) => projection.stream(transform.stream(clip(s))) };
}
function namedProjection(projection) {
  switch (`${projection}`.toLowerCase()) {
    case "albers-usa":
      return scaleProjection(albersUsa_default, 0.7463, 0.4673);
    case "albers":
      return conicProjection(albers_default, 0.7463, 0.4673);
    case "azimuthal-equal-area":
      return scaleProjection(azimuthalEqualArea_default, 4, 4);
    case "azimuthal-equidistant":
      return scaleProjection(azimuthalEquidistant_default, tau, tau);
    case "conic-conformal":
      return conicProjection(conicConformal_default, tau, tau);
    case "conic-equal-area":
      return conicProjection(conicEqualArea_default, 6.1702, 2.9781);
    case "conic-equidistant":
      return conicProjection(conicEquidistant_default, 7.312, 3.6282);
    case "equal-earth":
      return scaleProjection(equalEarth_default, 5.4133, 2.6347);
    case "equirectangular":
      return scaleProjection(equirectangular_default, tau, pi);
    case "gnomonic":
      return scaleProjection(gnomonic_default, 3.4641, 3.4641);
    case "identity":
      return { type: identity3 };
    case "reflect-y":
      return { type: reflectY };
    case "mercator":
      return scaleProjection(mercator_default, tau, tau);
    case "orthographic":
      return scaleProjection(orthographic_default, 2, 2);
    case "stereographic":
      return scaleProjection(stereographic_default, 2, 2);
    case "transverse-mercator":
      return scaleProjection(transverseMercator_default, tau, tau);
    default:
      throw new Error(`unknown projection type: ${projection}`);
  }
}
function maybePostClip(clip, x1, y1, x2, y2) {
  if (clip === false || clip == null || typeof clip === "number")
    return (s) => s;
  if (clip === true)
    clip = "frame";
  switch (`${clip}`.toLowerCase()) {
    case "frame":
      return clipRectangle(x1, y1, x2, y2);
    default:
      throw new Error(`unknown projection clip type: ${clip}`);
  }
}
function scaleProjection(createProjection, kx, ky) {
  return {
    type: ({ width, height, rotate, precision = 0.15, clip }) => {
      var _a, _b, _c;
      const projection = createProjection();
      if (precision != null)
        (_a = projection.precision) == null ? void 0 : _a.call(projection, precision);
      if (rotate != null)
        (_b = projection.rotate) == null ? void 0 : _b.call(projection, rotate);
      if (typeof clip === "number")
        (_c = projection.clipAngle) == null ? void 0 : _c.call(projection, clip);
      projection.scale(Math.min(width / kx, height / ky));
      projection.translate([width / 2, height / 2]);
      return projection;
    },
    aspectRatio: ky / kx
  };
}
function conicProjection(createProjection, kx, ky) {
  const { type, aspectRatio } = scaleProjection(createProjection, kx, ky);
  return {
    type: (options) => {
      const { parallels, domain, width, height } = options;
      const projection = type(options);
      if (parallels != null) {
        projection.parallels(parallels);
        if (domain === void 0) {
          projection.fitSize([width, height], { type: "Sphere" });
        }
      }
      return projection;
    },
    aspectRatio
  };
}
var identity3 = constant({ stream: (stream) => stream });
var reflectY = constant(transform_default({
  point(x, y) {
    this.stream.point(x, -y);
  }
}));
function maybeProject(cx, cy, channels, values2, context) {
  const x = channels[cx] && channels[cx].scale === "x";
  const y = channels[cy] && channels[cy].scale === "y";
  if (x && y) {
    project(cx, cy, values2, context.projection);
  } else if (x) {
    throw new Error(`projection requires paired x and y channels; ${cx} is missing ${cy}`);
  } else if (y) {
    throw new Error(`projection requires paired x and y channels; ${cy} is missing ${cx}`);
  }
}
function project(cx, cy, values2, projection) {
  const x = values2[cx];
  const y = values2[cy];
  const n = x.length;
  const X = values2[cx] = new Float64Array(n).fill(NaN);
  const Y = values2[cy] = new Float64Array(n).fill(NaN);
  let i;
  const stream = projection.stream({
    point(x2, y2) {
      X[i] = x2;
      Y[i] = y2;
    }
  });
  for (i = 0; i < n; ++i) {
    stream.point(x[i], y[i]);
  }
}
function projectionAspectRatio(projection, geometry) {
  if (typeof (projection == null ? void 0 : projection.stream) === "function")
    return defaultAspectRatio;
  if (isObject(projection))
    projection = projection.type;
  if (projection == null)
    return geometry ? defaultAspectRatio : void 0;
  if (typeof projection !== "function") {
    const { aspectRatio } = namedProjection(projection);
    if (aspectRatio)
      return aspectRatio;
  }
  return defaultAspectRatio;
}
function Position(channels, scales, context) {
  const { x, y } = channels;
  let position2 = {};
  if (x)
    position2.x = x;
  if (y)
    position2.y = y;
  position2 = valueObject(position2, scales);
  if (context.projection)
    maybeProject("x", "y", channels, position2, context);
  if (x)
    position2.x = coerceNumbers(position2.x);
  if (y)
    position2.y = coerceNumbers(position2.y);
  return position2;
}

// ../../node_modules/@observablehq/plot/dist/context.js
function Context(options = {}, dimensions) {
  const { document = typeof window !== "undefined" ? window.document : void 0 } = options;
  return { document, projection: Projection(options, dimensions) };
}
function create(name, { document }) {
  return select_default(creator_default(name).call(document.documentElement));
}

// ../../node_modules/@observablehq/plot/dist/memoize.js
function memoize1(compute) {
  let cacheValue, cacheKeys;
  return (...keys) => {
    if ((cacheKeys == null ? void 0 : cacheKeys.length) !== keys.length || cacheKeys.some((k, i) => k !== keys[i])) {
      cacheKeys = keys;
      cacheValue = compute(...keys);
    }
    return cacheValue;
  };
}

// ../../node_modules/@observablehq/plot/dist/format.js
var numberFormat = memoize1((locale) => new Intl.NumberFormat(locale));
var monthFormat = memoize1((locale, month) => new Intl.DateTimeFormat(locale, { timeZone: "UTC", ...month && { month } }));
var weekdayFormat = memoize1((locale, weekday) => new Intl.DateTimeFormat(locale, { timeZone: "UTC", ...weekday && { weekday } }));
function formatNumber(locale = "en-US") {
  const format3 = numberFormat(locale);
  return (i) => i != null && !isNaN(i) ? format3.format(i) : void 0;
}
function formatMonth(locale = "en-US", format3 = "short") {
  const fmt = monthFormat(locale, format3);
  return (i) => i != null && !isNaN(i = +new Date(Date.UTC(2e3, +i))) ? fmt.format(i) : void 0;
}
function formatWeekday(locale = "en-US", format3 = "short") {
  const fmt = weekdayFormat(locale, format3);
  return (i) => i != null && !isNaN(i = +new Date(Date.UTC(2001, 0, +i))) ? fmt.format(i) : void 0;
}
function formatIsoDate(date) {
  return format2(date, "Invalid Date");
}
function formatAuto(locale = "en-US") {
  const number3 = formatNumber(locale);
  return (v) => (v instanceof Date ? formatIsoDate : typeof v === "number" ? number3 : string)(v);
}
var formatDefault = formatAuto();

// ../../node_modules/@observablehq/plot/dist/math.js
var radians = Math.PI / 180;

// ../../node_modules/@observablehq/plot/dist/style.js
var offset = typeof window !== "undefined" && window.devicePixelRatio > 1 ? 0 : 0.5;
var nextClipId = 0;
function getClipId() {
  return `plot-clip-${++nextClipId}`;
}
function styles(mark, { title, href, ariaLabel: variaLabel, ariaDescription, ariaHidden, target, fill, fillOpacity, stroke, strokeWidth, strokeOpacity, strokeLinejoin, strokeLinecap, strokeMiterlimit, strokeDasharray, strokeDashoffset, opacity: opacity2, mixBlendMode, paintOrder, pointerEvents, shapeRendering }, { ariaLabel: cariaLabel, fill: defaultFill = "currentColor", fillOpacity: defaultFillOpacity, stroke: defaultStroke = "none", strokeOpacity: defaultStrokeOpacity, strokeWidth: defaultStrokeWidth, strokeLinecap: defaultStrokeLinecap, strokeLinejoin: defaultStrokeLinejoin, strokeMiterlimit: defaultStrokeMiterlimit, paintOrder: defaultPaintOrder }) {
  if (defaultFill === null) {
    fill = null;
    fillOpacity = null;
  }
  if (defaultStroke === null) {
    stroke = null;
    strokeOpacity = null;
  }
  if (isNoneish(defaultFill)) {
    if (!isNoneish(defaultStroke) && !isNoneish(fill))
      defaultStroke = "none";
  } else {
    if (isNoneish(defaultStroke) && !isNoneish(stroke))
      defaultFill = "none";
  }
  const [vfill, cfill] = maybeColorChannel(fill, defaultFill);
  const [vfillOpacity, cfillOpacity] = maybeNumberChannel(fillOpacity, defaultFillOpacity);
  const [vstroke, cstroke] = maybeColorChannel(stroke, defaultStroke);
  const [vstrokeOpacity, cstrokeOpacity] = maybeNumberChannel(strokeOpacity, defaultStrokeOpacity);
  const [vopacity, copacity] = maybeNumberChannel(opacity2);
  if (!isNone(cstroke)) {
    if (strokeWidth === void 0)
      strokeWidth = defaultStrokeWidth;
    if (strokeLinecap === void 0)
      strokeLinecap = defaultStrokeLinecap;
    if (strokeLinejoin === void 0)
      strokeLinejoin = defaultStrokeLinejoin;
    if (strokeMiterlimit === void 0 && !isRound(strokeLinejoin))
      strokeMiterlimit = defaultStrokeMiterlimit;
    if (!isNone(cfill) && paintOrder === void 0)
      paintOrder = defaultPaintOrder;
  }
  const [vstrokeWidth, cstrokeWidth] = maybeNumberChannel(strokeWidth);
  if (defaultFill !== null) {
    mark.fill = impliedString(cfill, "currentColor");
    mark.fillOpacity = impliedNumber(cfillOpacity, 1);
  }
  if (defaultStroke !== null) {
    mark.stroke = impliedString(cstroke, "none");
    mark.strokeWidth = impliedNumber(cstrokeWidth, 1);
    mark.strokeOpacity = impliedNumber(cstrokeOpacity, 1);
    mark.strokeLinejoin = impliedString(strokeLinejoin, "miter");
    mark.strokeLinecap = impliedString(strokeLinecap, "butt");
    mark.strokeMiterlimit = impliedNumber(strokeMiterlimit, 4);
    mark.strokeDasharray = impliedString(strokeDasharray, "none");
    mark.strokeDashoffset = impliedString(strokeDashoffset, "0");
  }
  mark.target = string(target);
  mark.ariaLabel = string(cariaLabel);
  mark.ariaDescription = string(ariaDescription);
  mark.ariaHidden = string(ariaHidden);
  mark.opacity = impliedNumber(copacity, 1);
  mark.mixBlendMode = impliedString(mixBlendMode, "normal");
  mark.paintOrder = impliedString(paintOrder, "normal");
  mark.pointerEvents = impliedString(pointerEvents, "auto");
  mark.shapeRendering = impliedString(shapeRendering, "auto");
  return {
    title: { value: title, optional: true },
    href: { value: href, optional: true },
    ariaLabel: { value: variaLabel, optional: true },
    fill: { value: vfill, scale: "color", optional: true },
    fillOpacity: { value: vfillOpacity, scale: "opacity", optional: true },
    stroke: { value: vstroke, scale: "color", optional: true },
    strokeOpacity: { value: vstrokeOpacity, scale: "opacity", optional: true },
    strokeWidth: { value: vstrokeWidth, optional: true },
    opacity: { value: vopacity, scale: "opacity", optional: true }
  };
}
function applyTitle(selection, L) {
  if (L)
    selection.filter((i) => nonempty(L[i])).append("title").call(applyText, L);
}
function applyTitleGroup(selection, L) {
  if (L)
    selection.filter(([i]) => nonempty(L[i])).append("title").call(applyTextGroup, L);
}
function applyText(selection, T) {
  if (T)
    selection.text((i) => formatDefault(T[i]));
}
function applyTextGroup(selection, T) {
  if (T)
    selection.text(([i]) => formatDefault(T[i]));
}
function applyChannelStyles(selection, { target }, { ariaLabel: AL, title: T, fill: F, fillOpacity: FO, stroke: S, strokeOpacity: SO, strokeWidth: SW, opacity: O, href: H }) {
  if (AL)
    applyAttr(selection, "aria-label", (i) => AL[i]);
  if (F)
    applyAttr(selection, "fill", (i) => F[i]);
  if (FO)
    applyAttr(selection, "fill-opacity", (i) => FO[i]);
  if (S)
    applyAttr(selection, "stroke", (i) => S[i]);
  if (SO)
    applyAttr(selection, "stroke-opacity", (i) => SO[i]);
  if (SW)
    applyAttr(selection, "stroke-width", (i) => SW[i]);
  if (O)
    applyAttr(selection, "opacity", (i) => O[i]);
  if (H)
    applyHref(selection, (i) => H[i], target);
  applyTitle(selection, T);
}
function applyGroupedChannelStyles(selection, { target }, { ariaLabel: AL, title: T, fill: F, fillOpacity: FO, stroke: S, strokeOpacity: SO, strokeWidth: SW, opacity: O, href: H }) {
  if (AL)
    applyAttr(selection, "aria-label", ([i]) => AL[i]);
  if (F)
    applyAttr(selection, "fill", ([i]) => F[i]);
  if (FO)
    applyAttr(selection, "fill-opacity", ([i]) => FO[i]);
  if (S)
    applyAttr(selection, "stroke", ([i]) => S[i]);
  if (SO)
    applyAttr(selection, "stroke-opacity", ([i]) => SO[i]);
  if (SW)
    applyAttr(selection, "stroke-width", ([i]) => SW[i]);
  if (O)
    applyAttr(selection, "opacity", ([i]) => O[i]);
  if (H)
    applyHref(selection, ([i]) => H[i], target);
  applyTitleGroup(selection, T);
}
function groupAesthetics({ ariaLabel: AL, title: T, fill: F, fillOpacity: FO, stroke: S, strokeOpacity: SO, strokeWidth: SW, opacity: O, href: H }) {
  return [AL, T, F, FO, S, SO, SW, O, H].filter((c) => c !== void 0);
}
function groupZ2(I, Z, z) {
  const G = group(I, (i) => Z[i]);
  if (z === void 0 && G.size > I.length >> 1) {
    warn(`Warning: the implicit z channel has high cardinality. This may occur when the fill or stroke channel is associated with quantitative data rather than ordinal or categorical data. You can suppress this warning by setting the z option explicitly; if this data represents a single series, set z to null.`);
  }
  return G.values();
}
function* groupIndex(I, position2, { z }, channels) {
  const { z: Z } = channels;
  const A = groupAesthetics(channels);
  const C = [...position2, ...A];
  for (const G of Z ? groupZ2(I, Z, z) : [I]) {
    let Ag;
    let Gg;
    out:
      for (const i of G) {
        for (const c of C) {
          if (!defined(c[i])) {
            if (Gg)
              Gg.push(-1);
            continue out;
          }
        }
        if (Ag === void 0) {
          if (Gg)
            yield Gg;
          Ag = A.map((c) => keyof(c[i])), Gg = [i];
          continue;
        }
        Gg.push(i);
        for (let j = 0; j < A.length; ++j) {
          const k = keyof(A[j][i]);
          if (k !== Ag[j]) {
            yield Gg;
            Ag = A.map((c) => keyof(c[i])), Gg = [i];
            continue out;
          }
        }
      }
    if (Gg)
      yield Gg;
  }
}
function maybeClip(clip) {
  if (clip === true)
    clip = "frame";
  else if (clip === false)
    clip = null;
  return maybeKeyword(clip, "clip", ["frame", "sphere"]);
}
function applyClip(selection, mark, dimensions, context) {
  let clipUrl;
  switch (mark.clip) {
    case "frame": {
      const { width, height, marginLeft, marginRight, marginTop, marginBottom } = dimensions;
      const id = getClipId();
      clipUrl = `url(#${id})`;
      selection = create("svg:g", context).call((g) => g.append("svg:clipPath").attr("id", id).append("rect").attr("x", marginLeft).attr("y", marginTop).attr("width", width - marginRight - marginLeft).attr("height", height - marginTop - marginBottom)).each(function() {
        this.appendChild(selection.node());
        selection.node = () => this;
      });
      break;
    }
    case "sphere": {
      const { projection } = context;
      if (!projection)
        throw new Error(`the "sphere" clip option requires a projection`);
      const id = getClipId();
      clipUrl = `url(#${id})`;
      selection.append("clipPath").attr("id", id).append("path").attr("d", path_default(projection)({ type: "Sphere" }));
      break;
    }
  }
  applyAttr(selection, "aria-label", mark.ariaLabel);
  applyAttr(selection, "aria-description", mark.ariaDescription);
  applyAttr(selection, "aria-hidden", mark.ariaHidden);
  applyAttr(selection, "clip-path", clipUrl);
}
function applyIndirectStyles(selection, mark, dimensions, context) {
  applyClip(selection, mark, dimensions, context);
  applyAttr(selection, "fill", mark.fill);
  applyAttr(selection, "fill-opacity", mark.fillOpacity);
  applyAttr(selection, "stroke", mark.stroke);
  applyAttr(selection, "stroke-width", mark.strokeWidth);
  applyAttr(selection, "stroke-opacity", mark.strokeOpacity);
  applyAttr(selection, "stroke-linejoin", mark.strokeLinejoin);
  applyAttr(selection, "stroke-linecap", mark.strokeLinecap);
  applyAttr(selection, "stroke-miterlimit", mark.strokeMiterlimit);
  applyAttr(selection, "stroke-dasharray", mark.strokeDasharray);
  applyAttr(selection, "stroke-dashoffset", mark.strokeDashoffset);
  applyAttr(selection, "shape-rendering", mark.shapeRendering);
  applyAttr(selection, "paint-order", mark.paintOrder);
  applyAttr(selection, "pointer-events", mark.pointerEvents);
}
function applyDirectStyles(selection, mark) {
  applyStyle(selection, "mix-blend-mode", mark.mixBlendMode);
  applyAttr(selection, "opacity", mark.opacity);
}
function applyHref(selection, href, target) {
  selection.each(function(i) {
    const h = href(i);
    if (h != null) {
      const a = this.ownerDocument.createElementNS(namespaces_default.svg, "a");
      a.setAttribute("fill", "inherit");
      a.setAttributeNS(namespaces_default.xlink, "href", h);
      if (target != null)
        a.setAttribute("target", target);
      this.parentNode.insertBefore(a, this).appendChild(this);
    }
  });
}
function applyAttr(selection, name, value) {
  if (value != null)
    selection.attr(name, value);
}
function applyStyle(selection, name, value) {
  if (value != null)
    selection.style(name, value);
}
function applyTransform(selection, mark, { x, y }, tx = offset, ty = offset) {
  tx += mark.dx;
  ty += mark.dy;
  if (x == null ? void 0 : x.bandwidth)
    tx += x.bandwidth() / 2;
  if (y == null ? void 0 : y.bandwidth)
    ty += y.bandwidth() / 2;
  if (tx || ty)
    selection.attr("transform", `translate(${tx},${ty})`);
}
function impliedString(value, impliedValue) {
  if ((value = string(value)) !== impliedValue)
    return value;
}
function impliedNumber(value, impliedValue) {
  if ((value = number(value)) !== impliedValue)
    return value;
}
var validClassName = /^-?([_a-z]|[\240-\377]|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])([_a-z0-9-]|[\240-\377]|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])*$/;
function maybeClassName(name) {
  if (name === void 0)
    return `plot-${Math.random().toString(16).slice(2)}`;
  name = `${name}`;
  if (!validClassName.test(name))
    throw new Error(`invalid class name: ${name}`);
  return name;
}
function applyInlineStyles(selection, style) {
  if (typeof style === "string") {
    selection.property("style", style);
  } else if (style != null) {
    for (const element of selection) {
      Object.assign(element.style, style);
    }
  }
}
function applyFrameAnchor({ frameAnchor }, { width, height, marginTop, marginRight, marginBottom, marginLeft }) {
  return [
    /left$/.test(frameAnchor) ? marginLeft : /right$/.test(frameAnchor) ? width - marginRight : (marginLeft + width - marginRight) / 2,
    /^top/.test(frameAnchor) ? marginTop : /^bottom/.test(frameAnchor) ? height - marginBottom : (marginTop + height - marginBottom) / 2
  ];
}

// ../../node_modules/@observablehq/plot/dist/axis.js
var AxisX = class {
  constructor(scale2, { name = "x", axis, ticks: ticks2, tickSize = name === "fx" ? 0 : 6, tickPadding = tickSize === 0 ? 9 : 3, tickFormat, fontVariant = inferFontVariant(scale2), grid, label, labelAnchor, labelOffset, line: line2, tickRotate, ariaLabel, ariaDescription } = {}) {
    this.name = name;
    this.axis = keyword(axis, "axis", ["top", "bottom"]);
    this.ticks = maybeTicks(ticks2, scale2);
    this.tickSize = number(tickSize);
    this.tickPadding = number(tickPadding);
    this.tickFormat = maybeTickFormat(tickFormat);
    this.fontVariant = impliedString(fontVariant, "normal");
    this.grid = boolean(grid);
    this.label = string(label);
    this.labelAnchor = maybeKeyword(labelAnchor, "labelAnchor", ["center", "left", "right"]);
    this.labelOffset = number(labelOffset);
    this.line = boolean(line2);
    this.tickRotate = number(tickRotate);
    this.ariaLabel = string(ariaLabel);
    this.ariaDescription = string(ariaDescription);
  }
  render(index, { [this.name]: x, fy }, { width, height, marginTop, marginRight, marginBottom, marginLeft, offsetLeft = 0, facetMarginTop, facetMarginBottom, labelMarginLeft = 0, labelMarginRight = 0 }, context) {
    const { axis, fontVariant, grid, label, labelAnchor, labelOffset, line: line2, name, tickRotate } = this;
    const offset2 = name === "x" ? 0 : axis === "top" ? marginTop - facetMarginTop : marginBottom - facetMarginBottom;
    const offsetSign = axis === "top" ? -1 : 1;
    const ty = offsetSign * offset2 + (axis === "top" ? marginTop : height - marginBottom);
    return create("svg:g", context).call(applyAria, this).attr("transform", `translate(${offsetLeft},${ty})`).call(createAxis(axis === "top" ? axisTop : axisBottom, x, this)).call(maybeTickRotate, tickRotate).attr("font-size", null).attr("font-family", null).attr("font-variant", fontVariant).call(!line2 ? (g) => g.select(".domain").remove() : () => {
    }).call(!grid ? () => {
    } : fy ? gridFacetX(index, fy, -ty) : gridX(offsetSign * (marginBottom + marginTop - height))).call(!label ? () => {
    } : (g) => g.append("text").attr("fill", "currentColor").attr("transform", `translate(${labelAnchor === "center" ? (width + marginLeft - marginRight) / 2 : labelAnchor === "right" ? width + labelMarginRight : -labelMarginLeft},${labelOffset * offsetSign})`).attr("dy", axis === "top" ? "1em" : "-0.32em").attr("text-anchor", labelAnchor === "center" ? "middle" : labelAnchor === "right" ? "end" : "start").text(label)).node();
  }
};
var AxisY = class {
  constructor(scale2, { name = "y", axis, ticks: ticks2, tickSize = name === "fy" ? 0 : 6, tickPadding = tickSize === 0 ? 9 : 3, tickFormat, fontVariant = inferFontVariant(scale2), grid, label, labelAnchor, labelOffset, line: line2, tickRotate, ariaLabel, ariaDescription } = {}) {
    this.name = name;
    this.axis = keyword(axis, "axis", ["left", "right"]);
    this.ticks = maybeTicks(ticks2, scale2);
    this.tickSize = number(tickSize);
    this.tickPadding = number(tickPadding);
    this.tickFormat = maybeTickFormat(tickFormat);
    this.fontVariant = impliedString(fontVariant, "normal");
    this.grid = boolean(grid);
    this.label = string(label);
    this.labelAnchor = maybeKeyword(labelAnchor, "labelAnchor", ["center", "top", "bottom"]);
    this.labelOffset = number(labelOffset);
    this.line = boolean(line2);
    this.tickRotate = number(tickRotate);
    this.ariaLabel = string(ariaLabel);
    this.ariaDescription = string(ariaDescription);
  }
  render(index, { [this.name]: y, fx }, { width, height, marginTop, marginRight, marginBottom, marginLeft, offsetTop = 0, facetMarginLeft, facetMarginRight }, context) {
    const { axis, fontVariant, grid, label, labelAnchor, labelOffset, line: line2, name, tickRotate } = this;
    const offset2 = name === "y" ? 0 : axis === "left" ? marginLeft - facetMarginLeft : marginRight - facetMarginRight;
    const offsetSign = axis === "left" ? -1 : 1;
    const tx = offsetSign * offset2 + (axis === "right" ? width - marginRight : marginLeft);
    return create("svg:g", context).call(applyAria, this).attr("transform", `translate(${tx},${offsetTop})`).call(createAxis(axis === "right" ? axisRight : axisLeft, y, this)).call(maybeTickRotate, tickRotate).attr("font-size", null).attr("font-family", null).attr("font-variant", fontVariant).call(!line2 ? (g) => g.select(".domain").remove() : () => {
    }).call(!grid ? () => {
    } : fx ? gridFacetY(index, fx, -tx) : gridY(offsetSign * (marginLeft + marginRight - width))).call(!label ? () => {
    } : (g) => g.append("text").attr("fill", "currentColor").attr("font-variant", fontVariant == null ? null : "normal").attr("transform", `translate(${labelOffset * offsetSign},${labelAnchor === "center" ? (height + marginTop - marginBottom) / 2 : labelAnchor === "bottom" ? height - marginBottom : marginTop})${labelAnchor === "center" ? ` rotate(-90)` : ""}`).attr("dy", labelAnchor === "center" ? axis === "right" ? "-0.32em" : "0.75em" : labelAnchor === "bottom" ? "1.4em" : "-1em").attr("text-anchor", labelAnchor === "center" ? "middle" : axis === "right" ? "end" : "start").text(label)).node();
  }
};
function applyAria(selection, { name, label, ariaLabel = `${name}-axis`, ariaDescription = label }) {
  applyAttr(selection, "aria-label", ariaLabel);
  applyAttr(selection, "aria-description", ariaDescription);
}
function gridX(y2) {
  return (g) => g.selectAll(".tick line").clone(true).attr("stroke-opacity", 0.1).attr("y2", y2);
}
function gridY(x2) {
  return (g) => g.selectAll(".tick line").clone(true).attr("stroke-opacity", 0.1).attr("x2", x2);
}
function gridFacetX(index, fy, ty) {
  const dy = fy.bandwidth();
  const domain = fy.domain();
  return (g) => g.selectAll(".tick").append("path").attr("stroke", "currentColor").attr("stroke-opacity", 0.1).attr("d", (index ? take(domain, index) : domain).map((v) => `M0,${fy(v) + ty}v${dy}`).join(""));
}
function gridFacetY(index, fx, tx) {
  const dx = fx.bandwidth();
  const domain = fx.domain();
  return (g) => g.selectAll(".tick").append("path").attr("stroke", "currentColor").attr("stroke-opacity", 0.1).attr("d", (index ? take(domain, index) : domain).map((v) => `M${fx(v) + tx},0h${dx}`).join(""));
}
function maybeTicks(ticks2, scale2) {
  return ticks2 === null ? [] : isTemporalScale(scale2) && typeof ticks2 === "string" ? (scale2.type === "time" ? maybeTimeInterval : maybeUtcInterval)(ticks2) : ticks2;
}
function maybeTickFormat(tickFormat) {
  return tickFormat === null ? () => null : tickFormat;
}
function maybeAutoTickFormat(tickFormat, domain) {
  return tickFormat === void 0 ? isTemporal(domain) ? formatIsoDate : string : typeof tickFormat === "function" ? tickFormat : (typeof tickFormat === "string" ? isTemporal(domain) ? utcFormat : format : constant)(tickFormat);
}
function createAxis(axis, scale2, { ticks: ticks2, tickSize, tickPadding, tickFormat }) {
  if (!scale2.tickFormat) {
    tickFormat = maybeAutoTickFormat(tickFormat, scale2.domain());
  }
  return axis(scale2).ticks(Array.isArray(ticks2) ? null : ticks2, typeof tickFormat === "function" ? null : tickFormat).tickFormat(typeof tickFormat === "function" ? tickFormat : null).tickSizeInner(tickSize).tickSizeOuter(0).tickPadding(tickPadding).tickValues(Array.isArray(ticks2) ? ticks2 : null);
}
function maybeTickRotate(g, rotate) {
  if (!(rotate = +rotate))
    return;
  for (const text2 of g.selectAll("text")) {
    const x = +text2.getAttribute("x");
    const y = +text2.getAttribute("y");
    if (Math.abs(y) > Math.abs(x)) {
      const s = Math.sign(y);
      text2.setAttribute("transform", `translate(0, ${y + s * 4 * Math.cos(rotate * radians)}) rotate(${rotate})`);
      text2.setAttribute("text-anchor", Math.abs(rotate) < 10 ? "middle" : rotate < 0 ^ s > 0 ? "start" : "end");
    } else {
      const s = Math.sign(x);
      text2.setAttribute("transform", `translate(${x + s * 4 * Math.abs(Math.sin(rotate * radians))}, 0) rotate(${rotate})`);
      text2.setAttribute("text-anchor", Math.abs(rotate) > 60 ? "middle" : s > 0 ? "start" : "end");
    }
    text2.removeAttribute("x");
    text2.removeAttribute("y");
    text2.setAttribute("dy", "0.32em");
  }
}
function inferFontVariant(scale2) {
  return isOrdinalScale(scale2) && scale2.interval === void 0 ? void 0 : "tabular-nums";
}

// ../../node_modules/@observablehq/plot/dist/axes.js
function Axes({ x: xScale, y: yScale, fx: fxScale, fy: fyScale }, { x = {}, y = {}, fx = {}, fy = {}, axis = true, grid, line: line2, label, facet: { axis: facetAxis = axis, grid: facetGrid, label: facetLabel = label } = {} } = {}) {
  let { axis: xAxis = axis } = x;
  let { axis: yAxis = axis } = y;
  let { axis: fxAxis = facetAxis } = fx;
  let { axis: fyAxis = facetAxis } = fy;
  if (!xScale)
    xAxis = null;
  else if (xAxis === true)
    xAxis = "bottom";
  if (!yScale)
    yAxis = null;
  else if (yAxis === true)
    yAxis = "left";
  if (!fxScale)
    fxAxis = null;
  else if (fxAxis === true)
    fxAxis = xAxis === "bottom" ? "top" : "bottom";
  if (!fyScale)
    fyAxis = null;
  else if (fyAxis === true)
    fyAxis = yAxis === "left" ? "right" : "left";
  return {
    ...xAxis && { x: new AxisX(xScale, { grid, line: line2, label, ...x, axis: xAxis }) },
    ...yAxis && { y: new AxisY(yScale, { grid, line: line2, label, ...y, axis: yAxis }) },
    ...fxAxis && { fx: new AxisX(fxScale, { name: "fx", grid: facetGrid, label: facetLabel, ...fx, axis: fxAxis }) },
    ...fyAxis && { fy: new AxisY(fyScale, { name: "fy", grid: facetGrid, label: facetLabel, ...fy, axis: fyAxis }) }
  };
}
function autoAxisTicks({ x, y, fx, fy }, { x: xAxis, y: yAxis, fx: fxAxis, fy: fyAxis }) {
  if (fxAxis)
    autoAxisTicksK(fx, fxAxis, 80);
  if (fyAxis)
    autoAxisTicksK(fy, fyAxis, 35);
  if (xAxis)
    autoAxisTicksK(x, xAxis, 80);
  if (yAxis)
    autoAxisTicksK(y, yAxis, 35);
}
function autoAxisTicksK(scale2, axis, k) {
  if (axis.ticks === void 0) {
    const interval = scale2.interval;
    if (interval !== void 0) {
      const [min2, max2] = extent(scale2.scale.domain());
      axis.ticks = interval.range(interval.floor(min2), interval.offset(interval.floor(max2)));
    } else {
      const [min2, max2] = extent(scale2.scale.range());
      axis.ticks = (max2 - min2) / k;
    }
  }
  if (axis.tickFormat === void 0 && isOrdinalScale(scale2)) {
    axis.tickFormat = formatDefault;
  }
}
function autoScaleLabels(channels, scales, { x, y, fx, fy }, dimensions, options) {
  if (fx) {
    autoAxisLabelsX(fx, scales.fx, channels.get("fx"));
    if (fx.labelOffset === void 0) {
      const { facetMarginTop, facetMarginBottom } = dimensions;
      fx.labelOffset = fx.axis === "top" ? facetMarginTop : facetMarginBottom;
    }
  }
  if (fy) {
    autoAxisLabelsY(fy, fx, scales.fy, channels.get("fy"));
    if (fy.labelOffset === void 0) {
      const { facetMarginLeft, facetMarginRight } = dimensions;
      fy.labelOffset = fy.axis === "left" ? facetMarginLeft : facetMarginRight;
    }
  }
  if (x) {
    autoAxisLabelsX(x, scales.x, channels.get("x"));
    if (x.labelOffset === void 0) {
      const { marginTop, marginBottom, facetMarginTop, facetMarginBottom } = dimensions;
      x.labelOffset = x.axis === "top" ? marginTop - facetMarginTop : marginBottom - facetMarginBottom;
    }
  }
  if (y) {
    autoAxisLabelsY(y, x, scales.y, channels.get("y"));
    if (y.labelOffset === void 0) {
      const { marginRight, marginLeft, facetMarginLeft, facetMarginRight } = dimensions;
      y.labelOffset = y.axis === "left" ? marginLeft - facetMarginLeft : marginRight - facetMarginRight;
    }
  }
  for (const [key, type] of registry) {
    if (type !== position && scales[key]) {
      autoScaleLabel(key, scales[key], channels.get(key), options[key]);
    }
  }
}
function autoAxisLabelsX(axis, scale2, channels) {
  if (axis.labelAnchor === void 0) {
    axis.labelAnchor = isOrdinalScale(scale2) ? "center" : scaleOrder(scale2) < 0 ? "left" : "right";
  }
  if (axis.label === void 0) {
    axis.label = inferLabel(channels, scale2, axis, "x");
  }
  scale2.label = axis.label;
}
function autoAxisLabelsY(axis, opposite, scale2, channels) {
  if (axis.labelAnchor === void 0) {
    axis.labelAnchor = isOrdinalScale(scale2) ? "center" : opposite && opposite.axis === "top" ? "bottom" : "top";
  }
  if (axis.label === void 0) {
    axis.label = inferLabel(channels, scale2, axis, "y");
  }
  scale2.label = axis.label;
}
function autoScaleLabel(key, scale2, channels, options) {
  if (options) {
    scale2.label = options.label;
  }
  if (scale2.label === void 0) {
    scale2.label = inferLabel(channels, scale2, null, key);
  }
}
function inferLabel(channels = [], scale2, axis, key) {
  let candidate;
  for (const { label } of channels) {
    if (label === void 0)
      continue;
    if (candidate === void 0)
      candidate = label;
    else if (candidate !== label)
      return;
  }
  if (candidate !== void 0) {
    if (isTemporalScale(scale2) && /^(date|time|year)$/i.test(candidate))
      return;
    if (!isOrdinalScale(scale2)) {
      if (scale2.percent)
        candidate = `${candidate} (%)`;
      if (key === "x" || key === "y") {
        const order2 = scaleOrder(scale2);
        if (order2) {
          if (key === "x" || axis && axis.labelAnchor === "center") {
            candidate = key === "x" === order2 < 0 ? `← ${candidate}` : `${candidate} →`;
          } else {
            candidate = `${order2 < 0 ? "↑ " : "↓ "}${candidate}`;
          }
        }
      }
    }
  }
  return candidate;
}

// ../../node_modules/@observablehq/plot/dist/dimensions.js
function Dimensions(scales, geometry, axes, options = {}) {
  const { x: { axis: x } = {}, y: { axis: y } = {}, fx: { axis: fx } = {}, fy: { axis: fy } = {} } = axes;
  let { facet: { margin: facetMargin, marginTop: facetMarginTop = facetMargin !== void 0 ? facetMargin : fx === "top" ? 30 : 0, marginRight: facetMarginRight = facetMargin !== void 0 ? facetMargin : fy === "right" ? 40 : 0, marginBottom: facetMarginBottom = facetMargin !== void 0 ? facetMargin : fx === "bottom" ? 30 : 0, marginLeft: facetMarginLeft = facetMargin !== void 0 ? facetMargin : fy === "left" ? 40 : 0 } = {} } = options;
  facetMarginTop = +facetMarginTop;
  facetMarginRight = +facetMarginRight;
  facetMarginBottom = +facetMarginBottom;
  facetMarginLeft = +facetMarginLeft;
  const marginTopDefault = Math.max((x === "top" ? 30 : 0) + facetMarginTop, y || fy ? 20 : 0.5 - offset);
  const marginBottomDefault = Math.max((x === "bottom" ? 30 : 0) + facetMarginBottom, y || fy ? 20 : 0.5 + offset);
  const marginRightDefault = Math.max((y === "right" ? 40 : 0) + facetMarginRight, x || fx ? 20 : 0.5 + offset);
  const marginLeftDefault = Math.max((y === "left" ? 40 : 0) + facetMarginLeft, x || fx ? 20 : 0.5 - offset);
  let { margin, marginTop = margin !== void 0 ? margin : marginTopDefault, marginRight = margin !== void 0 ? margin : marginRightDefault, marginBottom = margin !== void 0 ? margin : marginBottomDefault, marginLeft = margin !== void 0 ? margin : marginLeftDefault } = options;
  marginTop = +marginTop;
  marginRight = +marginRight;
  marginBottom = +marginBottom;
  marginLeft = +marginLeft;
  let { width = 640, height = autoHeight(scales, geometry, options, {
    width,
    marginTopDefault,
    marginBottomDefault,
    marginRightDefault,
    marginLeftDefault
  }) + Math.max(0, marginTop - marginTopDefault + marginBottom - marginBottomDefault) } = options;
  width = +width;
  height = +height;
  return {
    width,
    height,
    marginTop,
    marginRight,
    marginBottom,
    marginLeft,
    facetMarginTop,
    facetMarginRight,
    facetMarginBottom,
    facetMarginLeft
  };
}
function autoHeight({ y, fy, fx }, geometry, { projection }, { width, marginTopDefault, marginBottomDefault, marginRightDefault, marginLeftDefault }) {
  const nfy = fy ? fy.scale.domain().length : 1;
  const ar = projectionAspectRatio(projection, geometry);
  if (ar) {
    const nfx = fx ? fx.scale.domain().length : 1;
    const far = (1.1 * nfy - 0.1) / (1.1 * nfx - 0.1) * ar;
    const lar = Math.max(0.1, Math.min(10, far));
    return Math.round((width - marginLeftDefault - marginRightDefault) * lar + marginTopDefault + marginBottomDefault);
  }
  const ny = y ? isOrdinalScale(y) ? y.scale.domain().length : Math.max(7, 17 / nfy) : 1;
  return !!(y || fy) * Math.max(1, Math.min(60, ny * nfy)) * 20 + !!fx * 30 + 60;
}

// ../../node_modules/@observablehq/plot/dist/legends/ramp.js
function legendRamp(color3, options) {
  let { label = color3.label, tickSize = 6, width = 240, height = 44 + tickSize, marginTop = 18, marginRight = 0, marginBottom = 16 + tickSize, marginLeft = 0, style, ticks: ticks2 = (width - marginLeft - marginRight) / 64, tickFormat, fontVariant = inferFontVariant(color3), round: round2 = true, className } = options;
  const context = Context(options);
  className = maybeClassName(className);
  if (tickFormat === null)
    tickFormat = () => null;
  const svg = create("svg", context).attr("class", className).attr("font-family", "system-ui, sans-serif").attr("font-size", 10).attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).call((svg2) => svg2.append("style").text(`
        .${className} {
          display: block;
          background: white;
          height: auto;
          height: intrinsic;
          max-width: 100%;
          overflow: visible;
        }
        .${className} text {
          white-space: pre;
        }
      `)).call(applyInlineStyles, style);
  let tickAdjust = (g) => g.selectAll(".tick line").attr("y1", marginTop + marginBottom - height);
  let x;
  const applyRange = round2 ? (x2, range4) => x2.rangeRound(range4) : (x2, range4) => x2.range(range4);
  const { type, domain, range: range3, interpolate, scale: scale2, pivot } = color3;
  if (interpolate) {
    const interpolator = range3 === void 0 ? interpolate : piecewise(interpolate.length === 1 ? interpolatePiecewise(interpolate) : interpolate, range3);
    x = applyRange(scale2.copy(), quantize_default(number_default(marginLeft, width - marginRight), Math.min(domain.length + (pivot !== void 0), range3 === void 0 ? Infinity : range3.length)));
    const n = 256;
    const canvas = context.document.createElement("canvas");
    canvas.width = n;
    canvas.height = 1;
    const context2 = canvas.getContext("2d");
    for (let i = 0, j = n - 1; i < n; ++i) {
      context2.fillStyle = interpolator(i / j);
      context2.fillRect(i, 0, 1, 1);
    }
    svg.append("image").attr("x", marginLeft).attr("y", marginTop).attr("width", width - marginLeft - marginRight).attr("height", height - marginTop - marginBottom).attr("preserveAspectRatio", "none").attr("xlink:href", canvas.toDataURL());
  } else if (type === "threshold") {
    const thresholds = domain;
    const thresholdFormat = tickFormat === void 0 ? (d) => d : typeof tickFormat === "string" ? format(tickFormat) : tickFormat;
    x = applyRange(linear().domain([-1, range3.length - 1]), [marginLeft, width - marginRight]);
    svg.append("g").selectAll().data(range3).enter().append("rect").attr("x", (d, i) => x(i - 1)).attr("y", marginTop).attr("width", (d, i) => x(i) - x(i - 1)).attr("height", height - marginTop - marginBottom).attr("fill", (d) => d);
    ticks2 = map2(thresholds, (_, i) => i);
    tickFormat = (i) => thresholdFormat(thresholds[i], i);
  } else {
    x = applyRange(band().domain(domain), [marginLeft, width - marginRight]);
    svg.append("g").selectAll().data(domain).enter().append("rect").attr("x", x).attr("y", marginTop).attr("width", Math.max(0, x.bandwidth() - 1)).attr("height", height - marginTop - marginBottom).attr("fill", scale2);
    tickAdjust = () => {
    };
  }
  svg.append("g").attr("transform", `translate(0,${height - marginBottom})`).call(axisBottom(x).ticks(Array.isArray(ticks2) ? null : ticks2, typeof tickFormat === "string" ? tickFormat : void 0).tickFormat(typeof tickFormat === "function" ? tickFormat : void 0).tickSize(tickSize).tickValues(Array.isArray(ticks2) ? ticks2 : null)).attr("font-size", null).attr("font-family", null).attr("font-variant", impliedString(fontVariant, "normal")).call(tickAdjust).call((g) => g.select(".domain").remove());
  if (label !== void 0) {
    svg.append("text").attr("x", marginLeft).attr("y", marginTop - 6).attr("fill", "currentColor").attr("font-weight", "bold").text(label);
  }
  return svg.node();
}

// ../../node_modules/@observablehq/plot/dist/legends/swatches.js
function maybeScale(scale2, key) {
  if (key == null)
    return key;
  const s = scale2(key);
  if (!s)
    throw new Error(`scale not found: ${key}`);
  return s;
}
function legendSwatches(color3, options) {
  if (!isOrdinalScale(color3) && !isThresholdScale(color3))
    throw new Error(`swatches legend requires ordinal or threshold color scale (not ${color3.type})`);
  return legendItems(color3, options, (selection, scale2) => selection.append("svg").attr("fill", scale2.scale).append("rect").attr("width", "100%").attr("height", "100%"), (className) => `.${className}-swatch svg {
        width: var(--swatchWidth);
        height: var(--swatchHeight);
        margin-right: 0.5em;
      }`);
}
function legendSymbols(symbol2, { fill = ((_a) => (_a = symbol2.hint) == null ? void 0 : _a.fill)() !== void 0 ? symbol2.hint.fill : "none", fillOpacity = 1, stroke = ((_b) => (_b = symbol2.hint) == null ? void 0 : _b.stroke)() !== void 0 ? symbol2.hint.stroke : isNoneish(fill) ? "currentColor" : "none", strokeOpacity = 1, strokeWidth = 1.5, r = 4.5, ...options } = {}, scale2) {
  const [vf, cf] = maybeColorChannel(fill);
  const [vs, cs] = maybeColorChannel(stroke);
  const sf = maybeScale(scale2, vf);
  const ss = maybeScale(scale2, vs);
  const size = r * r * Math.PI;
  fillOpacity = maybeNumberChannel(fillOpacity)[1];
  strokeOpacity = maybeNumberChannel(strokeOpacity)[1];
  strokeWidth = maybeNumberChannel(strokeWidth)[1];
  return legendItems(symbol2, options, (selection) => selection.append("svg").attr("viewBox", "-8 -8 16 16").attr("fill", vf === "color" ? (d) => sf.scale(d) : null).attr("stroke", vs === "color" ? (d) => ss.scale(d) : null).append("path").attr("d", (d) => {
    const p = pathRound();
    symbol2.scale(d).draw(p, size);
    return p;
  }), (className) => `.${className}-swatch > svg {
        width: var(--swatchWidth);
        height: var(--swatchHeight);
        margin-right: 0.5em;
        overflow: visible;
        fill: ${cf};
        fill-opacity: ${fillOpacity};
        stroke: ${cs};
        stroke-width: ${strokeWidth}px;
        stroke-opacity: ${strokeOpacity};
      }`);
}
function legendItems(scale2, options = {}, swatch, swatchStyle) {
  let {
    columns,
    tickFormat,
    fontVariant = inferFontVariant(scale2),
    // TODO label,
    swatchSize = 15,
    swatchWidth = swatchSize,
    swatchHeight = swatchSize,
    marginLeft = 0,
    className,
    style,
    width
  } = options;
  const context = Context(options);
  className = maybeClassName(className);
  tickFormat = maybeAutoTickFormat(tickFormat, scale2.domain);
  const swatches = create("div", context).attr("class", className).attr("style", `
        --swatchWidth: ${+swatchWidth}px;
        --swatchHeight: ${+swatchHeight}px;
      `);
  let extraStyle;
  if (columns != null) {
    extraStyle = `
      .${className}-swatch {
        display: flex;
        align-items: center;
        break-inside: avoid;
        padding-bottom: 1px;
      }
      .${className}-swatch::before {
        flex-shrink: 0;
      }
      .${className}-label {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    `;
    swatches.style("columns", columns).selectAll().data(scale2.domain).enter().append("div").attr("class", `${className}-swatch`).call(swatch, scale2).call((item) => item.append("div").attr("class", `${className}-label`).attr("title", tickFormat).text(tickFormat));
  } else {
    extraStyle = `
      .${className} {
        display: flex;
        align-items: center;
        min-height: 33px;
        flex-wrap: wrap;
      }
      .${className}-swatch {
        display: inline-flex;
        align-items: center;
        margin-right: 1em;
      }
    `;
    swatches.selectAll().data(scale2.domain).enter().append("span").attr("class", `${className}-swatch`).call(swatch, scale2).append(function() {
      return this.ownerDocument.createTextNode(tickFormat.apply(this, arguments));
    });
  }
  return swatches.call((div) => div.insert("style", "*").text(`
        .${className} {
          font-family: system-ui, sans-serif;
          font-size: 10px;
          margin-bottom: 0.5em;${marginLeft === void 0 ? "" : `
          margin-left: ${+marginLeft}px;`}${width === void 0 ? "" : `
          width: ${width}px;`}
        }
        ${swatchStyle(className)}
        ${extraStyle}
      `)).style("font-variant", impliedString(fontVariant, "normal")).call(applyInlineStyles, style).node();
}

// ../../node_modules/@observablehq/plot/dist/legends.js
var legendRegistry = /* @__PURE__ */ new Map([
  ["symbol", legendSymbols],
  ["color", legendColor],
  ["opacity", legendOpacity]
]);
function legend(options = {}) {
  for (const [key, value] of legendRegistry) {
    const scale2 = options[key];
    if (isScaleOptions(scale2)) {
      const context = Context(options);
      let hint;
      if (key === "symbol") {
        const { fill, stroke = fill === void 0 && isScaleOptions(options.color) ? "color" : void 0 } = options;
        hint = { fill, stroke };
      }
      return value(normalizeScale(key, scale2, hint), legendOptions(context, scale2, options), (key2) => isScaleOptions(options[key2]) ? normalizeScale(key2, options[key2]) : null);
    }
  }
  throw new Error("unknown legend type; no scale found");
}
function exposeLegends(scales, context, defaults21 = {}) {
  return (key, options) => {
    if (!legendRegistry.has(key))
      throw new Error(`unknown legend type: ${key}`);
    if (!(key in scales))
      return;
    return legendRegistry.get(key)(scales[key], legendOptions(context, defaults21[key], options), (key2) => scales[key2]);
  };
}
function legendOptions(context, { label, ticks: ticks2, tickFormat } = {}, options) {
  return inherit(options, context, { label, ticks: ticks2, tickFormat });
}
function legendColor(color3, { legend: legend2 = true, ...options }) {
  if (legend2 === true)
    legend2 = color3.type === "ordinal" ? "swatches" : "ramp";
  if (color3.domain === void 0)
    return;
  switch (`${legend2}`.toLowerCase()) {
    case "swatches":
      return legendSwatches(color3, options);
    case "ramp":
      return legendRamp(color3, options);
    default:
      throw new Error(`unknown legend type: ${legend2}`);
  }
}
function legendOpacity({ type, interpolate, ...scale2 }, { legend: legend2 = true, color: color3 = rgb(0, 0, 0), ...options }) {
  if (!interpolate)
    throw new Error(`${type} opacity scales are not supported`);
  if (legend2 === true)
    legend2 = "ramp";
  if (`${legend2}`.toLowerCase() !== "ramp")
    throw new Error(`${legend2} opacity legends are not supported`);
  return legendColor({ type, ...scale2, interpolate: interpolateOpacity(color3) }, { legend: legend2, ...options });
}
function interpolateOpacity(color3) {
  const { r, g, b } = rgb(color3) || rgb(0, 0, 0);
  return (t) => `rgba(${r},${g},${b},${t})`;
}
function Legends(scales, context, options) {
  const legends = [];
  for (const [key, value] of legendRegistry) {
    const o = options[key];
    if ((o == null ? void 0 : o.legend) && key in scales) {
      const legend2 = value(scales[key], legendOptions(context, scales[key], o), (key2) => scales[key2]);
      if (legend2 != null)
        legends.push(legend2);
    }
  }
  return legends;
}

// ../../node_modules/@observablehq/plot/dist/plot.js
function plot(options = {}) {
  const { facet, style, caption, ariaLabel, ariaDescription } = options;
  const className = maybeClassName(options.className);
  const marks2 = options.marks === void 0 ? [] : options.marks.flat(Infinity).map(markify);
  const topFacetState = maybeTopFacet(facet, options);
  const facetStateByMark = /* @__PURE__ */ new Map();
  for (const mark of marks2) {
    const facetState = maybeMarkFacet(mark, topFacetState, options);
    if (facetState)
      facetStateByMark.set(mark, facetState);
  }
  const channelsByScale = /* @__PURE__ */ new Map();
  if (topFacetState)
    addScaleChannels(channelsByScale, [topFacetState]);
  addScaleChannels(channelsByScale, facetStateByMark);
  let facets = Facets(channelsByScale, options);
  if (facets !== void 0) {
    const topFacetsIndex = topFacetState ? filterFacets(facets, topFacetState) : void 0;
    for (const mark of marks2) {
      if (mark.facet === null)
        continue;
      const facetState = facetStateByMark.get(mark);
      if (facetState === void 0)
        continue;
      facetState.facetsIndex = mark.fx != null || mark.fy != null ? filterFacets(facets, facetState) : topFacetsIndex;
    }
    const nonEmpty = /* @__PURE__ */ new Set();
    for (const { facetsIndex } of facetStateByMark.values()) {
      facetsIndex == null ? void 0 : facetsIndex.forEach((index, i) => {
        if ((index == null ? void 0 : index.length) > 0) {
          nonEmpty.add(i);
        }
      });
    }
    if (0 < nonEmpty.size && nonEmpty.size < facets.length) {
      facets = facets.filter((_, i) => nonEmpty.has(i));
      for (const state of facetStateByMark.values()) {
        const { facetsIndex } = state;
        if (!facetsIndex)
          continue;
        state.facetsIndex = facetsIndex.filter((_, i) => nonEmpty.has(i));
      }
    }
    for (const mark of marks2) {
      if (mark.facet === "exclude") {
        const facetState = facetStateByMark.get(mark);
        facetState.facetsIndex = excludeIndex(facetState.facetsIndex);
      }
    }
  }
  for (const key of registry.keys()) {
    if (isScaleOptions(options[key]) && key !== "fx" && key !== "fy") {
      channelsByScale.set(key, []);
    }
  }
  const stateByMark = /* @__PURE__ */ new Map();
  for (const mark of marks2) {
    if (stateByMark.has(mark))
      throw new Error("duplicate mark; each mark must be unique");
    const { facetsIndex, channels: facetChannels } = facetStateByMark.get(mark) || {};
    const { data, facets: facets2, channels } = mark.initialize(facetsIndex, facetChannels);
    applyScaleTransforms(channels, options);
    stateByMark.set(mark, { data, facets: facets2, channels });
  }
  const scaleDescriptors = Scales(addScaleChannels(channelsByScale, stateByMark), options);
  const scales = ScaleFunctions(scaleDescriptors);
  const axes = Axes(scaleDescriptors, options);
  const dimensions = Dimensions(scaleDescriptors, hasGeometry(stateByMark), axes, options);
  autoScaleRange(scaleDescriptors, dimensions);
  autoAxisTicks(scaleDescriptors, axes);
  const { fx, fy } = scales;
  const fyMargins = fy && { marginTop: 0, marginBottom: 0, height: fy.bandwidth() };
  const fxMargins = fx && { marginRight: 0, marginLeft: 0, width: fx.bandwidth() };
  const subdimensions = { ...dimensions, ...fxMargins, ...fyMargins };
  const context = Context(options, subdimensions);
  const newByScale = /* @__PURE__ */ new Set();
  for (const [mark, state] of stateByMark) {
    if (mark.initializer != null) {
      const { facets: facets2, channels } = mark.initializer(state.data, state.facets, state.channels, scales, subdimensions, context);
      if (facets2 !== void 0) {
        state.facets = facets2;
      }
      if (channels !== void 0) {
        inferChannelScale(channels, mark);
        applyScaleTransforms(channels, options);
        Object.assign(state.channels, channels);
        for (const { scale: scale2 } of Object.values(channels))
          if (scale2 != null)
            newByScale.add(scale2);
      }
    }
  }
  if (newByScale.size) {
    for (const key of newByScale) {
      if (registry.get(key) === position) {
        throw new Error(`initializers cannot declare position scales: ${key}`);
      }
    }
    const newChannelsByScale = /* @__PURE__ */ new Map();
    addScaleChannels(newChannelsByScale, stateByMark, (key) => newByScale.has(key));
    addScaleChannels(channelsByScale, stateByMark, (key) => newByScale.has(key));
    const newScaleDescriptors = Scales(newChannelsByScale, options);
    const newScales = ScaleFunctions(newScaleDescriptors);
    Object.assign(scaleDescriptors, newScaleDescriptors);
    Object.assign(scales, newScales);
  }
  autoScaleLabels(channelsByScale, scaleDescriptors, axes, dimensions, options);
  for (const [mark, state] of stateByMark) {
    state.values = mark.scale(state.channels, scales, context);
  }
  const { width, height } = dimensions;
  const svg = create("svg", context).attr("class", className).attr("fill", "currentColor").attr("font-family", "system-ui, sans-serif").attr("font-size", 10).attr("text-anchor", "middle").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("aria-label", ariaLabel).attr("aria-description", ariaDescription).call((svg2) => svg2.append("style").text(`
        .${className} {
          display: block;
          background: white;
          height: auto;
          height: intrinsic;
          max-width: 100%;
        }
        .${className} text,
        .${className} tspan {
          white-space: pre;
        }
      `)).call(applyInlineStyles, style).node();
  const axisY = axes[facets !== void 0 && fy ? "fy" : "y"];
  const axisX = axes[facets !== void 0 && fx ? "fx" : "x"];
  if (axisY)
    svg.appendChild(axisY.render(null, scales, dimensions, context));
  if (axisX)
    svg.appendChild(axisX.render(null, scales, dimensions, context));
  if (facets !== void 0) {
    const fxDomain = fx == null ? void 0 : fx.domain();
    const fyDomain = fy == null ? void 0 : fy.domain();
    const selection = select_default(svg);
    const fxy = fx && fy && (axes.x || axes.y) ? group(facets, ({ x }) => x, ({ y }) => y) : void 0;
    if (fy && axes.y) {
      const axis1 = axes.y, axis2 = nolabel(axis1);
      const j = axis1.labelAnchor === "bottom" ? fyDomain.length - 1 : axis1.labelAnchor === "center" ? fyDomain.length >> 1 : 0;
      selection.selectAll().data(fyDomain).enter().append((ky, i) => (i === j ? axis1 : axis2).render(fx && where(fxDomain, (kx) => fxy.get(kx).has(ky)), scales, { ...dimensions, ...fyMargins, offsetTop: fy(ky) }, context));
    }
    if (fx && axes.x) {
      const axis1 = axes.x, axis2 = nolabel(axis1);
      const j = axis1.labelAnchor === "right" ? fxDomain.length - 1 : axis1.labelAnchor === "center" ? fxDomain.length >> 1 : 0;
      const { marginLeft, marginRight } = dimensions;
      selection.selectAll().data(fxDomain).enter().append((kx, i) => (i === j ? axis1 : axis2).render(fy && where(fyDomain, (ky) => fxy.get(kx).has(ky)), scales, {
        ...dimensions,
        ...fxMargins,
        labelMarginLeft: marginLeft,
        labelMarginRight: marginRight,
        offsetLeft: fx(kx)
      }, context));
    }
    const facetPosition = new Map(facets.map((f, j) => [f, j]));
    selection.selectAll().data(facetKeys(facets, fx, fy)).enter().append("g").attr("aria-label", "facet").attr("transform", facetTranslate(fx, fy)).each(function(key) {
      for (const [mark, { channels, values: values2, facets: facets2 }] of stateByMark) {
        let facet2 = null;
        if (facets2) {
          const fi = facetPosition.get(key);
          facet2 = facets2[fi] ?? facets2[0];
          facet2 = mark.filter(facet2, channels, values2);
          if (!facet2.length)
            continue;
          facet2.fi = fi;
        }
        const node = mark.render(facet2, scales, values2, subdimensions, context);
        if (node != null)
          this.appendChild(node);
      }
    });
  } else {
    for (const [mark, { channels, values: values2, facets: facets2 }] of stateByMark) {
      let facet2 = null;
      if (facets2) {
        facet2 = facets2[0];
        facet2 = mark.filter(facet2, channels, values2);
        if (!facet2.length)
          continue;
      }
      const node = mark.render(facet2, scales, values2, dimensions, context);
      if (node != null)
        svg.appendChild(node);
    }
  }
  let figure = svg;
  const legends = Legends(scaleDescriptors, context, options);
  if (caption != null || legends.length > 0) {
    const { document } = context;
    figure = document.createElement("figure");
    figure.style.maxWidth = "initial";
    for (const legend2 of legends)
      figure.appendChild(legend2);
    figure.appendChild(svg);
    if (caption != null) {
      const figcaption = document.createElement("figcaption");
      figcaption.appendChild(caption instanceof Node ? caption : document.createTextNode(caption));
      figure.appendChild(figcaption);
    }
  }
  figure.scale = exposeScales(scaleDescriptors);
  figure.legend = exposeLegends(scaleDescriptors, context, options);
  const w = consumeWarnings();
  if (w > 0) {
    select_default(svg).append("text").attr("x", width).attr("y", 20).attr("dy", "-1em").attr("text-anchor", "end").attr("font-family", "initial").text("⚠️").append("title").text(`${w.toLocaleString("en-US")} warning${w === 1 ? "" : "s"}. Please check the console.`);
  }
  return figure;
}
var Mark = class {
  constructor(data, channels = {}, options = {}, defaults21) {
    const { facet = "auto", fx, fy, sort: sort3, dx, dy, clip, channels: extraChannels } = options;
    this.data = data;
    this.sort = isDomainSort(sort3) ? sort3 : null;
    this.initializer = initializer(options).initializer;
    this.transform = this.initializer ? options.transform : basic(options).transform;
    if (facet === null || facet === false) {
      this.facet = null;
    } else {
      this.facet = keyword(facet === true ? "include" : facet, "facet", ["auto", "include", "exclude"]);
      this.fx = fx;
      this.fy = fy;
    }
    channels = maybeNamed(channels);
    if (extraChannels !== void 0)
      channels = { ...maybeNamed(extraChannels), ...channels };
    if (defaults21 !== void 0)
      channels = { ...styles(this, options, defaults21), ...channels };
    this.channels = Object.fromEntries(Object.entries(channels).filter(([name, { value, optional }]) => {
      if (value != null)
        return true;
      if (optional)
        return false;
      throw new Error(`missing channel value: ${name}`);
    }));
    this.dx = +dx || 0;
    this.dy = +dy || 0;
    this.clip = maybeClip(clip);
  }
  initialize(facets, facetChannels) {
    let data = arrayify(this.data);
    if (facets === void 0 && data != null)
      facets = [range2(data)];
    if (this.transform != null)
      ({ facets, data } = this.transform(data, facets)), data = arrayify(data);
    const channels = Channels(this.channels, data);
    if (this.sort != null)
      channelDomain(channels, facetChannels, data, this.sort);
    return { data, facets, channels };
  }
  filter(index, channels, values2) {
    for (const name in channels) {
      const { filter: filter2 = defined } = channels[name];
      if (filter2 !== null) {
        const value = values2[name];
        index = index.filter((i) => filter2(value[i]));
      }
    }
    return index;
  }
  // If there is a projection, and there are both x and y channels (or x1 and
  // y1, or x2 and y2 channels), and those channels are associated with the x
  // and y scale respectively (and not already in screen coordinates as with an
  // initializer), then apply the projection, replacing the x and y values. Note
  // that the x and y scales themselves don’t exist if there is a projection,
  // but whether the channels are associated with scales still determines
  // whether the projection should apply; think of the projection as a
  // combination xy-scale.
  project(channels, values2, context) {
    maybeProject("x", "y", channels, values2, context);
    maybeProject("x1", "y1", channels, values2, context);
    maybeProject("x2", "y2", channels, values2, context);
  }
  scale(channels, scales, context) {
    const values2 = valueObject(channels, scales);
    if (context.projection)
      this.project(channels, values2, context);
    return values2;
  }
  plot({ marks: marks2 = [], ...options } = {}) {
    return plot({ ...options, marks: [...marks2, this] });
  }
};
function marks(...marks2) {
  marks2.plot = Mark.prototype.plot;
  return marks2;
}
function markify(mark) {
  return typeof (mark == null ? void 0 : mark.render) === "function" ? mark : new Render(mark);
}
var Render = class extends Mark {
  constructor(render) {
    super();
    if (render == null)
      return;
    if (typeof render !== "function")
      throw new TypeError("invalid mark; missing render function");
    this.render = render;
  }
  render() {
  }
};
function applyScaleTransforms(channels, options) {
  var _a;
  for (const name in channels) {
    const channel = channels[name];
    const { scale: scale2 } = channel;
    if (scale2 != null) {
      const { percent, interval, transform = percent ? (x) => x * 100 : (_a = maybeInterval(interval)) == null ? void 0 : _a.floor } = options[scale2] || {};
      if (transform != null)
        channel.value = map2(channel.value, transform);
    }
  }
  return channels;
}
function inferChannelScale(channels) {
  for (const name in channels) {
    const channel = channels[name];
    let { scale: scale2 } = channel;
    if (scale2 === true) {
      switch (name) {
        case "fill":
        case "stroke":
          scale2 = "color";
          break;
        case "fillOpacity":
        case "strokeOpacity":
        case "opacity":
          scale2 = "opacity";
          break;
        default:
          scale2 = registry.has(name) ? name : null;
          break;
      }
      channel.scale = scale2;
    }
  }
}
function addScaleChannels(channelsByScale, stateByMark, filter2 = yes) {
  for (const { channels } of stateByMark.values()) {
    for (const name in channels) {
      const channel = channels[name];
      const { scale: scale2 } = channel;
      if (scale2 != null && filter2(scale2)) {
        const scaleChannels = channelsByScale.get(scale2);
        if (scaleChannels !== void 0)
          scaleChannels.push(channel);
        else
          channelsByScale.set(scale2, [channel]);
      }
    }
  }
  return channelsByScale;
}
function hasGeometry(stateByMark) {
  for (const { channels } of stateByMark.values()) {
    if (channels.geometry)
      return true;
  }
  return false;
}
function nolabel(axis) {
  return axis === void 0 || axis.label === void 0 ? axis : Object.assign(Object.create(axis), { label: void 0 });
}
function Facets(channelsByScale, options) {
  const { fx, fy } = Scales(channelsByScale, options);
  const fxDomain = fx == null ? void 0 : fx.scale.domain();
  const fyDomain = fy == null ? void 0 : fy.scale.domain();
  return fxDomain && fyDomain ? cross(fxDomain, fyDomain).map(([x, y]) => ({ x, y })) : fxDomain ? fxDomain.map((x) => ({ x })) : fyDomain ? fyDomain.map((y) => ({ y })) : void 0;
}
function facetKeys(facets, fx, fy) {
  const fxI = fx && new InternMap(fx.domain().map((x, i) => [x, i]));
  const fyI = fy && new InternMap(fy.domain().map((y, i) => [y, i]));
  return sort(facets, (a, b) => fxI && fxI.get(a.x) - fxI.get(b.x) || fyI && fyI.get(a.y) - fyI.get(b.y));
}
function facetGroups(data, { fx, fy }) {
  const I = range2(data);
  const FX = fx == null ? void 0 : fx.value;
  const FY = fy == null ? void 0 : fy.value;
  return fx && fy ? rollup(I, (G) => (G.fx = FX[G[0]], G.fy = FY[G[0]], G), (i) => FX[i], (i) => FY[i]) : fx ? rollup(I, (G) => (G.fx = FX[G[0]], G), (i) => FX[i]) : rollup(I, (G) => (G.fy = FY[G[0]], G), (i) => FY[i]);
}
function facetTranslate(fx, fy) {
  return fx && fy ? ({ x, y }) => `translate(${fx(x)},${fy(y)})` : fx ? ({ x }) => `translate(${fx(x)},0)` : ({ y }) => `translate(0,${fy(y)})`;
}
function excludeIndex(index) {
  const ex = [];
  const e = new Uint32Array(sum(index, (d) => d.length));
  for (const i of index) {
    let n = 0;
    for (const j of index) {
      if (i === j)
        continue;
      e.set(j, n);
      n += j.length;
    }
    ex.push(e.slice(0, n));
  }
  return ex;
}
function maybeTopFacet(facet, options) {
  if (facet == null)
    return;
  const { x, y } = facet;
  if (x == null && y == null)
    return;
  const data = arrayify(facet.data ?? x ?? y);
  if (data === void 0)
    throw new Error(`missing facet data`);
  const channels = {};
  if (x != null)
    channels.fx = Channel(data, { value: x, scale: "fx" });
  if (y != null)
    channels.fy = Channel(data, { value: y, scale: "fy" });
  applyScaleTransforms(channels, options);
  const groups = facetGroups(data, channels);
  const dataLength = groups.size > 1 || channels.fx && channels.fy && groups.size === 1 && [...groups][0][1].size > 1 ? data.length : void 0;
  return { channels, groups, data: facet.data, dataLength };
}
function maybeMarkFacet(mark, topFacetState, options) {
  var _a;
  if (mark.facet === null)
    return;
  const { fx: x, fy: y } = mark;
  if (x != null || y != null) {
    const data2 = arrayify(mark.data ?? x ?? y);
    if (data2 === void 0)
      throw new Error(`missing facet data in ${mark.ariaLabel}`);
    const channels2 = {};
    if (x != null)
      channels2.fx = Channel(data2, { value: x, scale: "fx" });
    if (y != null)
      channels2.fy = Channel(data2, { value: y, scale: "fy" });
    applyScaleTransforms(channels2, options);
    return { channels: channels2, groups: facetGroups(data2, channels2) };
  }
  if (topFacetState === void 0)
    return;
  const { channels, groups, data, dataLength } = topFacetState;
  if (mark.facet !== "auto" || mark.data === data)
    return { channels, groups };
  if (dataLength !== void 0 && ((_a = arrayify(mark.data)) == null ? void 0 : _a.length) === dataLength) {
    warn(`Warning: the ${mark.ariaLabel} mark appears to use faceted data, but isn’t faceted. The mark data has the same length as the facet data and the mark facet option is "auto", but the mark data and facet data are distinct. If this mark should be faceted, set the mark facet option to true; otherwise, suppress this warning by setting the mark facet option to false.`);
  }
}
function filterFacets(facets, { channels: { fx, fy }, groups }) {
  return fx && fy ? facets.map(({ x, y }) => {
    var _a;
    return ((_a = groups.get(x)) == null ? void 0 : _a.get(y)) ?? [];
  }) : fx ? facets.map(({ x }) => groups.get(x) ?? []) : facets.map(({ y }) => groups.get(y) ?? []);
}

// ../../node_modules/@observablehq/plot/dist/curve.js
var curves = /* @__PURE__ */ new Map([
  ["basis", basis_default],
  ["basis-closed", basisClosed_default],
  ["basis-open", basisOpen_default],
  ["bundle", bundle_default],
  ["bump-x", bumpX],
  ["bump-y", bumpY],
  ["cardinal", cardinal_default],
  ["cardinal-closed", cardinalClosed_default],
  ["cardinal-open", cardinalOpen_default],
  ["catmull-rom", catmullRom_default],
  ["catmull-rom-closed", catmullRomClosed_default],
  ["catmull-rom-open", catmullRomOpen_default],
  ["linear", linear_default],
  ["linear-closed", linearClosed_default],
  ["monotone-x", monotoneX],
  ["monotone-y", monotoneY],
  ["natural", natural_default],
  ["step", step_default],
  ["step-after", stepAfter],
  ["step-before", stepBefore]
]);
function Curve(curve = linear_default, tension) {
  if (typeof curve === "function")
    return curve;
  const c = curves.get(`${curve}`.toLowerCase());
  if (!c)
    throw new Error(`unknown curve: ${curve}`);
  if (tension !== void 0) {
    if ("beta" in c) {
      return c.beta(tension);
    } else if ("tension" in c) {
      return c.tension(tension);
    } else if ("alpha" in c) {
      return c.alpha(tension);
    }
  }
  return c;
}

// ../../node_modules/@observablehq/plot/dist/transforms/inset.js
function maybeInsetX({ inset, insetLeft, insetRight, ...options } = {}) {
  [insetLeft, insetRight] = maybeInset(inset, insetLeft, insetRight);
  return { inset, insetLeft, insetRight, ...options };
}
function maybeInsetY({ inset, insetTop, insetBottom, ...options } = {}) {
  [insetTop, insetBottom] = maybeInset(inset, insetTop, insetBottom);
  return { inset, insetTop, insetBottom, ...options };
}
function maybeInset(inset, inset1, inset2) {
  return inset === void 0 && inset1 === void 0 && inset2 === void 0 ? offset ? [1, 0] : [0.5, 0.5] : [inset1, inset2];
}

// ../../node_modules/@observablehq/plot/dist/transforms/bin.js
function binX(outputs = { y: "count" }, options = {}) {
  [outputs, options] = mergeOptions(outputs, options);
  const { x, y } = options;
  return binn(maybeBinValue(x, options, identity2), null, null, y, outputs, maybeInsetX(options));
}
function binY(outputs = { x: "count" }, options = {}) {
  [outputs, options] = mergeOptions(outputs, options);
  const { x, y } = options;
  return binn(null, maybeBinValue(y, options, identity2), x, null, outputs, maybeInsetY(options));
}
function bin(outputs = { fill: "count" }, options = {}) {
  [outputs, options] = mergeOptions(outputs, options);
  const { x, y } = maybeBinValueTuple(options);
  return binn(x, y, null, null, outputs, maybeInsetX(maybeInsetY(options)));
}
function maybeDenseInterval(bin2, k, options = {}) {
  return (options == null ? void 0 : options.interval) == null ? options : bin2({ [k]: (options == null ? void 0 : options.reduce) === void 0 ? reduceFirst : options.reduce, filter: null }, options);
}
function maybeDenseIntervalX(options) {
  return maybeDenseInterval(binX, "y", options);
}
function maybeDenseIntervalY(options) {
  return maybeDenseInterval(binY, "x", options);
}
function binn(bx, by, gx, gy, {
  data: reduceData = reduceIdentity,
  // TODO avoid materializing when unused?
  filter: filter2 = reduceCount,
  // return only non-empty bins by default
  sort: sort3,
  reverse: reverse3,
  ...outputs
  // output channel definitions
} = {}, inputs = {}) {
  bx = maybeBin(bx);
  by = maybeBin(by);
  outputs = maybeOutputs(outputs, inputs);
  reduceData = maybeReduce(reduceData, identity2);
  sort3 = sort3 == null ? void 0 : maybeOutput("sort", sort3, inputs);
  filter2 = filter2 == null ? void 0 : maybeEvaluator("filter", filter2, inputs);
  if (gx != null && hasOutput(outputs, "x", "x1", "x2"))
    gx = null;
  if (gy != null && hasOutput(outputs, "y", "y1", "y2"))
    gy = null;
  const [BX1, setBX1] = maybeColumn(bx);
  const [BX2, setBX2] = maybeColumn(bx);
  const [BY1, setBY1] = maybeColumn(by);
  const [BY2, setBY2] = maybeColumn(by);
  const [k, gk] = gx != null ? [gx, "x"] : gy != null ? [gy, "y"] : [];
  const [GK, setGK] = maybeColumn(k);
  const {
    x,
    y,
    z,
    fill,
    stroke,
    x1,
    x2,
    // consumed if x is an output
    y1,
    y2,
    // consumed if y is an output
    domain,
    cumulative,
    thresholds,
    interval,
    ...options
  } = inputs;
  const [GZ, setGZ] = maybeColumn(z);
  const [vfill] = maybeColorChannel(fill);
  const [vstroke] = maybeColorChannel(stroke);
  const [GF, setGF] = maybeColumn(vfill);
  const [GS, setGS] = maybeColumn(vstroke);
  return {
    ..."z" in inputs && { z: GZ || z },
    ..."fill" in inputs && { fill: GF || fill },
    ..."stroke" in inputs && { stroke: GS || stroke },
    ...basic(options, (data, facets) => {
      const K = valueof(data, k);
      const Z = valueof(data, z);
      const F = valueof(data, vfill);
      const S = valueof(data, vstroke);
      const G = maybeSubgroup(outputs, { z: Z, fill: F, stroke: S });
      const groupFacets = [];
      const groupData = [];
      const GK2 = K && setGK([]);
      const GZ2 = Z && setGZ([]);
      const GF2 = F && setGF([]);
      const GS2 = S && setGS([]);
      const BX12 = bx && setBX1([]);
      const BX22 = bx && setBX2([]);
      const BY12 = by && setBY1([]);
      const BY22 = by && setBY2([]);
      const bin2 = Bin(bx == null ? void 0 : bx(data), by == null ? void 0 : by(data));
      let i = 0;
      for (const o of outputs)
        o.initialize(data);
      if (sort3)
        sort3.initialize(data);
      if (filter2)
        filter2.initialize(data);
      for (const facet of facets) {
        const groupFacet = [];
        for (const o of outputs)
          o.scope("facet", facet);
        if (sort3)
          sort3.scope("facet", facet);
        if (filter2)
          filter2.scope("facet", facet);
        for (const [f, I] of maybeGroup(facet, G)) {
          for (const [k2, g] of maybeGroup(I, K)) {
            for (const [b, extent3] of bin2(g)) {
              if (filter2 && !filter2.reduce(b, extent3))
                continue;
              groupFacet.push(i++);
              groupData.push(reduceData.reduce(b, data, extent3));
              if (K)
                GK2.push(k2);
              if (Z)
                GZ2.push(G === Z ? f : Z[b[0]]);
              if (F)
                GF2.push(G === F ? f : F[b[0]]);
              if (S)
                GS2.push(G === S ? f : S[b[0]]);
              if (BX12)
                BX12.push(extent3.x1), BX22.push(extent3.x2);
              if (BY12)
                BY12.push(extent3.y1), BY22.push(extent3.y2);
              for (const o of outputs)
                o.reduce(b, extent3);
              if (sort3)
                sort3.reduce(b);
            }
          }
        }
        groupFacets.push(groupFacet);
      }
      maybeSort(groupFacets, sort3, reverse3);
      return { data: groupData, facets: groupFacets };
    }),
    ...!hasOutput(outputs, "x") && (BX1 ? { x1: BX1, x2: BX2, x: mid(BX1, BX2) } : { x, x1, x2 }),
    ...!hasOutput(outputs, "y") && (BY1 ? { y1: BY1, y2: BY2, y: mid(BY1, BY2) } : { y, y1, y2 }),
    ...GK && { [gk]: GK },
    ...Object.fromEntries(outputs.map(({ name, output }) => [name, output]))
  };
}
function mergeOptions({ cumulative, domain, thresholds, interval, ...outputs }, options) {
  return [outputs, { cumulative, domain, thresholds, interval, ...options }];
}
function maybeBinValue(value, { cumulative, domain, thresholds, interval }, defaultValue) {
  value = { ...maybeValue(value) };
  if (value.domain === void 0)
    value.domain = domain;
  if (value.cumulative === void 0)
    value.cumulative = cumulative;
  if (value.thresholds === void 0)
    value.thresholds = thresholds;
  if (value.interval === void 0)
    value.interval = interval;
  if (value.value === void 0)
    value.value = defaultValue;
  value.thresholds = maybeThresholds(value.thresholds, value.interval);
  return value;
}
function maybeBinValueTuple(options) {
  let { x, y } = options;
  x = maybeBinValue(x, options);
  y = maybeBinValue(y, options);
  [x.value, y.value] = maybeTuple(x.value, y.value);
  return { x, y };
}
function maybeBin(options) {
  if (options == null)
    return;
  const { value, cumulative, domain = extent, thresholds } = options;
  const bin2 = (data) => {
    let V = valueof(data, value);
    let T;
    if (isTemporal(V) || isTimeThresholds(thresholds)) {
      V = map2(V, coerceDate, Float64Array);
      let [min2, max2] = typeof domain === "function" ? domain(V) : domain;
      let t = typeof thresholds === "function" && !isInterval(thresholds) ? thresholds(V, min2, max2) : thresholds;
      if (typeof t === "number")
        t = utcTickInterval(min2, max2, t);
      if (isInterval(t)) {
        if (domain === extent) {
          min2 = t.floor(min2);
          max2 = t.offset(t.floor(max2));
        }
        t = t.range(min2, t.offset(max2));
      }
      T = t;
    } else {
      V = map2(V, coerceNumber, Float64Array);
      let [min2, max2] = typeof domain === "function" ? domain(V) : domain;
      let t = typeof thresholds === "function" && !isInterval(thresholds) ? thresholds(V, min2, max2) : thresholds;
      if (typeof t === "number") {
        if (domain === extent) {
          let step = tickIncrement(min2, max2, t);
          if (isFinite(step)) {
            if (step > 0) {
              let r0 = Math.round(min2 / step);
              let r1 = Math.round(max2 / step);
              if (!(r0 * step <= min2))
                --r0;
              if (!(r1 * step > max2))
                ++r1;
              let n = r1 - r0 + 1;
              t = new Float64Array(n);
              for (let i = 0; i < n; ++i)
                t[i] = (r0 + i) * step;
            } else if (step < 0) {
              step = -step;
              let r0 = Math.round(min2 * step);
              let r1 = Math.round(max2 * step);
              if (!(r0 / step <= min2))
                --r0;
              if (!(r1 / step > max2))
                ++r1;
              let n = r1 - r0 + 1;
              t = new Float64Array(n);
              for (let i = 0; i < n; ++i)
                t[i] = (r0 + i) / step;
            } else {
              t = [min2];
            }
          } else {
            t = [min2];
          }
        } else {
          t = ticks(min2, max2, t);
        }
      } else if (isInterval(t)) {
        if (domain === extent) {
          min2 = t.floor(min2);
          max2 = t.offset(t.floor(max2));
        }
        t = t.range(min2, t.offset(max2));
      }
      T = t;
    }
    const E = [];
    if (T.length === 1)
      E.push([T[0], T[0]]);
    else
      for (let i = 1; i < T.length; ++i)
        E.push([T[i - 1], T[i]]);
    E.bin = (cumulative < 0 ? bin1cn : cumulative > 0 ? bin1cp : bin1)(E, T, V);
    return E;
  };
  bin2.label = labelof(value);
  return bin2;
}
function maybeThresholds(thresholds, interval, defaultThresholds = thresholdAuto) {
  if (thresholds === void 0) {
    return interval === void 0 ? defaultThresholds : maybeRangeInterval(interval);
  }
  if (typeof thresholds === "string") {
    switch (thresholds.toLowerCase()) {
      case "freedman-diaconis":
        return thresholdFreedmanDiaconis;
      case "scott":
        return thresholdScott;
      case "sturges":
        return thresholdSturges;
      case "auto":
        return thresholdAuto;
    }
    const interval2 = maybeInterval(thresholds);
    if (interval2 !== void 0)
      return interval2;
    throw new Error(`invalid thresholds: ${thresholds}`);
  }
  return thresholds;
}
function maybeRangeInterval(interval) {
  interval = maybeInterval(interval);
  if (!isInterval(interval))
    throw new Error(`invalid interval: ${interval}`);
  return interval;
}
function thresholdAuto(values2, min2, max2) {
  return Math.min(200, thresholdScott(values2, min2, max2));
}
function isTimeThresholds(t) {
  return isTimeInterval(t) || isIterable(t) && isTemporal(t);
}
function isTimeInterval(t) {
  return isInterval(t) && typeof t === "function" && t() instanceof Date;
}
function isInterval(t) {
  return t ? typeof t.range === "function" : false;
}
function Bin(EX, EY) {
  return EX && EY ? function* (I) {
    const X = EX.bin(I);
    for (const [ix, [x1, x2]] of EX.entries()) {
      const Y = EY.bin(X[ix]);
      for (const [iy, [y1, y2]] of EY.entries()) {
        yield [Y[iy], { x1, y1, x2, y2 }];
      }
    }
  } : EX ? function* (I) {
    const X = EX.bin(I);
    for (const [i, [x1, x2]] of EX.entries()) {
      yield [X[i], { x1, x2 }];
    }
  } : function* (I) {
    const Y = EY.bin(I);
    for (const [i, [y1, y2]] of EY.entries()) {
      yield [Y[i], { y1, y2 }];
    }
  };
}
function bin1(E, T, V) {
  T = T.map(coerceNumber);
  return (I) => {
    var _a;
    const B = E.map(() => []);
    for (const i of I)
      (_a = B[bisect_default(T, V[i]) - 1]) == null ? void 0 : _a.push(i);
    return B;
  };
}
function bin1cp(E, T, V) {
  const bin2 = bin1(E, T, V);
  return (I) => {
    const B = bin2(I);
    for (let i = 1, n = B.length; i < n; ++i) {
      const C = B[i - 1];
      const b = B[i];
      for (const j of C)
        b.push(j);
    }
    return B;
  };
}
function bin1cn(E, T, V) {
  const bin2 = bin1(E, T, V);
  return (I) => {
    const B = bin2(I);
    for (let i = B.length - 2; i >= 0; --i) {
      const C = B[i + 1];
      const b = B[i];
      for (const j of C)
        b.push(j);
    }
    return B;
  };
}

// ../../node_modules/@observablehq/plot/dist/transforms/identity.js
function maybeIdentityX(options = {}) {
  const { x, x1, x2 } = options;
  return x1 === void 0 && x2 === void 0 && x === void 0 ? { ...options, x: identity2 } : options;
}
function maybeIdentityY(options = {}) {
  const { y, y1, y2 } = options;
  return y1 === void 0 && y2 === void 0 && y === void 0 ? { ...options, y: identity2 } : options;
}

// ../../node_modules/@observablehq/plot/dist/transforms/stack.js
function stackX(stack2 = {}, options = {}) {
  if (arguments.length === 1)
    [stack2, options] = mergeOptions2(stack2);
  const { y1, y = y1, x, ...rest } = options;
  const [transform, Y, x1, x2] = stackAlias(y, x, "x", stack2, rest);
  return { ...transform, y1, y: Y, x1, x2, x: mid(x1, x2) };
}
function stackX1(stack2 = {}, options = {}) {
  if (arguments.length === 1)
    [stack2, options] = mergeOptions2(stack2);
  const { y1, y = y1, x } = options;
  const [transform, Y, X] = stackAlias(y, x, "x", stack2, options);
  return { ...transform, y1, y: Y, x: X };
}
function stackX2(stack2 = {}, options = {}) {
  if (arguments.length === 1)
    [stack2, options] = mergeOptions2(stack2);
  const { y1, y = y1, x } = options;
  const [transform, Y, , X] = stackAlias(y, x, "x", stack2, options);
  return { ...transform, y1, y: Y, x: X };
}
function stackY(stack2 = {}, options = {}) {
  if (arguments.length === 1)
    [stack2, options] = mergeOptions2(stack2);
  const { x1, x = x1, y, ...rest } = options;
  const [transform, X, y1, y2] = stackAlias(x, y, "y", stack2, rest);
  return { ...transform, x1, x: X, y1, y2, y: mid(y1, y2) };
}
function stackY1(stack2 = {}, options = {}) {
  if (arguments.length === 1)
    [stack2, options] = mergeOptions2(stack2);
  const { x1, x = x1, y } = options;
  const [transform, X, Y] = stackAlias(x, y, "y", stack2, options);
  return { ...transform, x1, x: X, y: Y };
}
function stackY2(stack2 = {}, options = {}) {
  if (arguments.length === 1)
    [stack2, options] = mergeOptions2(stack2);
  const { x1, x = x1, y } = options;
  const [transform, X, , Y] = stackAlias(x, y, "y", stack2, options);
  return { ...transform, x1, x: X, y: Y };
}
function maybeStackX({ x, x1, x2, ...options } = {}) {
  if (x1 === void 0 && x2 === void 0)
    return stackX({ x, ...options });
  [x1, x2] = maybeZero(x, x1, x2);
  return { ...options, x1, x2 };
}
function maybeStackY({ y, y1, y2, ...options } = {}) {
  if (y1 === void 0 && y2 === void 0)
    return stackY({ y, ...options });
  [y1, y2] = maybeZero(y, y1, y2);
  return { ...options, y1, y2 };
}
function mergeOptions2(options) {
  const { offset: offset2, order: order2, reverse: reverse3, ...rest } = options;
  return [{ offset: offset2, order: order2, reverse: reverse3 }, rest];
}
function stack(x, y = one, ky, { offset: offset2, order: order2, reverse: reverse3 }, options) {
  const z = maybeZ(options);
  const [X, setX] = maybeColumn(x);
  const [Y1, setY1] = column(y);
  const [Y2, setY2] = column(y);
  offset2 = maybeOffset(offset2);
  order2 = maybeOrder(order2, offset2, ky);
  return [
    basic(options, (data, facets) => {
      const X2 = x == null ? void 0 : setX(valueof(data, x));
      const Y = valueof(data, y, Float64Array);
      const Z = valueof(data, z);
      const O = order2 && order2(data, X2, Y, Z);
      const n = data.length;
      const Y12 = setY1(new Float64Array(n));
      const Y22 = setY2(new Float64Array(n));
      const facetstacks = [];
      for (const facet of facets) {
        const stacks = X2 ? Array.from(group(facet, (i) => X2[i]).values()) : [facet];
        if (O)
          applyOrder(stacks, O);
        for (const stack2 of stacks) {
          let yn = 0, yp = 0;
          if (reverse3)
            stack2.reverse();
          for (const i of stack2) {
            const y2 = Y[i];
            if (y2 < 0)
              yn = Y22[i] = (Y12[i] = yn) + y2;
            else if (y2 > 0)
              yp = Y22[i] = (Y12[i] = yp) + y2;
            else
              Y22[i] = Y12[i] = yp;
          }
        }
        facetstacks.push(stacks);
      }
      if (offset2)
        offset2(facetstacks, Y12, Y22, Z);
      return { data, facets };
    }),
    X,
    Y1,
    Y2
  ];
}
var stackAlias = stack;
function maybeOffset(offset2) {
  if (offset2 == null)
    return;
  if (typeof offset2 === "function")
    return offset2;
  switch (`${offset2}`.toLowerCase()) {
    case "expand":
    case "normalize":
      return offsetExpand;
    case "center":
    case "silhouette":
      return offsetCenter;
    case "wiggle":
      return offsetWiggle;
  }
  throw new Error(`unknown offset: ${offset2}`);
}
function extent2(stack2, Y2) {
  let min2 = 0, max2 = 0;
  for (const i of stack2) {
    const y = Y2[i];
    if (y < min2)
      min2 = y;
    if (y > max2)
      max2 = y;
  }
  return [min2, max2];
}
function offsetExpand(facetstacks, Y1, Y2) {
  for (const stacks of facetstacks) {
    for (const stack2 of stacks) {
      const [yn, yp] = extent2(stack2, Y2);
      for (const i of stack2) {
        const m = 1 / (yp - yn || 1);
        Y1[i] = m * (Y1[i] - yn);
        Y2[i] = m * (Y2[i] - yn);
      }
    }
  }
}
function offsetCenter(facetstacks, Y1, Y2) {
  for (const stacks of facetstacks) {
    for (const stack2 of stacks) {
      const [yn, yp] = extent2(stack2, Y2);
      for (const i of stack2) {
        const m = (yp + yn) / 2;
        Y1[i] -= m;
        Y2[i] -= m;
      }
    }
    offsetZero(stacks, Y1, Y2);
  }
  offsetCenterFacets(facetstacks, Y1, Y2);
}
function offsetWiggle(facetstacks, Y1, Y2, Z) {
  for (const stacks of facetstacks) {
    const prev = new InternMap();
    let y = 0;
    for (const stack2 of stacks) {
      let j = -1;
      const Fi = stack2.map((i) => Math.abs(Y2[i] - Y1[i]));
      const Df = stack2.map((i) => {
        j = Z ? Z[i] : ++j;
        const value = Y2[i] - Y1[i];
        const diff = prev.has(j) ? value - prev.get(j) : 0;
        prev.set(j, value);
        return diff;
      });
      const Cf1 = [0, ...cumsum(Df)];
      for (const i of stack2) {
        Y1[i] += y;
        Y2[i] += y;
      }
      const s1 = sum(Fi);
      if (s1)
        y -= sum(Fi, (d, i) => (Df[i] / 2 + Cf1[i]) * d) / s1;
    }
    offsetZero(stacks, Y1, Y2);
  }
  offsetCenterFacets(facetstacks, Y1, Y2);
}
function offsetZero(stacks, Y1, Y2) {
  const m = min(stacks, (stack2) => min(stack2, (i) => Y1[i]));
  for (const stack2 of stacks) {
    for (const i of stack2) {
      Y1[i] -= m;
      Y2[i] -= m;
    }
  }
}
function offsetCenterFacets(facetstacks, Y1, Y2) {
  const n = facetstacks.length;
  if (n === 1)
    return;
  const facets = facetstacks.map((stacks) => stacks.flat());
  const m = facets.map((I) => (min(I, (i) => Y1[i]) + max(I, (i) => Y2[i])) / 2);
  const m0 = min(m);
  for (let j = 0; j < n; j++) {
    const p = m0 - m[j];
    for (const i of facets[j]) {
      Y1[i] += p;
      Y2[i] += p;
    }
  }
}
function maybeOrder(order2, offset2, ky) {
  if (order2 === void 0 && offset2 === offsetWiggle)
    return orderInsideOut;
  if (order2 == null)
    return;
  if (typeof order2 === "string") {
    switch (order2.toLowerCase()) {
      case "value":
      case ky:
        return orderY;
      case "z":
        return orderZ;
      case "sum":
        return orderSum;
      case "appearance":
        return orderAppearance;
      case "inside-out":
        return orderInsideOut;
    }
    return orderFunction(field(order2));
  }
  if (typeof order2 === "function")
    return orderFunction(order2);
  if (Array.isArray(order2))
    return orderGiven(order2);
  throw new Error(`invalid order: ${order2}`);
}
function orderY(data, X, Y) {
  return Y;
}
function orderZ(order2, X, Y, Z) {
  return Z;
}
function orderSum(data, X, Y, Z) {
  return orderZDomain(Z, groupSort(range2(data), (I) => sum(I, (i) => Y[i]), (i) => Z[i]));
}
function orderAppearance(data, X, Y, Z) {
  return orderZDomain(Z, groupSort(range2(data), (I) => X[greatest(I, (i) => Y[i])], (i) => Z[i]));
}
function orderInsideOut(data, X, Y, Z) {
  const I = range2(data);
  const K = groupSort(I, (I2) => X[greatest(I2, (i) => Y[i])], (i) => Z[i]);
  const sums = rollup(I, (I2) => sum(I2, (i) => Y[i]), (i) => Z[i]);
  const Kp = [], Kn = [];
  let s = 0;
  for (const k of K) {
    if (s < 0) {
      s += sums.get(k);
      Kp.push(k);
    } else {
      s -= sums.get(k);
      Kn.push(k);
    }
  }
  return orderZDomain(Z, Kn.reverse().concat(Kp));
}
function orderFunction(f) {
  return (data) => valueof(data, f);
}
function orderGiven(domain) {
  return (data, X, Y, Z) => orderZDomain(Z, domain);
}
function orderZDomain(Z, domain) {
  if (!Z)
    throw new Error("missing channel: z");
  domain = new InternMap(domain.map((d, i) => [d, i]));
  return Z.map((z) => domain.get(z));
}
function applyOrder(stacks, O) {
  for (const stack2 of stacks) {
    stack2.sort((i, j) => ascendingDefined(O[i], O[j]));
  }
}

// ../../node_modules/@observablehq/plot/dist/marks/area.js
var defaults = {
  ariaLabel: "area",
  strokeWidth: 1,
  strokeLinecap: "round",
  strokeLinejoin: "round",
  strokeMiterlimit: 1
};
var Area = class extends Mark {
  constructor(data, options = {}) {
    const { x1, y1, x2, y2, z, curve, tension } = options;
    super(data, {
      x1: { value: x1, scale: "x" },
      y1: { value: y1, scale: "y" },
      x2: { value: x2, scale: "x", optional: true },
      y2: { value: y2, scale: "y", optional: true },
      z: { value: maybeZ(options), optional: true }
    }, options, defaults);
    this.z = z;
    this.curve = Curve(curve, tension);
  }
  filter(index) {
    return index;
  }
  render(index, scales, channels, dimensions, context) {
    const { x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1 } = channels;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, scales, 0, 0).call((g) => g.selectAll().data(groupIndex(index, [X1, Y1, X2, Y2], this, channels)).enter().append("path").call(applyDirectStyles, this).call(applyGroupedChannelStyles, this, channels).attr("d", area_default().curve(this.curve).defined((i) => i >= 0).x0((i) => X1[i]).y0((i) => Y1[i]).x1((i) => X2[i]).y1((i) => Y2[i]))).node();
  }
};
function area(data, options) {
  if (options === void 0)
    return areaY(data, { x: first, y: second2 });
  return new Area(data, options);
}
function areaX(data, options) {
  const { y = indexOf, ...rest } = maybeDenseIntervalY(options);
  return new Area(data, maybeStackX(maybeIdentityX({ ...rest, y1: y, y2: void 0 })));
}
function areaY(data, options) {
  const { x = indexOf, ...rest } = maybeDenseIntervalX(options);
  return new Area(data, maybeStackY(maybeIdentityY({ ...rest, x1: x, x2: void 0 })));
}

// ../../node_modules/@observablehq/plot/dist/marks/marker.js
function markers(mark, { marker, markerStart = marker, markerMid = marker, markerEnd = marker } = {}) {
  mark.markerStart = maybeMarker(markerStart);
  mark.markerMid = maybeMarker(markerMid);
  mark.markerEnd = maybeMarker(markerEnd);
}
function maybeMarker(marker) {
  if (marker == null || marker === false)
    return null;
  if (marker === true)
    return markerCircleFill;
  if (typeof marker === "function")
    return marker;
  switch (`${marker}`.toLowerCase()) {
    case "none":
      return null;
    case "arrow":
      return markerArrow;
    case "dot":
      return markerDot;
    case "circle":
    case "circle-fill":
      return markerCircleFill;
    case "circle-stroke":
      return markerCircleStroke;
  }
  throw new Error(`invalid marker: ${marker}`);
}
function markerArrow(color3, context) {
  return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("orient", "auto").attr("fill", "none").attr("stroke", color3).attr("stroke-width", 1.5).attr("stroke-linecap", "round").attr("stroke-linejoin", "round").call((marker) => marker.append("path").attr("d", "M-1.5,-3l3,3l-3,3")).node();
}
function markerDot(color3, context) {
  return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("fill", color3).attr("stroke", "none").call((marker) => marker.append("circle").attr("r", 2.5)).node();
}
function markerCircleFill(color3, context) {
  return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("fill", color3).attr("stroke", "white").attr("stroke-width", 1.5).call((marker) => marker.append("circle").attr("r", 3)).node();
}
function markerCircleStroke(color3, context) {
  return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("fill", "white").attr("stroke", color3).attr("stroke-width", 1.5).call((marker) => marker.append("circle").attr("r", 3)).node();
}
var nextMarkerId = 0;
function applyMarkers(path, mark, { stroke: S } = {}) {
  return applyMarkersColor(path, mark, S && ((i) => S[i]));
}
function applyGroupedMarkers(path, mark, { stroke: S } = {}) {
  return applyMarkersColor(path, mark, S && (([i]) => S[i]));
}
function applyMarkersColor(path, { markerStart, markerMid, markerEnd, stroke }, strokeof = () => stroke) {
  const iriByMarkerColor = /* @__PURE__ */ new Map();
  function applyMarker(marker) {
    return function(i) {
      const color3 = strokeof(i);
      let iriByColor = iriByMarkerColor.get(marker);
      if (!iriByColor)
        iriByMarkerColor.set(marker, iriByColor = /* @__PURE__ */ new Map());
      let iri = iriByColor.get(color3);
      if (!iri) {
        const context = { document: this.ownerDocument };
        const node = this.parentNode.insertBefore(marker(color3, context), this);
        const id = `plot-marker-${++nextMarkerId}`;
        node.setAttribute("id", id);
        iriByColor.set(color3, iri = `url(#${id})`);
      }
      return iri;
    };
  }
  if (markerStart)
    path.attr("marker-start", applyMarker(markerStart));
  if (markerMid)
    path.attr("marker-mid", applyMarker(markerMid));
  if (markerEnd)
    path.attr("marker-end", applyMarker(markerEnd));
}

// ../../node_modules/@observablehq/plot/dist/marks/link.js
var defaults2 = {
  ariaLabel: "link",
  fill: "none",
  stroke: "currentColor",
  strokeMiterlimit: 1
};
var Link = class extends Mark {
  constructor(data, options = {}) {
    const { x1, y1, x2, y2, curve, tension } = options;
    super(data, {
      x1: { value: x1, scale: "x" },
      y1: { value: y1, scale: "y" },
      x2: { value: x2, scale: "x", optional: true },
      y2: { value: y2, scale: "y", optional: true }
    }, options, defaults2);
    this.curve = Curve(curve, tension);
    markers(this, options);
  }
  render(index, scales, channels, dimensions, context) {
    const { x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1 } = channels;
    const { curve } = this;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, scales).call((g) => g.selectAll().data(index).enter().append("path").call(applyDirectStyles, this).attr("d", (i) => {
      const p = pathRound();
      const c = curve(p);
      c.lineStart();
      c.point(X1[i], Y1[i]);
      c.point(X2[i], Y2[i]);
      c.lineEnd();
      return p;
    }).call(applyChannelStyles, this, channels).call(applyMarkers, this, channels)).node();
  }
};
function link(data, options = {}) {
  let { x, x1, x2, y, y1, y2, ...remainingOptions } = options;
  [x1, x2] = maybeSameValue(x, x1, x2);
  [y1, y2] = maybeSameValue(y, y1, y2);
  return new Link(data, { ...remainingOptions, x1, x2, y1, y2 });
}
function maybeSameValue(x, x1, x2) {
  if (x === void 0) {
    if (x1 === void 0) {
      if (x2 !== void 0)
        return [x2];
    } else {
      if (x2 === void 0)
        return [x1];
    }
  } else if (x1 === void 0) {
    return x2 === void 0 ? [x] : [x, x2];
  } else if (x2 === void 0) {
    return [x, x1];
  }
  return [x1, x2];
}

// ../../node_modules/@observablehq/plot/dist/marks/arrow.js
var defaults3 = {
  ariaLabel: "arrow",
  fill: "none",
  stroke: "currentColor",
  strokeLinecap: "round",
  strokeMiterlimit: 1,
  strokeWidth: 1.5
};
var Arrow = class extends Mark {
  constructor(data, options = {}) {
    const {
      x1,
      y1,
      x2,
      y2,
      bend = 0,
      headAngle = 60,
      headLength = 8,
      // Disable the arrow with headLength = 0; or, use Plot.link.
      inset = 0,
      insetStart = inset,
      insetEnd = inset
    } = options;
    super(data, {
      x1: { value: x1, scale: "x" },
      y1: { value: y1, scale: "y" },
      x2: { value: x2, scale: "x", optional: true },
      y2: { value: y2, scale: "y", optional: true }
    }, options, defaults3);
    this.bend = bend === true ? 22.5 : Math.max(-90, Math.min(90, bend));
    this.headAngle = +headAngle;
    this.headLength = +headLength;
    this.insetStart = +insetStart;
    this.insetEnd = +insetEnd;
  }
  render(index, scales, channels, dimensions, context) {
    const { x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1, SW } = channels;
    const { strokeWidth, bend, headAngle, headLength, insetStart, insetEnd } = this;
    const sw = SW ? (i) => SW[i] : constant(strokeWidth === void 0 ? 1 : strokeWidth);
    const bendAngle = bend * radians;
    const wingAngle = headAngle * radians / 2;
    const wingScale = headLength / 1.5;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, scales).call((g) => g.selectAll().data(index).enter().append("path").call(applyDirectStyles, this).attr("d", (i) => {
      let x1 = X1[i], y1 = Y1[i], x2 = X2[i], y2 = Y2[i];
      const lineLength = Math.hypot(x2 - x1, y2 - y1);
      if (lineLength <= insetStart + insetEnd)
        return null;
      let lineAngle = Math.atan2(y2 - y1, x2 - x1);
      const headLength2 = Math.min(wingScale * sw(i), lineLength / 3);
      const r = Math.hypot(lineLength / Math.tan(bendAngle), lineLength) / 2;
      if (insetStart || insetEnd) {
        if (r < 1e5) {
          const sign = Math.sign(bendAngle);
          const [cx, cy] = pointPointCenter([x1, y1], [x2, y2], r, sign);
          if (insetStart) {
            [x1, y1] = circleCircleIntersect([cx, cy, r], [x1, y1, insetStart], -sign * Math.sign(insetStart));
          }
          if (insetEnd) {
            const [x, y] = circleCircleIntersect([cx, cy, r], [x2, y2, insetEnd], sign * Math.sign(insetEnd));
            lineAngle += Math.atan2(y - cy, x - cx) - Math.atan2(y2 - cy, x2 - cx);
            x2 = x, y2 = y;
          }
        } else {
          const dx = x2 - x1, dy = y2 - y1, d = Math.hypot(dx, dy);
          if (insetStart)
            x1 += dx / d * insetStart, y1 += dy / d * insetStart;
          if (insetEnd)
            x2 -= dx / d * insetEnd, y2 -= dy / d * insetEnd;
        }
      }
      const endAngle = lineAngle + bendAngle;
      const leftAngle = endAngle + wingAngle;
      const rightAngle = endAngle - wingAngle;
      const x3 = x2 - headLength2 * Math.cos(leftAngle);
      const y3 = y2 - headLength2 * Math.sin(leftAngle);
      const x4 = x2 - headLength2 * Math.cos(rightAngle);
      const y4 = y2 - headLength2 * Math.sin(rightAngle);
      return `M${x1},${y1}${r < 1e5 ? `A${r},${r} 0,0,${bendAngle > 0 ? 1 : 0} ` : `L`}${x2},${y2}M${x3},${y3}L${x2},${y2}L${x4},${y4}`;
    }).call(applyChannelStyles, this, channels)).node();
  }
};
function pointPointCenter([ax, ay], [bx, by], r, sign) {
  const dx = bx - ax, dy = by - ay, d = Math.hypot(dx, dy);
  const k = sign * Math.sqrt(r * r - d * d / 4) / d;
  return [(ax + bx) / 2 - dy * k, (ay + by) / 2 + dx * k];
}
function circleCircleIntersect([ax, ay, ar], [bx, by, br], sign) {
  const dx = bx - ax, dy = by - ay, d = Math.hypot(dx, dy);
  const x = (dx * dx + dy * dy - br * br + ar * ar) / (2 * d);
  const y = sign * Math.sqrt(ar * ar - x * x);
  return [ax + (dx * x + dy * y) / d, ay + (dy * x - dx * y) / d];
}
function arrow(data, options = {}) {
  let { x, x1, x2, y, y1, y2, ...remainingOptions } = options;
  [x1, x2] = maybeSameValue(x, x1, x2);
  [y1, y2] = maybeSameValue(y, y1, y2);
  return new Arrow(data, { ...remainingOptions, x1, x2, y1, y2 });
}

// ../../node_modules/@observablehq/plot/dist/transforms/interval.js
function maybeIntervalValue(value, { interval }) {
  value = { ...maybeValue(value) };
  value.interval = maybeInterval(value.interval === void 0 ? interval : value.interval);
  return value;
}
function maybeIntervalK(k, maybeInsetK, options, trivial) {
  const { [k]: v, [`${k}1`]: v1, [`${k}2`]: v2 } = options;
  const { value, interval } = maybeIntervalValue(v, options);
  if (value == null || interval == null && !trivial)
    return options;
  const label = labelof(v);
  if (interval == null) {
    let V;
    const kv = { transform: (data) => V || (V = valueof(data, value)), label };
    return {
      ...options,
      [k]: void 0,
      [`${k}1`]: v1 === void 0 ? kv : v1,
      [`${k}2`]: v2 === void 0 ? kv : v2
    };
  }
  let D1, V1;
  function transform(data) {
    if (V1 !== void 0 && data === D1)
      return V1;
    return V1 = map2(valueof(D1 = data, value), (v3) => interval.floor(v3));
  }
  return maybeInsetK({
    ...options,
    [k]: void 0,
    [`${k}1`]: v1 === void 0 ? { transform, label } : v1,
    [`${k}2`]: v2 === void 0 ? { transform: (data) => transform(data).map((v3) => interval.offset(v3)), label } : v2
  });
}
function maybeIntervalMidK(k, maybeInsetK, options) {
  const { [k]: v } = options;
  const { value, interval } = maybeIntervalValue(v, options);
  if (value == null || interval == null)
    return options;
  return maybeInsetK({
    ...options,
    [k]: {
      label: labelof(v),
      transform: (data) => {
        const V1 = map2(valueof(data, value), (v2) => interval.floor(v2));
        const V2 = V1.map((v2) => interval.offset(v2));
        return V1.map(isTemporal(V1) ? (v1, v2) => v1 == null || isNaN(v1 = +v1) || (v2 = V2[v2], v2 == null) || isNaN(v2 = +v2) ? void 0 : new Date((v1 + v2) / 2) : (v1, v2) => v1 == null || (v2 = V2[v2], v2 == null) ? NaN : (+v1 + +v2) / 2);
      }
    }
  });
}
function maybeTrivialIntervalX(options = {}) {
  return maybeIntervalK("x", maybeInsetX, options, true);
}
function maybeTrivialIntervalY(options = {}) {
  return maybeIntervalK("y", maybeInsetY, options, true);
}
function maybeIntervalX(options = {}) {
  return maybeIntervalK("x", maybeInsetX, options);
}
function maybeIntervalY(options = {}) {
  return maybeIntervalK("y", maybeInsetY, options);
}
function maybeIntervalMidX(options = {}) {
  return maybeIntervalMidK("x", maybeInsetX, options);
}
function maybeIntervalMidY(options = {}) {
  return maybeIntervalMidK("y", maybeInsetY, options);
}

// ../../node_modules/@observablehq/plot/dist/marks/bar.js
var AbstractBar = class extends Mark {
  constructor(data, channels, options = {}, defaults21) {
    super(data, channels, options, defaults21);
    const { inset = 0, insetTop = inset, insetRight = inset, insetBottom = inset, insetLeft = inset, rx, ry } = options;
    this.insetTop = number(insetTop);
    this.insetRight = number(insetRight);
    this.insetBottom = number(insetBottom);
    this.insetLeft = number(insetLeft);
    this.rx = impliedString(rx, "auto");
    this.ry = impliedString(ry, "auto");
  }
  render(index, scales, channels, dimensions, context) {
    const { rx, ry } = this;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(this._transform, this, scales).call((g) => g.selectAll().data(index).enter().append("rect").call(applyDirectStyles, this).attr("x", this._x(scales, channels, dimensions)).attr("width", this._width(scales, channels, dimensions)).attr("y", this._y(scales, channels, dimensions)).attr("height", this._height(scales, channels, dimensions)).call(applyAttr, "rx", rx).call(applyAttr, "ry", ry).call(applyChannelStyles, this, channels)).node();
  }
  _x(scales, { x: X }, { marginLeft }) {
    const { insetLeft } = this;
    return X ? (i) => X[i] + insetLeft : marginLeft + insetLeft;
  }
  _y(scales, { y: Y }, { marginTop }) {
    const { insetTop } = this;
    return Y ? (i) => Y[i] + insetTop : marginTop + insetTop;
  }
  _width({ x }, { x: X }, { marginRight, marginLeft, width }) {
    const { insetLeft, insetRight } = this;
    const bandwidth = X && x ? x.bandwidth() : width - marginRight - marginLeft;
    return Math.max(0, bandwidth - insetLeft - insetRight);
  }
  _height({ y }, { y: Y }, { marginTop, marginBottom, height }) {
    const { insetTop, insetBottom } = this;
    const bandwidth = Y && y ? y.bandwidth() : height - marginTop - marginBottom;
    return Math.max(0, bandwidth - insetTop - insetBottom);
  }
};
var defaults4 = {
  ariaLabel: "bar"
};
var BarX = class extends AbstractBar {
  constructor(data, options = {}) {
    const { x1, x2, y } = options;
    super(data, {
      x1: { value: x1, scale: "x" },
      x2: { value: x2, scale: "x" },
      y: { value: y, scale: "y", type: "band", optional: true }
    }, options, defaults4);
  }
  _transform(selection, mark, { x }) {
    selection.call(applyTransform, mark, { x }, 0, 0);
  }
  _x({ x }, { x1: X1, x2: X2 }, { marginLeft }) {
    const { insetLeft } = this;
    return isCollapsed(x) ? marginLeft + insetLeft : (i) => Math.min(X1[i], X2[i]) + insetLeft;
  }
  _width({ x }, { x1: X1, x2: X2 }, { marginRight, marginLeft, width }) {
    const { insetLeft, insetRight } = this;
    return isCollapsed(x) ? width - marginRight - marginLeft - insetLeft - insetRight : (i) => Math.max(0, Math.abs(X2[i] - X1[i]) - insetLeft - insetRight);
  }
};
var BarY = class extends AbstractBar {
  constructor(data, options = {}) {
    const { x, y1, y2 } = options;
    super(data, {
      y1: { value: y1, scale: "y" },
      y2: { value: y2, scale: "y" },
      x: { value: x, scale: "x", type: "band", optional: true }
    }, options, defaults4);
  }
  _transform(selection, mark, { y }) {
    selection.call(applyTransform, mark, { y }, 0, 0);
  }
  _y({ y }, { y1: Y1, y2: Y2 }, { marginTop }) {
    const { insetTop } = this;
    return isCollapsed(y) ? marginTop + insetTop : (i) => Math.min(Y1[i], Y2[i]) + insetTop;
  }
  _height({ y }, { y1: Y1, y2: Y2 }, { marginTop, marginBottom, height }) {
    const { insetTop, insetBottom } = this;
    return isCollapsed(y) ? height - marginTop - marginBottom - insetTop - insetBottom : (i) => Math.max(0, Math.abs(Y2[i] - Y1[i]) - insetTop - insetBottom);
  }
};
function barX(data, options = { y: indexOf, x2: identity2 }) {
  return new BarX(data, maybeStackX(maybeIntervalX(maybeIdentityX(options))));
}
function barY(data, options = { x: indexOf, y2: identity2 }) {
  return new BarY(data, maybeStackY(maybeIntervalY(maybeIdentityY(options))));
}

// ../../node_modules/@observablehq/plot/dist/transforms/map.js
function mapX(map4, options = {}) {
  return mapAlias(Object.fromEntries(["x", "x1", "x2"].filter((key) => options[key] != null).map((key) => [key, map4])), options);
}
function mapY(map4, options = {}) {
  return mapAlias(Object.fromEntries(["y", "y1", "y2"].filter((key) => options[key] != null).map((key) => [key, map4])), options);
}
function map3(outputs = {}, options = {}) {
  const z = maybeZ(options);
  const channels = Object.entries(outputs).map(([key, map4]) => {
    const input = maybeInput(key, options);
    if (input == null)
      throw new Error(`missing channel: ${key}`);
    const [output, setOutput] = column(input);
    return { key, input, output, setOutput, map: maybeMap(map4) };
  });
  return {
    ...basic(options, (data, facets) => {
      const Z = valueof(data, z);
      const X = channels.map(({ input }) => valueof(data, input));
      const MX = channels.map(({ setOutput }) => setOutput(new Array(data.length)));
      for (const facet of facets) {
        for (const I of Z ? group(facet, (i) => Z[i]).values() : [facet]) {
          channels.forEach(({ map: map4 }, i) => map4.map(I, X[i], MX[i]));
        }
      }
      return { data, facets };
    }),
    ...Object.fromEntries(channels.map(({ key, output }) => [key, output]))
  };
}
var mapAlias = map3;
function maybeMap(map4) {
  if (map4 && typeof map4.map === "function")
    return map4;
  if (typeof map4 === "function")
    return mapFunction(map4);
  switch (`${map4}`.toLowerCase()) {
    case "cumsum":
      return mapCumsum;
    case "rank":
      return mapFunction(rank);
    case "quantile":
      return mapFunction(rankQuantile);
  }
  throw new Error(`invalid map: ${map4}`);
}
function rankQuantile(V) {
  const n = count(V) - 1;
  return rank(V).map((r) => r / n);
}
function mapFunction(f) {
  return {
    map(I, S, T) {
      const M = f(take(S, I));
      if (M.length !== I.length)
        throw new Error("map function returned a mismatched length");
      for (let i = 0, n = I.length; i < n; ++i)
        T[I[i]] = M[i];
    }
  };
}
var mapCumsum = {
  map(I, S, T) {
    let sum2 = 0;
    for (const i of I)
      T[i] = sum2 += S[i];
  }
};

// ../../node_modules/@observablehq/plot/dist/template.js
function template(strings, ...parts) {
  let n = parts.length;
  for (let j = 0, copy = true; j < n; ++j) {
    if (typeof parts[j] !== "function") {
      if (copy) {
        strings = strings.slice();
        copy = false;
      }
      strings.splice(j, 2, strings[j] + parts[j] + strings[j + 1]);
      parts.splice(j, 1);
      --j, --n;
    }
  }
  return (i) => {
    let s = strings[0];
    for (let j = 0; j < n; ++j) {
      s += parts[j](i) + strings[j + 1];
    }
    return s;
  };
}

// ../../node_modules/@observablehq/plot/dist/marks/dot.js
var defaults5 = {
  ariaLabel: "dot",
  fill: "none",
  stroke: "currentColor",
  strokeWidth: 1.5
};
function withDefaultSort(options) {
  return options.sort === void 0 && options.reverse === void 0 ? sort2({ channel: "r", order: "descending" }, options) : options;
}
var Dot = class extends Mark {
  constructor(data, options = {}) {
    const { x, y, r, rotate, symbol: symbol2 = circle_default, frameAnchor } = options;
    const [vrotate, crotate] = maybeNumberChannel(rotate, 0);
    const [vsymbol, csymbol] = maybeSymbolChannel(symbol2);
    const [vr, cr] = maybeNumberChannel(r, vsymbol == null ? 3 : 4.5);
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      r: { value: vr, scale: "r", filter: positive, optional: true },
      rotate: { value: vrotate, optional: true },
      symbol: { value: vsymbol, scale: "symbol", optional: true }
    }, withDefaultSort(options), defaults5);
    this.r = cr;
    this.rotate = crotate;
    this.symbol = csymbol;
    this.frameAnchor = maybeFrameAnchor(frameAnchor);
    const { channels } = this;
    const { symbol: symbolChannel } = channels;
    if (symbolChannel) {
      const { fill: fillChannel, stroke: strokeChannel } = channels;
      symbolChannel.hint = {
        fill: fillChannel ? fillChannel.value === symbolChannel.value ? "color" : "currentColor" : this.fill,
        stroke: strokeChannel ? strokeChannel.value === symbolChannel.value ? "color" : "currentColor" : this.stroke
      };
    }
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x: X, y: Y, r: R, rotate: A, symbol: S } = channels;
    const { r, rotate, symbol: symbol2 } = this;
    const [cx, cy] = applyFrameAnchor(this, dimensions);
    const circle2 = this.symbol === circle_default;
    const size = R ? void 0 : r * r * Math.PI;
    if (negative(r))
      index = [];
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, { x: X && x, y: Y && y }).call((g) => g.selectAll().data(index).enter().append(circle2 ? "circle" : "path").call(applyDirectStyles, this).call(circle2 ? (selection) => {
      selection.attr("cx", X ? (i) => X[i] : cx).attr("cy", Y ? (i) => Y[i] : cy).attr("r", R ? (i) => R[i] : r);
    } : (selection) => {
      selection.attr("transform", template`translate(${X ? (i) => X[i] : cx},${Y ? (i) => Y[i] : cy})${A ? (i) => ` rotate(${A[i]})` : rotate ? ` rotate(${rotate})` : ``}`).attr("d", R && S ? (i) => {
        const p = pathRound();
        S[i].draw(p, R[i] * R[i] * Math.PI);
        return p;
      } : R ? (i) => {
        const p = pathRound();
        symbol2.draw(p, R[i] * R[i] * Math.PI);
        return p;
      } : S ? (i) => {
        const p = pathRound();
        S[i].draw(p, size);
        return p;
      } : (() => {
        const p = pathRound();
        symbol2.draw(p, size);
        return p;
      })());
    }).call(applyChannelStyles, this, channels)).node();
  }
};
function dot(data, options = {}) {
  let { x, y, ...remainingOptions } = options;
  if (options.frameAnchor === void 0)
    [x, y] = maybeTuple(x, y);
  return new Dot(data, { ...remainingOptions, x, y });
}
function dotX(data, options = {}) {
  const { x = identity2, ...remainingOptions } = options;
  return new Dot(data, maybeIntervalMidY({ ...remainingOptions, x }));
}
function dotY(data, options = {}) {
  const { y = identity2, ...remainingOptions } = options;
  return new Dot(data, maybeIntervalMidX({ ...remainingOptions, y }));
}
function circle(data, options) {
  return dot(data, { ...options, symbol: "circle" });
}
function hexagon(data, options) {
  return dot(data, { ...options, symbol: "hexagon" });
}

// ../../node_modules/@observablehq/plot/dist/marks/rule.js
var defaults6 = {
  ariaLabel: "rule",
  fill: null,
  stroke: "currentColor"
};
var RuleX = class extends Mark {
  constructor(data, options = {}) {
    const { x, y1, y2, inset = 0, insetTop = inset, insetBottom = inset } = options;
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y1: { value: y1, scale: "y", optional: true },
      y2: { value: y2, scale: "y", optional: true }
    }, options, defaults6);
    this.insetTop = number(insetTop);
    this.insetBottom = number(insetBottom);
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x: X, y1: Y1, y2: Y2 } = channels;
    const { width, height, marginTop, marginRight, marginLeft, marginBottom } = dimensions;
    const { insetTop, insetBottom } = this;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions).call(applyTransform, this, { x: X && x }, offset, 0).call((g) => g.selectAll().data(index).enter().append("line").call(applyDirectStyles, this).attr("x1", X ? (i) => X[i] : (marginLeft + width - marginRight) / 2).attr("x2", X ? (i) => X[i] : (marginLeft + width - marginRight) / 2).attr("y1", Y1 && !isCollapsed(y) ? (i) => Y1[i] + insetTop : marginTop + insetTop).attr("y2", Y2 && !isCollapsed(y) ? y.bandwidth ? (i) => Y2[i] + y.bandwidth() - insetBottom : (i) => Y2[i] - insetBottom : height - marginBottom - insetBottom).call(applyChannelStyles, this, channels)).node();
  }
};
var RuleY = class extends Mark {
  constructor(data, options = {}) {
    const { x1, x2, y, inset = 0, insetRight = inset, insetLeft = inset } = options;
    super(data, {
      y: { value: y, scale: "y", optional: true },
      x1: { value: x1, scale: "x", optional: true },
      x2: { value: x2, scale: "x", optional: true }
    }, options, defaults6);
    this.insetRight = number(insetRight);
    this.insetLeft = number(insetLeft);
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { y: Y, x1: X1, x2: X2 } = channels;
    const { width, height, marginTop, marginRight, marginLeft, marginBottom } = dimensions;
    const { insetLeft, insetRight } = this;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, { y: Y && y }, 0, offset).call((g) => g.selectAll().data(index).enter().append("line").call(applyDirectStyles, this).attr("x1", X1 && !isCollapsed(x) ? (i) => X1[i] + insetLeft : marginLeft + insetLeft).attr("x2", X2 && !isCollapsed(x) ? x.bandwidth ? (i) => X2[i] + x.bandwidth() - insetRight : (i) => X2[i] - insetRight : width - marginRight - insetRight).attr("y1", Y ? (i) => Y[i] : (marginTop + height - marginBottom) / 2).attr("y2", Y ? (i) => Y[i] : (marginTop + height - marginBottom) / 2).call(applyChannelStyles, this, channels)).node();
  }
};
function ruleX(data, options) {
  let { x = identity2, y, y1, y2, ...rest } = maybeIntervalY(options);
  [y1, y2] = maybeOptionalZero(y, y1, y2);
  return new RuleX(data, { ...rest, x, y1, y2 });
}
function ruleY(data, options) {
  let { y = identity2, x, x1, x2, ...rest } = maybeIntervalX(options);
  [x1, x2] = maybeOptionalZero(x, x1, x2);
  return new RuleY(data, { ...rest, y, x1, x2 });
}
function maybeOptionalZero(x, x1, x2) {
  if (x === void 0) {
    if (x1 === void 0) {
      if (x2 !== void 0)
        return [0, x2];
    } else {
      if (x2 === void 0)
        return [0, x1];
    }
  } else if (x1 === void 0) {
    return x2 === void 0 ? [0, x] : [x, x2];
  } else if (x2 === void 0) {
    return [x, x1];
  }
  return [x1, x2];
}

// ../../node_modules/@observablehq/plot/dist/marks/tick.js
var defaults7 = {
  ariaLabel: "tick",
  fill: null,
  stroke: "currentColor"
};
var AbstractTick = class extends Mark {
  constructor(data, channels, options) {
    super(data, channels, options, defaults7);
  }
  render(index, scales, channels, dimensions, context) {
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(this._transform, this, scales).call((g) => g.selectAll().data(index).enter().append("line").call(applyDirectStyles, this).attr("x1", this._x1(scales, channels, dimensions)).attr("x2", this._x2(scales, channels, dimensions)).attr("y1", this._y1(scales, channels, dimensions)).attr("y2", this._y2(scales, channels, dimensions)).call(applyChannelStyles, this, channels)).node();
  }
};
var TickX = class extends AbstractTick {
  constructor(data, options = {}) {
    const { x, y, inset = 0, insetTop = inset, insetBottom = inset } = options;
    super(data, {
      x: { value: x, scale: "x" },
      y: { value: y, scale: "y", type: "band", optional: true }
    }, options);
    this.insetTop = number(insetTop);
    this.insetBottom = number(insetBottom);
  }
  _transform(selection, mark, { x }) {
    selection.call(applyTransform, mark, { x }, offset, 0);
  }
  _x1(scales, { x: X }) {
    return (i) => X[i];
  }
  _x2(scales, { x: X }) {
    return (i) => X[i];
  }
  _y1({ y }, { y: Y }, { marginTop }) {
    const { insetTop } = this;
    return Y && y ? (i) => Y[i] + insetTop : marginTop + insetTop;
  }
  _y2({ y }, { y: Y }, { height, marginBottom }) {
    const { insetBottom } = this;
    return Y && y ? (i) => Y[i] + y.bandwidth() - insetBottom : height - marginBottom - insetBottom;
  }
};
var TickY = class extends AbstractTick {
  constructor(data, options = {}) {
    const { x, y, inset = 0, insetRight = inset, insetLeft = inset } = options;
    super(data, {
      y: { value: y, scale: "y" },
      x: { value: x, scale: "x", type: "band", optional: true }
    }, options);
    this.insetRight = number(insetRight);
    this.insetLeft = number(insetLeft);
  }
  _transform(selection, mark, { y }) {
    selection.call(applyTransform, mark, { y }, 0, offset);
  }
  _x1({ x }, { x: X }, { marginLeft }) {
    const { insetLeft } = this;
    return X && x ? (i) => X[i] + insetLeft : marginLeft + insetLeft;
  }
  _x2({ x }, { x: X }, { width, marginRight }) {
    const { insetRight } = this;
    return X && x ? (i) => X[i] + x.bandwidth() - insetRight : width - marginRight - insetRight;
  }
  _y1(scales, { y: Y }) {
    return (i) => Y[i];
  }
  _y2(scales, { y: Y }) {
    return (i) => Y[i];
  }
};
function tickX(data, options = {}) {
  const { x = identity2, ...remainingOptions } = options;
  return new TickX(data, { ...remainingOptions, x });
}
function tickY(data, options = {}) {
  const { y = identity2, ...remainingOptions } = options;
  return new TickY(data, { ...remainingOptions, y });
}

// ../../node_modules/@observablehq/plot/dist/marks/box.js
function boxX(data, options = {}) {
  const { x = { transform: (x2) => x2 }, y = null, fill = "#ccc", fillOpacity, stroke = "currentColor", strokeOpacity, strokeWidth = 2, sort: sort3, ...remainingOptions } = options;
  const group3 = y != null ? groupY : groupZ;
  return marks(ruleY(data, group3({ x1: loqr1, x2: hiqr2 }, { x, y, stroke, strokeOpacity, ...remainingOptions })), barX(data, group3({ x1: "p25", x2: "p75" }, { x, y, fill, fillOpacity, ...remainingOptions })), tickX(data, group3({ x: "p50" }, { x, y, stroke, strokeOpacity, strokeWidth, sort: sort3, ...remainingOptions })), dot(data, map3({ x: oqr }, { x, y, z: y, stroke, strokeOpacity, ...remainingOptions })));
}
function boxY(data, options = {}) {
  const { y = { transform: (y2) => y2 }, x = null, fill = "#ccc", fillOpacity, stroke = "currentColor", strokeOpacity, strokeWidth = 2, sort: sort3, ...remainingOptions } = options;
  const group3 = x != null ? groupX : groupZ;
  return marks(ruleX(data, group3({ y1: loqr1, y2: hiqr2 }, { x, y, stroke, strokeOpacity, ...remainingOptions })), barY(data, group3({ y1: "p25", y2: "p75" }, { x, y, fill, fillOpacity, ...remainingOptions })), tickY(data, group3({ y: "p50" }, { x, y, stroke, strokeOpacity, strokeWidth, sort: sort3, ...remainingOptions })), dot(data, map3({ y: oqr }, { x, y, z: x, stroke, strokeOpacity, ...remainingOptions })));
}
function oqr(values2) {
  const r1 = loqr1(values2);
  const r2 = hiqr2(values2);
  return values2.map((v) => v < r1 || v > r2 ? v : NaN);
}
function loqr1(values2, value) {
  const lo = quartile1(values2, value) * 2.5 - quartile3(values2, value) * 1.5;
  return min(values2, (d) => d >= lo ? d : NaN);
}
function hiqr2(values2, value) {
  const hi = quartile3(values2, value) * 2.5 - quartile1(values2, value) * 1.5;
  return max(values2, (d) => d <= hi ? d : NaN);
}
function quartile1(values2, value) {
  return quantile(values2, 0.25, value);
}
function quartile3(values2, value) {
  return quantile(values2, 0.75, value);
}

// ../../node_modules/@observablehq/plot/dist/marks/cell.js
var defaults8 = {
  ariaLabel: "cell"
};
var Cell = class extends AbstractBar {
  constructor(data, { x, y, ...options } = {}) {
    super(data, {
      x: { value: x, scale: "x", type: "band", optional: true },
      y: { value: y, scale: "y", type: "band", optional: true }
    }, options, defaults8);
  }
  _transform(selection, mark) {
    selection.call(applyTransform, mark, {}, 0, 0);
  }
};
function cell(data, options = {}) {
  let { x, y, ...remainingOptions } = options;
  [x, y] = maybeTuple(x, y);
  return new Cell(data, { ...remainingOptions, x, y });
}
function cellX(data, options = {}) {
  let { x = indexOf, fill, stroke, ...remainingOptions } = options;
  if (fill === void 0 && maybeColorChannel(stroke)[0] === void 0)
    fill = identity2;
  return new Cell(data, { ...remainingOptions, x, fill, stroke });
}
function cellY(data, options = {}) {
  let { y = indexOf, fill, stroke, ...remainingOptions } = options;
  if (fill === void 0 && maybeColorChannel(stroke)[0] === void 0)
    fill = identity2;
  return new Cell(data, { ...remainingOptions, y, fill, stroke });
}

// ../../node_modules/@observablehq/plot/dist/marks/raster.js
var defaults9 = {
  ariaLabel: "raster",
  stroke: null,
  pixelSize: 1
};
function number2(input, name) {
  const x = +input;
  if (isNaN(x))
    throw new Error(`invalid ${name}: ${input}`);
  return x;
}
function integer(input, name) {
  const x = Math.floor(input);
  if (isNaN(x))
    throw new Error(`invalid ${name}: ${input}`);
  return x;
}
var AbstractRaster = class extends Mark {
  constructor(data, channels, options = {}, defaults21) {
    let { width, height, x, y, x1 = x == null ? 0 : void 0, y1 = y == null ? 0 : void 0, x2 = x == null ? width : void 0, y2 = y == null ? height : void 0, pixelSize = defaults21.pixelSize, blur = 0, interpolate } = options;
    if (width != null)
      width = integer(width, "width");
    if (height != null)
      height = integer(height, "height");
    if (x1 != null)
      x1 = number2(x1, "x1");
    if (y1 != null)
      y1 = number2(y1, "y1");
    if (x2 != null)
      x2 = number2(x2, "x2");
    if (y2 != null)
      y2 = number2(y2, "y2");
    if (x == null && (x1 == null || x2 == null))
      throw new Error("missing x");
    if (y == null && (y1 == null || y2 == null))
      throw new Error("missing y");
    if (data != null && width != null && height != null) {
      if (x === void 0 && x1 != null && x2 != null)
        x = denseX(x1, x2, width, height);
      if (y === void 0 && y1 != null && y2 != null)
        y = denseY(y1, y2, width, height);
    }
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      x1: { value: x1 == null ? null : [x1], scale: "x", optional: true, filter: null },
      y1: { value: y1 == null ? null : [y1], scale: "y", optional: true, filter: null },
      x2: { value: x2 == null ? null : [x2], scale: "x", optional: true, filter: null },
      y2: { value: y2 == null ? null : [y2], scale: "y", optional: true, filter: null },
      ...channels
    }, options, defaults21);
    this.width = width;
    this.height = height;
    this.pixelSize = number2(pixelSize, "pixelSize");
    this.blur = number2(blur, "blur");
    this.interpolate = x == null || y == null ? null : maybeInterpolate(interpolate);
  }
};
var Raster = class extends AbstractRaster {
  constructor(data, options = {}) {
    const { imageRendering } = options;
    if (data == null) {
      const { fill, fillOpacity } = options;
      if (maybeNumberChannel(fillOpacity)[0] !== void 0)
        options = sampler("fillOpacity", options);
      if (maybeColorChannel(fill)[0] !== void 0)
        options = sampler("fill", options);
    }
    super(data, void 0, options, defaults9);
    this.imageRendering = impliedString(imageRendering, "auto");
  }
  // Ignore the color scale, so the fill channel is returned unscaled.
  scale(channels, { color: color3, ...scales }, context) {
    return super.scale(channels, scales, context);
  }
  render(index, scales, channels, dimensions, context) {
    const { color: color3 } = scales;
    const { x: X, y: Y } = channels;
    const { document } = context;
    const [x1, y1, x2, y2] = renderBounds(channels, dimensions, context);
    const dx = x2 - x1;
    const dy = y2 - y1;
    const { pixelSize: k, width: w = Math.round(Math.abs(dx) / k), height: h = Math.round(Math.abs(dy) / k) } = this;
    const n = w * h;
    let { fill: F, fillOpacity: FO } = channels;
    let offset2 = 0;
    if (this.interpolate) {
      const kx = w / dx;
      const ky = h / dy;
      const IX = map2(X, (x) => (x - x1) * kx, Float64Array);
      const IY = map2(Y, (y) => (y - y1) * ky, Float64Array);
      if (F)
        F = this.interpolate(index, w, h, IX, IY, F);
      if (FO)
        FO = this.interpolate(index, w, h, IX, IY, FO);
    } else if (this.data == null && index)
      offset2 = index.fi * n;
    const canvas = document.createElement("canvas");
    canvas.width = w;
    canvas.height = h;
    const context2d = canvas.getContext("2d");
    const image2 = context2d.createImageData(w, h);
    const imageData = image2.data;
    let { r, g, b } = rgb(this.fill) ?? { r: 0, g: 0, b: 0 };
    let a = (this.fillOpacity ?? 1) * 255;
    for (let i = 0; i < n; ++i) {
      const j = i << 2;
      if (F) {
        const fi = color3(F[i + offset2]);
        if (fi == null) {
          imageData[j + 3] = 0;
          continue;
        }
        ({ r, g, b } = rgb(fi));
      }
      if (FO)
        a = FO[i + offset2] * 255;
      imageData[j + 0] = r;
      imageData[j + 1] = g;
      imageData[j + 2] = b;
      imageData[j + 3] = a;
    }
    if (this.blur > 0)
      blurImage(image2, this.blur);
    context2d.putImageData(image2, 0, 0);
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, scales).call((g2) => g2.append("image").attr("transform", `translate(${x1},${y1}) scale(${Math.sign(x2 - x1)},${Math.sign(y2 - y1)})`).attr("width", Math.abs(dx)).attr("height", Math.abs(dy)).attr("preserveAspectRatio", "none").call(applyAttr, "image-rendering", this.imageRendering).call(applyDirectStyles, this).attr("xlink:href", canvas.toDataURL())).node();
  }
};
function maybeTuples(k, data, options) {
  if (arguments.length < 3)
    options = data, data = null;
  let { x, y, [k]: z, ...rest } = options;
  if (x === void 0 && y === void 0 && isTuples(data)) {
    x = first, y = second2;
    if (z === void 0)
      z = third;
  }
  return [data, { ...rest, x, y, [k]: z }];
}
function raster() {
  const [data, options] = maybeTuples("fill", ...arguments);
  return new Raster(data, data == null || options.fill !== void 0 || options.fillOpacity !== void 0 ? options : { ...options, fill: identity2 });
}
function renderBounds({ x1, y1, x2, y2 }, dimensions, { projection }) {
  const { width, height, marginTop, marginRight, marginBottom, marginLeft } = dimensions;
  return [
    x1 && projection == null ? x1[0] : marginLeft,
    y1 && projection == null ? y1[0] : marginTop,
    x2 && projection == null ? x2[0] : width - marginRight,
    y2 && projection == null ? y2[0] : height - marginBottom
  ];
}
function rasterBounds({ x1, y1, x2, y2 }, scales, dimensions, context) {
  const channels = {};
  if (x1)
    channels.x1 = x1;
  if (y1)
    channels.y1 = y1;
  if (x2)
    channels.x2 = x2;
  if (y2)
    channels.y2 = y2;
  return renderBounds(valueObject(channels, scales), dimensions, context);
}
function sampler(name, options = {}) {
  const { [name]: value } = options;
  if (typeof value !== "function")
    throw new Error(`invalid ${name}: not a function`);
  return initializer({ ...options, [name]: void 0 }, function(data, facets, channels, scales, dimensions, context) {
    const { x, y } = scales;
    if (!x)
      throw new Error("missing scale: x");
    if (!y)
      throw new Error("missing scale: y");
    const [x1, y1, x2, y2] = rasterBounds(channels, scales, dimensions, context);
    const dx = x2 - x1;
    const dy = y2 - y1;
    const { pixelSize: k } = this;
    const { width: w = Math.round(Math.abs(dx) / k), height: h = Math.round(Math.abs(dy) / k) } = options;
    const V = new Array(w * h * (facets ? facets.length : 1));
    const kx = dx / w;
    const ky = dy / h;
    let i = 0;
    for (const facet of facets ?? [void 0]) {
      for (let yi = 0.5; yi < h; ++yi) {
        for (let xi = 0.5; xi < w; ++xi, ++i) {
          V[i] = value(x.invert(x1 + xi * kx), y.invert(y1 + yi * ky), facet);
        }
      }
    }
    return { data: V, facets, channels: { [name]: { value: V, scale: true } } };
  });
}
function maybeInterpolate(interpolate) {
  if (typeof interpolate === "function")
    return interpolate;
  if (interpolate == null)
    return interpolateNone;
  switch (`${interpolate}`.toLowerCase()) {
    case "none":
      return interpolateNone;
    case "nearest":
      return interpolateNearest;
    case "barycentric":
      return interpolatorBarycentric();
    case "random-walk":
      return interpolatorRandomWalk();
  }
  throw new Error(`invalid interpolate: ${interpolate}`);
}
function interpolateNone(index, width, height, X, Y, V) {
  const W = new Array(width * height);
  for (const i of index) {
    if (X[i] < 0 || X[i] >= width || Y[i] < 0 || Y[i] >= height)
      continue;
    W[Math.floor(Y[i]) * width + Math.floor(X[i])] = V[i];
  }
  return W;
}
function interpolatorBarycentric({ random = lcg(42) } = {}) {
  return (index, width, height, X, Y, V) => {
    const n = index.length;
    const nw = width >> 2;
    const nh = (height >> 2) - 1;
    const m = n + nw * 2 + nh * 2;
    const XY = new Float64Array(m * 2);
    for (let i2 = 0; i2 < n; ++i2)
      XY[i2 * 2] = X[index[i2]], XY[i2 * 2 + 1] = Y[index[i2]];
    let i = n;
    const addPoint = (x, y) => (XY[i * 2] = x, XY[i * 2 + 1] = y, i++);
    for (let j = 0; j <= nw; ++j)
      addPoint(j / nw * width, 0), addPoint(j / nw * width, height);
    for (let j = 0; j < nh; ++j)
      addPoint(width, j / nh * height), addPoint(0, j / nh * height);
    V = take(V, index);
    const delaunay = new Delaunay(XY.subarray(0, n * 2));
    for (let j = n, ij; j < m; ++j)
      V[j] = V[ij = delaunay.find(XY[j * 2], XY[j * 2 + 1], ij)];
    const { points, triangles } = new Delaunay(XY);
    const W = new V.constructor(width * height);
    const mix = mixer(V, random);
    for (let i2 = 0; i2 < triangles.length; i2 += 3) {
      const ta = triangles[i2];
      const tb = triangles[i2 + 1];
      const tc = triangles[i2 + 2];
      const Ax = points[2 * ta];
      const Bx = points[2 * tb];
      const Cx = points[2 * tc];
      const Ay = points[2 * ta + 1];
      const By = points[2 * tb + 1];
      const Cy = points[2 * tc + 1];
      const x1 = Math.min(Ax, Bx, Cx);
      const x2 = Math.max(Ax, Bx, Cx);
      const y1 = Math.min(Ay, By, Cy);
      const y2 = Math.max(Ay, By, Cy);
      const z = (By - Cy) * (Ax - Cx) + (Ay - Cy) * (Cx - Bx);
      if (!z)
        continue;
      const va = V[ta];
      const vb = V[tb];
      const vc = V[tc];
      for (let x = Math.floor(x1); x < x2; ++x) {
        for (let y = Math.floor(y1); y < y2; ++y) {
          if (x < 0 || x >= width || y < 0 || y >= height)
            continue;
          const xp = x + 0.5;
          const yp = y + 0.5;
          const ga = ((By - Cy) * (xp - Cx) + (yp - Cy) * (Cx - Bx)) / z;
          if (ga < 0)
            continue;
          const gb = ((Cy - Ay) * (xp - Cx) + (yp - Cy) * (Ax - Cx)) / z;
          if (gb < 0)
            continue;
          const gc = 1 - ga - gb;
          if (gc < 0)
            continue;
          W[x + width * y] = mix(va, ga, vb, gb, vc, gc, x, y);
        }
      }
    }
    return W;
  };
}
function interpolateNearest(index, width, height, X, Y, V) {
  const W = new V.constructor(width * height);
  const delaunay = Delaunay.from(index, (i) => X[i], (i) => Y[i]);
  let iy, ix;
  for (let y = 0.5, k = 0; y < height; ++y) {
    ix = iy;
    for (let x = 0.5; x < width; ++x, ++k) {
      ix = delaunay.find(x, y, ix);
      if (x === 0.5)
        iy = ix;
      W[k] = V[index[ix]];
    }
  }
  return W;
}
function interpolatorRandomWalk({ random = lcg(42), minDistance = 0.5, maxSteps = 2 } = {}) {
  return (index, width, height, X, Y, V) => {
    const W = new V.constructor(width * height);
    const delaunay = Delaunay.from(index, (i) => X[i], (i) => Y[i]);
    let iy, ix, iw;
    for (let y = 0.5, k = 0; y < height; ++y) {
      ix = iy;
      for (let x = 0.5; x < width; ++x, ++k) {
        let cx = x;
        let cy = y;
        iw = ix = delaunay.find(cx, cy, ix);
        if (x === 0.5)
          iy = ix;
        let distance;
        let step = 0;
        while ((distance = Math.hypot(X[index[iw]] - cx, Y[index[iw]] - cy)) > minDistance && step < maxSteps) {
          const angle = random(x, y, step) * 2 * Math.PI;
          cx += Math.cos(angle) * distance;
          cy += Math.sin(angle) * distance;
          iw = delaunay.find(cx, cy, iw);
          ++step;
        }
        W[k] = V[index[iw]];
      }
    }
    return W;
  };
}
function blend(a, ca, b, cb, c, cc) {
  return ca * a + cb * b + cc * c;
}
function pick(random) {
  return (a, ca, b, cb, c, cc, x, y) => {
    const u = random(x, y);
    return u < ca ? a : u < ca + cb ? b : c;
  };
}
function mixer(F, random) {
  return isNumeric(F) || isTemporal(F) ? blend : pick(random);
}
function denseX(x1, x2, width) {
  return {
    transform(data) {
      const n = data.length;
      const X = new Float64Array(n);
      const kx = (x2 - x1) / width;
      const x0 = x1 + kx / 2;
      for (let i = 0; i < n; ++i)
        X[i] = i % width * kx + x0;
      return X;
    }
  };
}
function denseY(y1, y2, width, height) {
  return {
    transform(data) {
      const n = data.length;
      const Y = new Float64Array(n);
      const ky = (y2 - y1) / height;
      const y0 = y1 + ky / 2;
      for (let i = 0; i < n; ++i)
        Y[i] = Math.floor(i / width) % height * ky + y0;
      return Y;
    }
  };
}

// ../../node_modules/@observablehq/plot/dist/marks/contour.js
var defaults10 = {
  ariaLabel: "contour",
  fill: "none",
  stroke: "currentColor",
  strokeMiterlimit: 1,
  pixelSize: 2
};
var Contour = class extends AbstractRaster {
  constructor(data, { smooth = true, value, ...options } = {}) {
    const channels = styles({}, options, defaults10);
    if (value === void 0) {
      for (const key in channels) {
        if (channels[key].value != null) {
          if (value !== void 0)
            throw new Error("ambiguous contour value");
          value = options[key];
          options[key] = "value";
        }
      }
    }
    if (value != null) {
      const v = { transform: (D) => D.map((d) => d.value), label: labelof(value) };
      for (const key in channels) {
        if (options[key] === "value") {
          options[key] = v;
        }
      }
    }
    if (data == null) {
      if (value == null)
        throw new Error("missing contour value");
      options = sampler("value", { value, ...options });
      value = null;
    } else {
      let { interpolate } = options;
      if (value === void 0)
        value = identity2;
      if (interpolate === void 0)
        options.interpolate = "nearest";
    }
    super(data, { value: { value, optional: true } }, contourGeometry(options), defaults10);
    const contourChannels = { geometry: { value: identity2 } };
    for (const key in this.channels) {
      const channel = this.channels[key];
      const { scale: scale2 } = channel;
      if (scale2 === "x" || scale2 === "y" || key === "value")
        continue;
      contourChannels[key] = channel;
      delete this.channels[key];
    }
    this.contourChannels = contourChannels;
    this.smooth = !!smooth;
  }
  filter(index, { x, y, value, ...channels }, values2) {
    return super.filter(index, channels, values2);
  }
  render(index, scales, channels, dimensions, context) {
    const { geometry: G } = channels;
    const path = path_default();
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, scales).call((g) => {
      g.selectAll().data(index).enter().append("path").call(applyDirectStyles, this).attr("d", (i) => path(G[i])).call(applyChannelStyles, this, channels);
    }).node();
  }
};
function contourGeometry({ thresholds, interval, ...options }) {
  thresholds = maybeThresholds(thresholds, interval, thresholdSturges);
  return initializer(options, function(data, facets, channels, scales, dimensions, context) {
    const [x1, y1, x2, y2] = rasterBounds(channels, scales, dimensions, context);
    const dx = x2 - x1;
    const dy = y2 - y1;
    const { pixelSize: k, width: w = Math.round(Math.abs(dx) / k), height: h = Math.round(Math.abs(dy) / k) } = this;
    const kx = w / dx;
    const ky = h / dy;
    const V = channels.value.value;
    const VV = [];
    if (this.interpolate) {
      const { x: X, y: Y } = Position(channels, scales, context);
      const IX = map(X, (x) => (x - x1) * kx, Float64Array);
      const IY = map(Y, (y) => (y - y1) * ky, Float64Array);
      const ichannels = [channels.x, channels.y, channels.value];
      const ivalues = [IX, IY, V];
      for (const facet of facets) {
        const index = this.filter(facet, ichannels, ivalues);
        VV.push(this.interpolate(index, w, h, IX, IY, V));
      }
    } else if (facets) {
      const n = w * h;
      const m = facets.length;
      for (let i = 0; i < m; ++i)
        VV.push(V.slice(i * n, i * n + n));
    } else {
      VV.push(V);
    }
    if (this.blur > 0)
      for (const V2 of VV)
        blur2({ data: V2, width: w, height: h }, this.blur);
    const T = maybeTicks2(thresholds, V, ...finiteExtent(VV));
    if (T === null)
      throw new Error(`unsupported thresholds: ${thresholds}`);
    const { contour: contour2 } = contours_default().size([w, h]).smooth(this.smooth);
    const contourData = [];
    const contourFacets = [];
    for (const V2 of VV)
      contourFacets.push(range(contourData.length, contourData.push(...T.map((t) => contour2(V2, t)))));
    for (const { coordinates } of contourData) {
      for (const rings of coordinates) {
        for (const ring of rings) {
          for (const point2 of ring) {
            point2[0] = point2[0] / kx + x1;
            point2[1] = point2[1] / ky + y1;
          }
        }
      }
    }
    return {
      data: contourData,
      facets: contourFacets,
      channels: Channels(this.contourChannels, contourData)
    };
  });
}
function maybeTicks2(thresholds, V, min2, max2) {
  if (typeof (thresholds == null ? void 0 : thresholds.range) === "function")
    return thresholds.range(thresholds.floor(min2), max2);
  if (typeof thresholds === "function")
    thresholds = thresholds(V, min2, max2);
  if (typeof thresholds !== "number")
    return arrayify(thresholds, Array);
  const tz = ticks(...nice(min2, max2, thresholds), thresholds);
  while (tz[tz.length - 1] >= max2)
    tz.pop();
  while (tz[1] < min2)
    tz.shift();
  return tz;
}
function contour() {
  return new Contour(...maybeTuples("value", ...arguments));
}
function finiteExtent(VV) {
  return [min(VV, (V) => min(V, finite2)), max(VV, (V) => max(V, finite2))];
}
function finite2(x) {
  return isFinite(x) ? x : NaN;
}

// ../../node_modules/@observablehq/plot/dist/marks/delaunay.js
var delaunayLinkDefaults = {
  ariaLabel: "delaunay link",
  fill: "none",
  stroke: "currentColor",
  strokeMiterlimit: 1
};
var delaunayMeshDefaults = {
  ariaLabel: "delaunay mesh",
  fill: null,
  stroke: "currentColor",
  strokeOpacity: 0.2
};
var hullDefaults = {
  ariaLabel: "hull",
  fill: "none",
  stroke: "currentColor",
  strokeWidth: 1.5,
  strokeMiterlimit: 1
};
var voronoiDefaults = {
  ariaLabel: "voronoi",
  fill: "none",
  stroke: "currentColor",
  strokeMiterlimit: 1
};
var voronoiMeshDefaults = {
  ariaLabel: "voronoi mesh",
  fill: null,
  stroke: "currentColor",
  strokeOpacity: 0.2
};
var DelaunayLink = class extends Mark {
  constructor(data, options = {}) {
    const { x, y, z, curve, tension } = options;
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      z: { value: z, optional: true }
    }, options, delaunayLinkDefaults);
    this.curve = Curve(curve, tension);
    markers(this, options);
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x: X, y: Y, z: Z } = channels;
    const { curve } = this;
    const [cx, cy] = applyFrameAnchor(this, dimensions);
    const xi = X ? (i) => X[i] : constant(cx);
    const yi = Y ? (i) => Y[i] : constant(cy);
    const mark = this;
    function links(index2) {
      let i = -1;
      const newIndex = [];
      const newChannels = {};
      for (const k in channels)
        newChannels[k] = [];
      const X1 = [];
      const X2 = [];
      const Y1 = [];
      const Y2 = [];
      function link2(ti, tj) {
        ti = index2[ti];
        tj = index2[tj];
        newIndex.push(++i);
        X1[i] = xi(ti);
        Y1[i] = yi(ti);
        X2[i] = xi(tj);
        Y2[i] = yi(tj);
        for (const k in channels)
          newChannels[k].push(channels[k][tj]);
      }
      const { halfedges, hull: hull2, triangles } = Delaunay.from(index2, xi, yi);
      for (let i2 = 0; i2 < halfedges.length; ++i2) {
        const j = halfedges[i2];
        if (j > i2)
          link2(triangles[i2], triangles[j]);
      }
      for (let i2 = 0; i2 < hull2.length; ++i2) {
        link2(hull2[i2], hull2[(i2 + 1) % hull2.length]);
      }
      select_default(this).selectAll().data(newIndex).join("path").call(applyDirectStyles, mark).attr("d", (i2) => {
        const p = pathRound();
        const c = curve(p);
        c.lineStart();
        c.point(X1[i2], Y1[i2]);
        c.point(X2[i2], Y2[i2]);
        c.lineEnd();
        return p;
      }).call(applyChannelStyles, mark, newChannels).call(applyMarkers, mark, newChannels);
    }
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, { x: X && x, y: Y && y }).call(Z ? (g) => g.selectAll().data(group(index, (i) => Z[i]).values()).enter().append("g").each(links) : (g) => g.datum(index).each(links)).node();
  }
};
var AbstractDelaunayMark = class extends Mark {
  constructor(data, options = {}, defaults21, zof = ({ z }) => z) {
    const { x, y } = options;
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      z: { value: zof(options), optional: true }
    }, options, defaults21);
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x: X, y: Y, z: Z } = channels;
    const [cx, cy] = applyFrameAnchor(this, dimensions);
    const xi = X ? (i) => X[i] : constant(cx);
    const yi = Y ? (i) => Y[i] : constant(cy);
    const mark = this;
    function mesh(index2) {
      const delaunay = Delaunay.from(index2, xi, yi);
      select_default(this).append("path").datum(index2[0]).call(applyDirectStyles, mark).attr("d", mark._render(delaunay, dimensions)).call(applyChannelStyles, mark, channels);
    }
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, { x: X && x, y: Y && y }).call(Z ? (g) => g.selectAll().data(group(index, (i) => Z[i]).values()).enter().append("g").each(mesh) : (g) => g.datum(index).each(mesh)).node();
  }
};
var DelaunayMesh = class extends AbstractDelaunayMark {
  constructor(data, options = {}) {
    super(data, options, delaunayMeshDefaults);
    this.fill = "none";
  }
  _render(delaunay) {
    return delaunay.render();
  }
};
var Hull = class extends AbstractDelaunayMark {
  constructor(data, options = {}) {
    super(data, options, hullDefaults, maybeZ);
  }
  _render(delaunay) {
    return delaunay.renderHull();
  }
};
var Voronoi = class extends Mark {
  constructor(data, options = {}) {
    const { x, y, z } = options;
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      z: { value: z, optional: true }
    }, options, voronoiDefaults);
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x: X, y: Y, z: Z } = channels;
    const [cx, cy] = applyFrameAnchor(this, dimensions);
    const xi = X ? (i) => X[i] : constant(cx);
    const yi = Y ? (i) => Y[i] : constant(cy);
    function cells(index2) {
      const delaunay = Delaunay.from(index2, xi, yi);
      const voronoi2 = voronoiof(delaunay, dimensions);
      select_default(this).selectAll().data(index2).enter().append("path").call(applyDirectStyles, this).attr("d", (_, i) => voronoi2.renderCell(i)).call(applyChannelStyles, this, channels);
    }
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, { x: X && x, y: Y && y }).call(Z ? (g) => g.selectAll().data(group(index, (i) => Z[i]).values()).enter().append("g").each(cells) : (g) => g.datum(index).each(cells)).node();
  }
};
var VoronoiMesh = class extends AbstractDelaunayMark {
  constructor(data, options) {
    super(data, options, voronoiMeshDefaults);
    this.fill = "none";
  }
  _render(delaunay, dimensions) {
    return voronoiof(delaunay, dimensions).render();
  }
};
function voronoiof(delaunay, dimensions) {
  const { width, height, marginTop, marginRight, marginBottom, marginLeft } = dimensions;
  return delaunay.voronoi([marginLeft, marginTop, width - marginRight, height - marginBottom]);
}
function delaunayMark(DelaunayMark, data, { x, y, ...options } = {}) {
  [x, y] = maybeTuple(x, y);
  return new DelaunayMark(data, { ...options, x, y });
}
function delaunayLink(data, options) {
  return delaunayMark(DelaunayLink, data, options);
}
function delaunayMesh(data, options) {
  return delaunayMark(DelaunayMesh, data, options);
}
function hull(data, options) {
  return delaunayMark(Hull, data, options);
}
function voronoi(data, options) {
  return delaunayMark(Voronoi, data, options);
}
function voronoiMesh(data, options) {
  return delaunayMark(VoronoiMesh, data, options);
}

// ../../node_modules/@observablehq/plot/dist/marks/density.js
var defaults11 = {
  ariaLabel: "density",
  fill: "none",
  stroke: "currentColor",
  strokeMiterlimit: 1
};
var Density = class extends Mark {
  constructor(data, { x, y, z, weight, fill, stroke, ...options } = {}) {
    const fillDensity = isDensity(fill) && (fill = "currentColor", true);
    const strokeDensity = isDensity(stroke) && (stroke = "currentColor", true);
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      z: { value: maybeZ({ z, fill, stroke }), optional: true },
      weight: { value: weight, optional: true }
    }, densityInitializer({ ...options, fill, stroke }, fillDensity, strokeDensity), defaults11);
    if (fillDensity)
      this.fill = void 0;
    if (strokeDensity)
      this.stroke = void 0;
    this.z = z;
  }
  filter(index) {
    return index;
  }
  render(index, scales, channels, dimensions, context) {
    const { contours } = channels;
    const path = path_default();
    return create_default("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, {}).call((g) => g.selectAll().data(index).enter().append("path").call(applyDirectStyles, this).call(applyChannelStyles, this, channels).attr("d", (i) => path(contours[i]))).node();
  }
};
function density(data, options = {}) {
  let { x, y, ...remainingOptions } = options;
  [x, y] = maybeTuple(x, y);
  return new Density(data, { ...remainingOptions, x, y });
}
var dropChannels = /* @__PURE__ */ new Set(["x", "y", "z", "weight"]);
function densityInitializer(options, fillDensity, strokeDensity) {
  const k = 100;
  let { bandwidth, thresholds } = options;
  bandwidth = bandwidth === void 0 ? 20 : +bandwidth;
  thresholds = thresholds === void 0 ? 20 : typeof (thresholds == null ? void 0 : thresholds[Symbol.iterator]) === "function" ? coerceNumbers(thresholds) : +thresholds;
  return initializer(options, function(data, facets, channels, scales, dimensions, context) {
    var _a;
    const W = channels.weight ? coerceNumbers(channels.weight.value) : null;
    const Z = (_a = channels.z) == null ? void 0 : _a.value;
    const { z } = this;
    const [cx, cy] = applyFrameAnchor(this, dimensions);
    const { width, height } = dimensions;
    const { x: X, y: Y } = Position(channels, scales, context);
    const newChannels = Object.fromEntries(Object.entries(channels).filter(([key]) => !dropChannels.has(key)).map(([key, channel]) => [key, { ...channel, value: [] }]));
    const FD = fillDensity && [];
    const SD = strokeDensity && [];
    const density2 = density_default().x(X ? (i) => X[i] : cx).y(Y ? (i) => Y[i] : cy).weight(W ? (i) => W[i] : 1).size([width, height]).bandwidth(bandwidth);
    const facetsContours = [];
    for (const facet of facets) {
      const facetContours = [];
      facetsContours.push(facetContours);
      for (const index of Z ? groupZ2(facet, Z, z) : [facet]) {
        const contour2 = density2.contours(index);
        facetContours.push([index, contour2]);
      }
    }
    let T = thresholds;
    if (!isTypedArray(T)) {
      let maxValue = 0;
      for (const facetContours of facetsContours) {
        for (const [, contour2] of facetContours) {
          const max2 = contour2.max;
          if (max2 > maxValue)
            maxValue = max2;
        }
      }
      T = Float64Array.from({ length: thresholds - 1 }, (_, i) => maxValue * k * (i + 1) / thresholds);
    }
    const newFacets = [];
    const contours = [];
    for (const facetContours of facetsContours) {
      const newFacet = [];
      newFacets.push(newFacet);
      for (const [index, contour2] of facetContours) {
        for (const t of T) {
          newFacet.push(contours.length);
          contours.push(contour2(t / k));
          if (FD)
            FD.push(t);
          if (SD)
            SD.push(t);
          for (const key in newChannels) {
            newChannels[key].value.push(channels[key].value[index[0]]);
          }
        }
      }
    }
    if (FD)
      FD.push(0);
    if (SD)
      SD.push(0);
    return {
      data,
      facets: newFacets,
      channels: {
        ...newChannels,
        ...FD && { fill: { value: FD, scale: "color" } },
        ...SD && { stroke: { value: SD, scale: "color" } },
        contours: { value: contours }
      }
    };
  });
}
function isDensity(value) {
  return /^density$/i.test(value);
}

// ../../node_modules/@observablehq/plot/dist/marks/frame.js
var defaults12 = {
  ariaLabel: "frame",
  fill: "none",
  stroke: "currentColor"
};
var Frame = class extends Mark {
  constructor(options = {}) {
    const { inset = 0, insetTop = inset, insetRight = inset, insetBottom = inset, insetLeft = inset, rx, ry } = options;
    super(void 0, void 0, options, defaults12);
    this.insetTop = number(insetTop);
    this.insetRight = number(insetRight);
    this.insetBottom = number(insetBottom);
    this.insetLeft = number(insetLeft);
    this.rx = number(rx);
    this.ry = number(ry);
  }
  render(index, scales, channels, dimensions, context) {
    const { marginTop, marginRight, marginBottom, marginLeft, width, height } = dimensions;
    const { insetTop, insetRight, insetBottom, insetLeft, rx, ry } = this;
    return create("svg:rect", context).call(applyIndirectStyles, this, dimensions, context).call(applyDirectStyles, this).call(applyTransform, this, {}).attr("x", marginLeft + insetLeft).attr("y", marginTop + insetTop).attr("width", width - marginLeft - marginRight - insetLeft - insetRight).attr("height", height - marginTop - marginBottom - insetTop - insetBottom).attr("rx", rx).attr("ry", ry).node();
  }
};
function frame(options) {
  return new Frame(options);
}

// ../../node_modules/@observablehq/plot/dist/marks/geo.js
var defaults13 = {
  ariaLabel: "geo",
  fill: "none",
  stroke: "currentColor",
  strokeWidth: 1,
  strokeLinecap: "round",
  strokeLinejoin: "round",
  strokeMiterlimit: 1
};
var Geo = class extends Mark {
  constructor(data, options = {}) {
    const [vr, cr] = maybeNumberChannel(options.r, 3);
    super(data, {
      geometry: { value: options.geometry },
      r: { value: vr, scale: "r", filter: positive, optional: true }
    }, withDefaultSort(options), defaults13);
    this.r = cr;
  }
  render(index, scales, channels, dimensions, context) {
    const { geometry: G, r: R } = channels;
    const path = path_default(context.projection ?? scaleProjection2(scales));
    const { r } = this;
    if (negative(r))
      index = [];
    else if (r !== void 0)
      path.pointRadius(r);
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, scales).call((g) => {
      g.selectAll().data(index).enter().append("path").call(applyDirectStyles, this).attr("d", R ? (i) => path.pointRadius(R[i])(G[i]) : (i) => path(G[i])).call(applyChannelStyles, this, channels);
    }).node();
  }
};
function scaleProjection2({ x: X, y: Y }) {
  if (X || Y) {
    X ?? (X = (x) => x);
    Y ?? (Y = (y) => y);
    return transform_default({
      point(x, y) {
        this.stream.point(X(x), Y(y));
      }
    });
  }
}
function geo(data, { geometry = identity2, ...options } = {}) {
  switch (data == null ? void 0 : data.type) {
    case "FeatureCollection":
      data = data.features;
      break;
    case "GeometryCollection":
      data = data.geometries;
      break;
    case "Feature":
    case "LineString":
    case "MultiLineString":
    case "MultiPoint":
    case "MultiPolygon":
    case "Point":
    case "Polygon":
    case "Sphere":
      data = [data];
      break;
  }
  return new Geo(data, { geometry, ...options });
}
function sphere({ strokeWidth = 1.5, ...options } = {}) {
  return geo({ type: "Sphere" }, { strokeWidth, ...options });
}
function graticule({ strokeOpacity = 0.1, ...options } = {}) {
  return geo(graticule10(), { strokeOpacity, ...options });
}

// ../../node_modules/@observablehq/plot/dist/transforms/hexbin.js
var ox = 0.5;
var oy = 0;
function hexbin(outputs = { fill: "count" }, { binWidth, ...options } = {}) {
  binWidth = binWidth === void 0 ? 20 : number(binWidth);
  outputs = maybeOutputs(outputs, options);
  const { z, fill, stroke } = options;
  if (stroke === void 0 && isNoneish(fill) && hasOutput(outputs, "fill"))
    options.stroke = "none";
  if (options.symbol === void 0)
    options.symbol = "hexagon";
  if (options.r === void 0 && !hasOutput(outputs, "r"))
    options.r = binWidth / 2;
  return initializer(options, (data, facets, channels, scales, _, context) => {
    let { x: X, y: Y, z: Z, fill: F, stroke: S, symbol: Q } = channels;
    if (X === void 0)
      throw new Error("missing channel: x");
    if (Y === void 0)
      throw new Error("missing channel: y");
    ({ x: X, y: Y } = Position(channels, scales, context));
    Z = Z ? Z.value : valueof(data, z);
    F = F == null ? void 0 : F.value;
    S = S == null ? void 0 : S.value;
    Q = Q == null ? void 0 : Q.value;
    const G = maybeSubgroup(outputs, { z: Z, fill: F, stroke: S, symbol: Q });
    const GZ = Z && [];
    const GF = F && [];
    const GS = S && [];
    const GQ = Q && [];
    const binFacets = [];
    const BX = [];
    const BY = [];
    let i = -1;
    for (const o of outputs)
      o.initialize(data);
    for (const facet of facets) {
      const binFacet = [];
      for (const o of outputs)
        o.scope("facet", facet);
      for (const [f, I] of maybeGroup(facet, G)) {
        for (const bin2 of hbin(I, X, Y, binWidth)) {
          binFacet.push(++i);
          BX.push(bin2.x);
          BY.push(bin2.y);
          if (Z)
            GZ.push(G === Z ? f : Z[bin2[0]]);
          if (F)
            GF.push(G === F ? f : F[bin2[0]]);
          if (S)
            GS.push(G === S ? f : S[bin2[0]]);
          if (Q)
            GQ.push(G === Q ? f : Q[bin2[0]]);
          for (const o of outputs)
            o.reduce(bin2);
        }
      }
      binFacets.push(binFacet);
    }
    const binChannels = {
      x: { value: BX },
      y: { value: BY },
      ...Z && { z: { value: GZ } },
      ...F && { fill: { value: GF, scale: true } },
      ...S && { stroke: { value: GS, scale: true } },
      ...Q && { symbol: { value: GQ, scale: true } },
      ...Object.fromEntries(outputs.map(({ name, output }) => [
        name,
        { scale: true, radius: name === "r" ? binWidth / 2 : void 0, value: output.transform() }
      ]))
    };
    return { data, facets: binFacets, channels: binChannels };
  });
}
function hbin(I, X, Y, dx) {
  const dy = dx * (1.5 / sqrt3);
  const bins = /* @__PURE__ */ new Map();
  for (const i of I) {
    let px = X[i], py = Y[i];
    if (isNaN(px) || isNaN(py))
      continue;
    let pj = Math.round(py = (py - oy) / dy), pi2 = Math.round(px = (px - ox) / dx - (pj & 1) / 2), py1 = py - pj;
    if (Math.abs(py1) * 3 > 1) {
      let px1 = px - pi2, pi22 = pi2 + (px < pi2 ? -1 : 1) / 2, pj2 = pj + (py < pj ? -1 : 1), px2 = px - pi22, py2 = py - pj2;
      if (px1 * px1 + py1 * py1 > px2 * px2 + py2 * py2)
        pi2 = pi22 + (pj & 1 ? 1 : -1) / 2, pj = pj2;
    }
    const key = `${pi2},${pj}`;
    let bin2 = bins.get(key);
    if (bin2 === void 0) {
      bins.set(key, bin2 = []);
      bin2.x = (pi2 + (pj & 1) / 2) * dx + ox;
      bin2.y = pj * dy + oy;
    }
    bin2.push(i);
  }
  return bins.values();
}

// ../../node_modules/@observablehq/plot/dist/marks/hexgrid.js
var defaults14 = {
  ariaLabel: "hexgrid",
  fill: "none",
  stroke: "currentColor",
  strokeOpacity: 0.1
};
function hexgrid(options) {
  return new Hexgrid(options);
}
var Hexgrid = class extends Mark {
  constructor({ binWidth = 20, clip = true, ...options } = {}) {
    super(void 0, void 0, { clip, ...options }, defaults14);
    this.binWidth = number(binWidth);
  }
  render(index, scales, channels, dimensions, context) {
    const { binWidth } = this;
    const { marginTop, marginRight, marginBottom, marginLeft, width, height } = dimensions;
    const x0 = marginLeft - ox, x1 = width - marginRight - ox, y0 = marginTop - oy, y1 = height - marginBottom - oy, rx = binWidth / 2, ry = rx * sqrt4_3, hy = ry / 2, wx = rx * 2, wy = ry * 1.5, i0 = Math.floor(x0 / wx), i1 = Math.ceil(x1 / wx), j0 = Math.floor((y0 + hy) / wy), j1 = Math.ceil((y1 - hy) / wy) + 1, path = `m0,${round(-ry)}l${round(rx)},${round(hy)}v${round(ry)}l${round(-rx)},${round(hy)}`;
    let d = path;
    for (let j = j0; j < j1; ++j) {
      for (let i = i0; i < i1; ++i) {
        d += `M${round(i * wx + (j & 1) * rx)},${round(j * wy)}${path}`;
      }
    }
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, {}, offset + ox, offset + oy).call((g) => g.append("path").call(applyDirectStyles, this).attr("d", d)).node();
  }
};
function round(x) {
  return Math.round(x * 1e3) / 1e3;
}

// ../../node_modules/@observablehq/plot/dist/marks/image.js
var defaults15 = {
  ariaLabel: "image",
  fill: null,
  stroke: null
};
function isPath(string2) {
  return /^\.*\//.test(string2);
}
function isUrl(string2) {
  return /^(blob|data|file|http|https):/i.test(string2);
}
function maybePathChannel(value) {
  return typeof value === "string" && (isPath(value) || isUrl(value)) ? [void 0, value] : [value, void 0];
}
var Image = class extends Mark {
  constructor(data, options = {}) {
    let { x, y, width, height, src, preserveAspectRatio, crossOrigin, frameAnchor } = options;
    if (width === void 0 && height !== void 0)
      width = height;
    else if (height === void 0 && width !== void 0)
      height = width;
    const [vs, cs] = maybePathChannel(src);
    const [vw, cw] = maybeNumberChannel(width, 16);
    const [vh, ch] = maybeNumberChannel(height, 16);
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      width: { value: vw, filter: positive, optional: true },
      height: { value: vh, filter: positive, optional: true },
      src: { value: vs, optional: true }
    }, options, defaults15);
    this.src = cs;
    this.width = cw;
    this.height = ch;
    this.preserveAspectRatio = impliedString(preserveAspectRatio, "xMidYMid");
    this.crossOrigin = string(crossOrigin);
    this.frameAnchor = maybeFrameAnchor(frameAnchor);
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x: X, y: Y, width: W, height: H, src: S } = channels;
    const [cx, cy] = applyFrameAnchor(this, dimensions);
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, { x: X && x, y: Y && y }).call((g) => g.selectAll().data(index).enter().append("image").call(applyDirectStyles, this).attr("x", W && X ? (i) => X[i] - W[i] / 2 : W ? (i) => cx - W[i] / 2 : X ? (i) => X[i] - this.width / 2 : cx - this.width / 2).attr("y", H && Y ? (i) => Y[i] - H[i] / 2 : H ? (i) => cy - H[i] / 2 : Y ? (i) => Y[i] - this.height / 2 : cy - this.height / 2).attr("width", W ? (i) => W[i] : this.width).attr("height", H ? (i) => H[i] : this.height).call(applyAttr, "href", S ? (i) => S[i] : this.src).call(applyAttr, "preserveAspectRatio", this.preserveAspectRatio).call(applyAttr, "crossorigin", this.crossOrigin).call(applyChannelStyles, this, channels)).node();
  }
};
function image(data, options = {}) {
  let { x, y, ...remainingOptions } = options;
  if (options.frameAnchor === void 0)
    [x, y] = maybeTuple(x, y);
  return new Image(data, { ...remainingOptions, x, y });
}

// ../../node_modules/@observablehq/plot/dist/marks/line.js
var defaults16 = {
  ariaLabel: "line",
  fill: "none",
  stroke: "currentColor",
  strokeWidth: 1.5,
  strokeLinecap: "round",
  strokeLinejoin: "round",
  strokeMiterlimit: 1
};
function curveAuto(context) {
  return linear_default(context);
}
function LineCurve({ curve = curveAuto, tension }) {
  return typeof curve !== "function" && `${curve}`.toLowerCase() === "auto" ? curveAuto : Curve(curve, tension);
}
var Line = class extends Mark {
  constructor(data, options = {}) {
    const { x, y, z } = options;
    super(data, {
      x: { value: x, scale: "x" },
      y: { value: y, scale: "y" },
      z: { value: maybeZ(options), optional: true }
    }, options, defaults16);
    this.z = z;
    this.curve = LineCurve(options);
    markers(this, options);
  }
  filter(index) {
    return index;
  }
  project(channels, values2, context) {
    if (this.curve !== curveAuto) {
      super.project(channels, values2, context);
    }
  }
  render(index, scales, channels, dimensions, context) {
    const { x: X, y: Y } = channels;
    const { curve } = this;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, scales).call((g) => g.selectAll().data(groupIndex(index, [X, Y], this, channels)).enter().append("path").call(applyDirectStyles, this).call(applyGroupedChannelStyles, this, channels).call(applyGroupedMarkers, this, channels).attr("d", curve === curveAuto && context.projection ? sphereLine(context.projection, X, Y) : line_default().curve(curve).defined((i) => i >= 0).x((i) => X[i]).y((i) => Y[i]))).node();
  }
};
function sphereLine(projection, X, Y) {
  const path = path_default(projection);
  X = coerceNumbers(X);
  Y = coerceNumbers(Y);
  return (I) => {
    let line2 = [];
    const lines = [line2];
    for (const i of I) {
      if (i === -1) {
        line2 = [];
        lines.push(line2);
      } else {
        line2.push([X[i], Y[i]]);
      }
    }
    return path({ type: "MultiLineString", coordinates: lines });
  };
}
function line(data, options = {}) {
  let { x, y, ...remainingOptions } = options;
  [x, y] = maybeTuple(x, y);
  return new Line(data, { ...remainingOptions, x, y });
}
function lineX(data, options = {}) {
  const { x = identity2, y = indexOf, ...remainingOptions } = options;
  return new Line(data, maybeDenseIntervalY({ ...remainingOptions, x, y }));
}
function lineY(data, options = {}) {
  const { x = indexOf, y = identity2, ...remainingOptions } = options;
  return new Line(data, maybeDenseIntervalX({ ...remainingOptions, x, y }));
}

// ../../node_modules/@observablehq/plot/dist/stats.js
function ibetainv(p, a, b) {
  var EPS = 1e-8;
  var a1 = a - 1;
  var b1 = b - 1;
  var j = 0;
  var lna, lnb, pp, t, u, err, x, al, h, w, afac;
  if (p <= 0)
    return 0;
  if (p >= 1)
    return 1;
  if (a >= 1 && b >= 1) {
    pp = p < 0.5 ? p : 1 - p;
    t = Math.sqrt(-2 * Math.log(pp));
    x = (2.30753 + t * 0.27061) / (1 + t * (0.99229 + t * 0.04481)) - t;
    if (p < 0.5)
      x = -x;
    al = (x * x - 3) / 6;
    h = 2 / (1 / (2 * a - 1) + 1 / (2 * b - 1));
    w = x * Math.sqrt(al + h) / h - (1 / (2 * b - 1) - 1 / (2 * a - 1)) * (al + 5 / 6 - 2 / (3 * h));
    x = a / (a + b * Math.exp(2 * w));
  } else {
    lna = Math.log(a / (a + b));
    lnb = Math.log(b / (a + b));
    t = Math.exp(a * lna) / a;
    u = Math.exp(b * lnb) / b;
    w = t + u;
    if (p < t / w)
      x = Math.pow(a * w * p, 1 / a);
    else
      x = 1 - Math.pow(b * w * (1 - p), 1 / b);
  }
  afac = -gammaln(a) - gammaln(b) + gammaln(a + b);
  for (; j < 10; j++) {
    if (x === 0 || x === 1)
      return x;
    err = ibeta(x, a, b) - p;
    t = Math.exp(a1 * Math.log(x) + b1 * Math.log(1 - x) + afac);
    u = err / t;
    x -= t = u / (1 - 0.5 * Math.min(1, u * (a1 / x - b1 / (1 - x))));
    if (x <= 0)
      x = 0.5 * (x + t);
    if (x >= 1)
      x = 0.5 * (x + t + 1);
    if (Math.abs(t) < EPS * x && j > 0)
      break;
  }
  return x;
}
function ibeta(x, a, b) {
  var bt = x === 0 || x === 1 ? 0 : Math.exp(gammaln(a + b) - gammaln(a) - gammaln(b) + a * Math.log(x) + b * Math.log(1 - x));
  if (x < 0 || x > 1)
    return false;
  if (x < (a + 1) / (a + b + 2))
    return bt * betacf(x, a, b) / a;
  return 1 - bt * betacf(1 - x, b, a) / b;
}
function betacf(x, a, b) {
  var fpmin = 1e-30;
  var m = 1;
  var qab = a + b;
  var qap = a + 1;
  var qam = a - 1;
  var c = 1;
  var d = 1 - qab * x / qap;
  var m2, aa, del, h;
  if (Math.abs(d) < fpmin)
    d = fpmin;
  d = 1 / d;
  h = d;
  for (; m <= 100; m++) {
    m2 = 2 * m;
    aa = m * (b - m) * x / ((qam + m2) * (a + m2));
    d = 1 + aa * d;
    if (Math.abs(d) < fpmin)
      d = fpmin;
    c = 1 + aa / c;
    if (Math.abs(c) < fpmin)
      c = fpmin;
    d = 1 / d;
    h *= d * c;
    aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
    d = 1 + aa * d;
    if (Math.abs(d) < fpmin)
      d = fpmin;
    c = 1 + aa / c;
    if (Math.abs(c) < fpmin)
      c = fpmin;
    d = 1 / d;
    del = d * c;
    h *= del;
    if (Math.abs(del - 1) < 3e-7)
      break;
  }
  return h;
}
function gammaln(x) {
  var j = 0;
  var cof = [
    76.18009172947146,
    -86.5053203294167,
    24.01409824083091,
    -1.231739572450155,
    0.001208650973866179,
    -5395239384953e-18
  ];
  var ser = 1.000000000190015;
  var xx, y, tmp;
  tmp = (y = xx = x) + 5.5;
  tmp -= (xx + 0.5) * Math.log(tmp);
  for (; j < 6; j++)
    ser += cof[j] / ++y;
  return Math.log(2.506628274631 * ser / xx) - tmp;
}
function qt(p, dof) {
  var x = ibetainv(2 * Math.min(p, 1 - p), 0.5 * dof, 0.5);
  x = Math.sqrt(dof * (1 - x) / x);
  return p > 0.5 ? x : -x;
}

// ../../node_modules/@observablehq/plot/dist/marks/linearRegression.js
var defaults17 = {
  ariaLabel: "linear-regression",
  fill: "currentColor",
  fillOpacity: 0.1,
  stroke: "currentColor",
  strokeWidth: 1.5,
  strokeLinecap: "round",
  strokeLinejoin: "round",
  strokeMiterlimit: 1
};
var LinearRegression = class extends Mark {
  constructor(data, options = {}) {
    const { x, y, z, ci = 0.95, precision = 4 } = options;
    super(data, {
      x: { value: x, scale: "x" },
      y: { value: y, scale: "y" },
      z: { value: maybeZ(options), optional: true }
    }, options, defaults17);
    this.z = z;
    this.ci = +ci;
    this.precision = +precision;
    if (!(0 <= this.ci && this.ci < 1))
      throw new Error(`invalid ci; not in [0, 1): ${ci}`);
    if (!(this.precision > 0))
      throw new Error(`invalid precision: ${precision}`);
  }
  render(index, scales, channels, dimensions, context) {
    const { x: X, y: Y, z: Z } = channels;
    const { ci } = this;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, scales).call((g) => g.selectAll().data(Z ? groupZ2(index, Z, this.z) : [index]).enter().call((enter) => enter.append("path").attr("fill", "none").call(applyDirectStyles, this).call(applyGroupedChannelStyles, this, { ...channels, fill: null, fillOpacity: null }).attr("d", (I) => this._renderLine(I, X, Y)).call(ci && !isNone(this.fill) ? (path) => path.select(pathBefore).attr("stroke", "none").call(applyDirectStyles, this).call(applyGroupedChannelStyles, this, {
      ...channels,
      stroke: null,
      strokeOpacity: null,
      strokeWidth: null
    }).attr("d", (I) => this._renderBand(I, X, Y)) : () => {
    }))).node();
  }
};
function pathBefore() {
  return this.parentNode.insertBefore(this.ownerDocument.createElementNS(namespaces_default.svg, "path"), this);
}
var LinearRegressionX = class extends LinearRegression {
  constructor(data, options) {
    super(data, options);
  }
  _renderBand(I, X, Y) {
    const { ci, precision } = this;
    const [y1, y2] = extent(I, (i) => Y[i]);
    const f = linearRegressionF(I, Y, X);
    const g = confidenceIntervalF(I, Y, X, (1 - ci) / 2, f);
    return area_default().y((y) => y).x0((y) => g(y, -1)).x1((y) => g(y, 1))(range(y1, y2 - precision / 2, precision).concat(y2));
  }
  _renderLine(I, X, Y) {
    const [y1, y2] = extent(I, (i) => Y[i]);
    const f = linearRegressionF(I, Y, X);
    return `M${f(y1)},${y1}L${f(y2)},${y2}`;
  }
};
var LinearRegressionY = class extends LinearRegression {
  constructor(data, options) {
    super(data, options);
  }
  _renderBand(I, X, Y) {
    const { ci, precision } = this;
    const [x1, x2] = extent(I, (i) => X[i]);
    const f = linearRegressionF(I, X, Y);
    const g = confidenceIntervalF(I, X, Y, (1 - ci) / 2, f);
    return area_default().x((x) => x).y0((x) => g(x, -1)).y1((x) => g(x, 1))(range(x1, x2 - precision / 2, precision).concat(x2));
  }
  _renderLine(I, X, Y) {
    const [x1, x2] = extent(I, (i) => X[i]);
    const f = linearRegressionF(I, X, Y);
    return `M${x1},${f(x1)}L${x2},${f(x2)}`;
  }
};
function linearRegressionX(data, options = {}) {
  const { y = indexOf, x = identity2, stroke, fill = isNoneish(stroke) ? "currentColor" : stroke, ...remainingOptions } = options;
  return new LinearRegressionX(data, maybeDenseIntervalY({ ...remainingOptions, x, y, fill, stroke }));
}
function linearRegressionY(data, options = {}) {
  const { x = indexOf, y = identity2, stroke, fill = isNoneish(stroke) ? "currentColor" : stroke, ...remainingOptions } = options;
  return new LinearRegressionY(data, maybeDenseIntervalX({ ...remainingOptions, x, y, fill, stroke }));
}
function linearRegressionF(I, X, Y) {
  let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
  for (const i of I) {
    const xi = X[i];
    const yi = Y[i];
    sumX += xi;
    sumY += yi;
    sumXY += xi * yi;
    sumX2 += xi * xi;
  }
  const n = I.length;
  const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
  const intercept = (sumY - slope * sumX) / n;
  return (x) => slope * x + intercept;
}
function confidenceIntervalF(I, X, Y, p, f) {
  const mean2 = sum(I, (i) => X[i]) / I.length;
  let a = 0, b = 0;
  for (const i of I) {
    a += (X[i] - mean2) ** 2;
    b += (Y[i] - f(X[i])) ** 2;
  }
  const sy = Math.sqrt(b / (I.length - 2));
  const t = qt(p, I.length - 2);
  return (x, k) => {
    const Y2 = f(x);
    const se = sy * Math.sqrt(1 / I.length + (x - mean2) ** 2 / a);
    return Y2 + k * t * se;
  };
}

// ../../node_modules/@observablehq/plot/dist/marks/rect.js
var defaults18 = {
  ariaLabel: "rect"
};
var Rect = class extends Mark {
  constructor(data, options = {}) {
    const { x1, y1, x2, y2, inset = 0, insetTop = inset, insetRight = inset, insetBottom = inset, insetLeft = inset, rx, ry } = options;
    super(data, {
      x1: { value: x1, scale: "x", optional: true },
      y1: { value: y1, scale: "y", optional: true },
      x2: { value: x2, scale: "x", optional: true },
      y2: { value: y2, scale: "y", optional: true }
    }, options, defaults18);
    this.insetTop = number(insetTop);
    this.insetRight = number(insetRight);
    this.insetBottom = number(insetBottom);
    this.insetLeft = number(insetLeft);
    this.rx = impliedString(rx, "auto");
    this.ry = impliedString(ry, "auto");
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x1: X1, y1: Y1, x2: X2, y2: Y2 } = channels;
    const { marginTop, marginRight, marginBottom, marginLeft, width, height } = dimensions;
    const { projection } = context;
    const { insetTop, insetRight, insetBottom, insetLeft, rx, ry } = this;
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, { x: X1 && X2 && x, y: Y1 && Y2 && y }, 0, 0).call((g) => g.selectAll().data(index).enter().append("rect").call(applyDirectStyles, this).attr("x", X1 && X2 && (projection || !isCollapsed(x)) ? (i) => Math.min(X1[i], X2[i]) + insetLeft : marginLeft + insetLeft).attr("y", Y1 && Y2 && (projection || !isCollapsed(y)) ? (i) => Math.min(Y1[i], Y2[i]) + insetTop : marginTop + insetTop).attr("width", X1 && X2 && (projection || !isCollapsed(x)) ? (i) => Math.max(0, Math.abs(X2[i] - X1[i]) - insetLeft - insetRight) : width - marginRight - marginLeft - insetRight - insetLeft).attr("height", Y1 && Y2 && (projection || !isCollapsed(y)) ? (i) => Math.max(0, Math.abs(Y1[i] - Y2[i]) - insetTop - insetBottom) : height - marginTop - marginBottom - insetTop - insetBottom).call(applyAttr, "rx", rx).call(applyAttr, "ry", ry).call(applyChannelStyles, this, channels)).node();
  }
};
function rect(data, options) {
  return new Rect(data, maybeTrivialIntervalX(maybeTrivialIntervalY(options)));
}
function rectX(data, options = { y: indexOf, interval: 1, x2: identity2 }) {
  return new Rect(data, maybeStackX(maybeTrivialIntervalY(maybeIdentityX(options))));
}
function rectY(data, options = { x: indexOf, interval: 1, y2: identity2 }) {
  return new Rect(data, maybeStackY(maybeTrivialIntervalX(maybeIdentityY(options))));
}

// ../../node_modules/@observablehq/plot/dist/marks/text.js
var defaults19 = {
  ariaLabel: "text",
  strokeLinejoin: "round",
  strokeWidth: 3,
  paintOrder: "stroke"
};
var Text = class extends Mark {
  constructor(data, options = {}) {
    const { x, y, text: text2 = isIterable(data) && isTextual(data) ? identity2 : indexOf, frameAnchor, textAnchor = /right$/i.test(frameAnchor) ? "end" : /left$/i.test(frameAnchor) ? "start" : "middle", lineAnchor = /^top/i.test(frameAnchor) ? "top" : /^bottom/i.test(frameAnchor) ? "bottom" : "middle", lineHeight = 1, lineWidth = Infinity, monospace, fontFamily = monospace ? "ui-monospace, monospace" : void 0, fontSize, fontStyle, fontVariant, fontWeight, rotate } = options;
    const [vrotate, crotate] = maybeNumberChannel(rotate, 0);
    const [vfontSize, cfontSize] = maybeFontSizeChannel(fontSize);
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      fontSize: { value: vfontSize, optional: true },
      rotate: { value: numberChannel(vrotate), optional: true },
      text: { value: text2, filter: nonempty }
    }, options, defaults19);
    this.rotate = crotate;
    this.textAnchor = impliedString(textAnchor, "middle");
    this.lineAnchor = keyword(lineAnchor, "lineAnchor", ["top", "middle", "bottom"]);
    this.lineHeight = +lineHeight;
    this.lineWidth = +lineWidth;
    this.monospace = !!monospace;
    this.fontFamily = string(fontFamily);
    this.fontSize = cfontSize;
    this.fontStyle = string(fontStyle);
    this.fontVariant = string(fontVariant);
    this.fontWeight = string(fontWeight);
    this.frameAnchor = maybeFrameAnchor(frameAnchor);
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x: X, y: Y, rotate: R, text: T, fontSize: FS } = channels;
    const { rotate } = this;
    const [cx, cy] = applyFrameAnchor(this, dimensions);
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyIndirectTextStyles, this, T, dimensions).call(applyTransform, this, { x: X && x, y: Y && y }).call((g) => g.selectAll().data(index).enter().append("text").call(applyDirectStyles, this).call(applyMultilineText, this, T).attr("transform", template`translate(${X ? (i) => X[i] : cx},${Y ? (i) => Y[i] : cy})${R ? (i) => ` rotate(${R[i]})` : rotate ? ` rotate(${rotate})` : ``}`).call(applyAttr, "font-size", FS && ((i) => FS[i])).call(applyChannelStyles, this, channels)).node();
  }
};
function applyMultilineText(selection, { monospace, lineAnchor, lineHeight, lineWidth }, T) {
  if (!T)
    return;
  const linesof = isFinite(lineWidth) ? monospace ? (t) => lineWrap(t, lineWidth, monospaceWidth) : (t) => lineWrap(t, lineWidth * 100, defaultWidth) : (t) => t.split(/\r\n?|\n/g);
  selection.each(function(i) {
    const lines = linesof(formatDefault(T[i]));
    const n = lines.length;
    const y = lineAnchor === "top" ? 0.71 : lineAnchor === "bottom" ? 1 - n : (164 - n * 100) / 200;
    if (n > 1) {
      for (let i2 = 0; i2 < n; ++i2) {
        if (!lines[i2])
          continue;
        const tspan = this.ownerDocument.createElementNS(namespaces_default.svg, "tspan");
        tspan.setAttribute("x", 0);
        tspan.setAttribute("y", `${(y + i2) * lineHeight}em`);
        tspan.textContent = lines[i2];
        this.appendChild(tspan);
      }
    } else {
      if (y)
        this.setAttribute("y", `${y * lineHeight}em`);
      this.textContent = lines[0];
    }
  });
}
function text(data, options = {}) {
  let { x, y, ...remainingOptions } = options;
  if (options.frameAnchor === void 0)
    [x, y] = maybeTuple(x, y);
  return new Text(data, { ...remainingOptions, x, y });
}
function textX(data, options = {}) {
  const { x = identity2, ...remainingOptions } = options;
  return new Text(data, maybeIntervalMidY({ ...remainingOptions, x }));
}
function textY(data, options = {}) {
  const { y = identity2, ...remainingOptions } = options;
  return new Text(data, maybeIntervalMidX({ ...remainingOptions, y }));
}
function applyIndirectTextStyles(selection, mark, T) {
  applyAttr(selection, "text-anchor", mark.textAnchor);
  applyAttr(selection, "font-family", mark.fontFamily);
  applyAttr(selection, "font-size", mark.fontSize);
  applyAttr(selection, "font-style", mark.fontStyle);
  applyAttr(selection, "font-variant", mark.fontVariant === void 0 && (isNumeric(T) || isTemporal(T)) ? "tabular-nums" : mark.fontVariant);
  applyAttr(selection, "font-weight", mark.fontWeight);
}
var fontSizes = /* @__PURE__ */ new Set([
  // global keywords
  "inherit",
  "initial",
  "revert",
  "unset",
  // absolute keywords
  "xx-small",
  "x-small",
  "small",
  "medium",
  "large",
  "x-large",
  "xx-large",
  "xxx-large",
  // relative keywords
  "larger",
  "smaller"
]);
function maybeFontSizeChannel(fontSize) {
  if (fontSize == null || typeof fontSize === "number")
    return [void 0, fontSize];
  if (typeof fontSize !== "string")
    return [fontSize, void 0];
  fontSize = fontSize.trim().toLowerCase();
  return fontSizes.has(fontSize) || /^[+-]?\d*\.?\d+(e[+-]?\d+)?(\w*|%)$/.test(fontSize) ? [void 0, fontSize] : [fontSize, void 0];
}
function lineWrap(input, maxWidth, widthof = (_, i, j) => j - i) {
  const lines = [];
  let lineStart, lineEnd = 0;
  for (const [wordStart, wordEnd, required] of lineBreaks(input)) {
    if (lineStart === void 0)
      lineStart = wordStart;
    if (lineEnd > lineStart && widthof(input, lineStart, wordEnd) > maxWidth) {
      lines.push(input.slice(lineStart, lineEnd));
      lineStart = wordStart;
    }
    if (required) {
      lines.push(input.slice(lineStart, wordEnd));
      lineStart = void 0;
      continue;
    }
    lineEnd = wordEnd;
  }
  return lines;
}
function* lineBreaks(input) {
  let i = 0, j = 0;
  const n = input.length;
  while (j < n) {
    let k = 1;
    switch (input[j]) {
      case "-":
        ++j;
        yield [i, j, false];
        i = j;
        break;
      case " ":
        yield [i, j, false];
        while (input[++j] === " ")
          ;
        i = j;
        break;
      case "\r":
        if (input[j + 1] === "\n")
          ++k;
      case "\n":
        yield [i, j, true];
        j += k;
        i = j;
        break;
      default:
        ++j;
        break;
    }
  }
  yield [i, j, true];
}
var defaultWidthMap = {
  a: 56,
  b: 63,
  c: 57,
  d: 63,
  e: 58,
  f: 37,
  g: 62,
  h: 60,
  i: 26,
  j: 26,
  k: 55,
  l: 26,
  m: 88,
  n: 60,
  o: 60,
  p: 62,
  q: 62,
  r: 39,
  s: 54,
  t: 38,
  u: 60,
  v: 55,
  w: 79,
  x: 54,
  y: 55,
  z: 55,
  A: 69,
  B: 67,
  C: 73,
  D: 74,
  E: 61,
  F: 58,
  G: 76,
  H: 75,
  I: 28,
  J: 55,
  K: 67,
  L: 58,
  M: 89,
  N: 75,
  O: 78,
  P: 65,
  Q: 78,
  R: 67,
  S: 65,
  T: 65,
  U: 75,
  V: 69,
  W: 98,
  X: 69,
  Y: 67,
  Z: 67,
  0: 64,
  1: 48,
  2: 62,
  3: 64,
  4: 66,
  5: 63,
  6: 65,
  7: 58,
  8: 65,
  9: 65,
  " ": 29,
  "!": 32,
  '"': 49,
  "'": 31,
  "(": 39,
  ")": 39,
  ",": 31,
  "-": 48,
  ".": 31,
  "/": 32,
  ":": 31,
  ";": 31,
  "?": 52,
  "‘": 31,
  "’": 31,
  "“": 47,
  "”": 47
};
function defaultWidth(text2, start, end) {
  let sum2 = 0;
  for (let i = start; i < end; ++i) {
    sum2 += defaultWidthMap[text2[i]] || defaultWidthMap.e;
    const first2 = text2.charCodeAt(i);
    if (first2 >= 55296 && first2 <= 56319) {
      const second3 = text2.charCodeAt(i + 1);
      if (second3 >= 56320 && second3 <= 57343) {
        ++i;
      }
    }
  }
  return sum2;
}
function monospaceWidth(text2, start, end) {
  return end - start;
}

// ../../node_modules/@observablehq/plot/dist/transforms/tree.js
function treeNode(options = {}) {
  let {
    path = identity2,
    // the delimited path
    delimiter,
    // how the path is separated
    frameAnchor,
    treeLayout = tree_default,
    treeSort,
    treeSeparation,
    treeAnchor,
    ...remainingOptions
  } = options;
  treeAnchor = maybeTreeAnchor(treeAnchor);
  treeSort = maybeTreeSort(treeSort);
  if (frameAnchor === void 0)
    frameAnchor = treeAnchor.frameAnchor;
  const normalize2 = normalizer(delimiter);
  const outputs = treeOutputs(remainingOptions, maybeNodeValue);
  const [X, setX] = column();
  const [Y, setY] = column();
  return {
    x: X,
    y: Y,
    frameAnchor,
    ...basic(remainingOptions, (data, facets) => {
      const P = normalize2(valueof(data, path));
      const X2 = setX([]);
      const Y2 = setY([]);
      let treeIndex = -1;
      const treeData = [];
      const treeFacets = [];
      const rootof = stratify_default().path((i) => P[i]);
      const layout = treeLayout();
      if (layout.nodeSize)
        layout.nodeSize([1, 1]);
      if (layout.separation && treeSeparation !== void 0)
        layout.separation(treeSeparation ?? one);
      for (const o of outputs)
        o[output_values] = o[output_setValues]([]);
      for (const facet of facets) {
        const treeFacet = [];
        const root = rootof(facet.filter((i) => P[i] != null)).each((node) => node.data = data[node.data]);
        if (treeSort != null)
          root.sort(treeSort);
        layout(root);
        for (const node of root.descendants()) {
          treeFacet.push(++treeIndex);
          treeData[treeIndex] = node.data;
          treeAnchor.position(node, treeIndex, X2, Y2);
          for (const o of outputs)
            o[output_values][treeIndex] = o[output_evaluate](node);
        }
        treeFacets.push(treeFacet);
      }
      return { data: treeData, facets: treeFacets };
    }),
    ...Object.fromEntries(outputs)
  };
}
function treeLink(options = {}) {
  let {
    path = identity2,
    // the delimited path
    delimiter,
    // how the path is separated
    curve = "bump-x",
    stroke = "#555",
    strokeWidth = 1.5,
    strokeOpacity = 0.5,
    treeLayout = tree_default,
    treeSort,
    treeSeparation,
    treeAnchor,
    ...remainingOptions
  } = options;
  treeAnchor = maybeTreeAnchor(treeAnchor);
  treeSort = maybeTreeSort(treeSort);
  remainingOptions = { curve, stroke, strokeWidth, strokeOpacity, ...remainingOptions };
  const normalize2 = normalizer(delimiter);
  const outputs = treeOutputs(remainingOptions, maybeLinkValue);
  const [X1, setX1] = column();
  const [X2, setX2] = column();
  const [Y1, setY1] = column();
  const [Y2, setY2] = column();
  return {
    x1: X1,
    x2: X2,
    y1: Y1,
    y2: Y2,
    ...basic(remainingOptions, (data, facets) => {
      const P = normalize2(valueof(data, path));
      const X12 = setX1([]);
      const X22 = setX2([]);
      const Y12 = setY1([]);
      const Y22 = setY2([]);
      let treeIndex = -1;
      const treeData = [];
      const treeFacets = [];
      const rootof = stratify_default().path((i) => P[i]);
      const layout = treeLayout();
      if (layout.nodeSize)
        layout.nodeSize([1, 1]);
      if (layout.separation && treeSeparation !== void 0)
        layout.separation(treeSeparation ?? one);
      for (const o of outputs)
        o[output_values] = o[output_setValues]([]);
      for (const facet of facets) {
        const treeFacet = [];
        const root = rootof(facet.filter((i) => P[i] != null)).each((node) => node.data = data[node.data]);
        if (treeSort != null)
          root.sort(treeSort);
        layout(root);
        for (const { source, target } of root.links()) {
          treeFacet.push(++treeIndex);
          treeData[treeIndex] = target.data;
          treeAnchor.position(source, treeIndex, X12, Y12);
          treeAnchor.position(target, treeIndex, X22, Y22);
          for (const o of outputs)
            o[output_values][treeIndex] = o[output_evaluate](target, source);
        }
        treeFacets.push(treeFacet);
      }
      return { data: treeData, facets: treeFacets };
    }),
    ...Object.fromEntries(outputs)
  };
}
function maybeTreeAnchor(anchor = "left") {
  switch (`${anchor}`.trim().toLowerCase()) {
    case "left":
      return treeAnchorLeft;
    case "right":
      return treeAnchorRight;
  }
  throw new Error(`invalid tree anchor: ${anchor}`);
}
var treeAnchorLeft = {
  frameAnchor: "left",
  dx: 6,
  position({ x, y }, i, X, Y) {
    X[i] = y;
    Y[i] = -x;
  }
};
var treeAnchorRight = {
  frameAnchor: "right",
  dx: -6,
  position({ x, y }, i, X, Y) {
    X[i] = -y;
    Y[i] = -x;
  }
};
function maybeTreeSort(sort3) {
  return sort3 == null || typeof sort3 === "function" ? sort3 : `${sort3}`.trim().toLowerCase().startsWith("node:") ? nodeSort(maybeNodeValue(sort3)) : nodeSort(nodeData(sort3));
}
function nodeSort(value) {
  return (a, b) => ascendingDefined(value(a), value(b));
}
function nodeData(field2) {
  return (node) => {
    var _a;
    return (_a = node.data) == null ? void 0 : _a[field2];
  };
}
function normalizer(delimiter = "/") {
  return `${delimiter}` === "/" ? (P) => P : (P) => P.map(replaceAll(delimiter, "/"));
}
function replaceAll(search, replace) {
  search = new RegExp(regexEscape(search), "g");
  return (value) => value == null ? null : `${value}`.replace(search, replace);
}
function regexEscape(string2) {
  return `${string2}`.replace(/[\\^$*+?.()|[\]{}]/g, "\\$&");
}
function isNodeValue(option) {
  return isObject(option) && typeof option.node === "function";
}
function isLinkValue(option) {
  return isObject(option) && typeof option.link === "function";
}
function maybeNodeValue(value) {
  if (isNodeValue(value))
    return value.node;
  value = `${value}`.trim().toLowerCase();
  if (!value.startsWith("node:"))
    return;
  switch (value) {
    case "node:name":
      return nodeName;
    case "node:path":
      return nodePath;
    case "node:internal":
      return nodeInternal;
    case "node:depth":
      return nodeDepth;
    case "node:height":
      return nodeHeight;
  }
  throw new Error(`invalid node value: ${value}`);
}
function maybeLinkValue(value) {
  if (isNodeValue(value))
    return value.node;
  if (isLinkValue(value))
    return value.link;
  value = `${value}`.trim().toLowerCase();
  if (!value.startsWith("node:") && !value.startsWith("parent:"))
    return;
  switch (value) {
    case "parent:name":
      return parentValue(nodeName);
    case "parent:path":
      return parentValue(nodePath);
    case "parent:depth":
      return parentValue(nodeDepth);
    case "parent:height":
      return parentValue(nodeHeight);
    case "node:name":
      return nodeName;
    case "node:path":
      return nodePath;
    case "node:internal":
      return nodeInternal;
    case "node:depth":
      return nodeDepth;
    case "node:height":
      return nodeHeight;
  }
  throw new Error(`invalid link value: ${value}`);
}
function nodePath(node) {
  return node.id;
}
function nodeName(node) {
  return nameof(node.id);
}
function nodeDepth(node) {
  return node.depth;
}
function nodeHeight(node) {
  return node.height;
}
function nodeInternal(node) {
  return !!node.children;
}
function parentValue(evaluate) {
  return (child, parent) => parent == null ? void 0 : evaluate(parent);
}
function nameof(path) {
  let i = path.length;
  while (--i > 0)
    if (slash(path, i))
      break;
  return path.slice(i + 1);
}
function slash(path, i) {
  if (path[i] === "/") {
    let k = 0;
    while (i > 0 && path[--i] === "\\")
      ++k;
    if ((k & 1) === 0)
      return true;
  }
  return false;
}
var output_setValues = 2;
var output_evaluate = 3;
var output_values = 4;
function treeOutputs(options, maybeTreeValue) {
  const outputs = [];
  for (const name in options) {
    const value = options[name];
    const treeValue = maybeTreeValue(value);
    if (treeValue !== void 0) {
      outputs.push([name, ...column(value), treeValue]);
    }
  }
  return outputs;
}

// ../../node_modules/@observablehq/plot/dist/marks/tree.js
function tree(data, options = {}) {
  let { fill, stroke, strokeWidth, strokeOpacity, strokeLinejoin, strokeLinecap, strokeMiterlimit, strokeDasharray, strokeDashoffset, marker, markerStart = marker, markerEnd = marker, dot: dotDot = isNoneish(markerStart) && isNoneish(markerEnd), text: textText = "node:name", textStroke = "white", title = "node:path", dx, dy, ...remainingOptions } = options;
  if (dx === void 0)
    dx = maybeTreeAnchor(remainingOptions.treeAnchor).dx;
  return marks(link(data, treeLink({
    markerStart,
    markerEnd,
    stroke: stroke !== void 0 ? stroke : fill === void 0 ? "node:internal" : fill,
    strokeWidth,
    strokeOpacity,
    strokeLinejoin,
    strokeLinecap,
    strokeMiterlimit,
    strokeDasharray,
    strokeDashoffset,
    ...remainingOptions
  })), dotDot ? dot(data, treeNode({ fill: fill === void 0 ? "node:internal" : fill, title, ...remainingOptions })) : null, textText != null ? text(data, treeNode({
    text: textText,
    fill: fill === void 0 ? "currentColor" : fill,
    stroke: textStroke,
    dx,
    dy,
    title,
    ...remainingOptions
  })) : null);
}
function cluster(data, options) {
  return tree(data, { ...options, treeLayout: cluster_default });
}

// ../../node_modules/@observablehq/plot/dist/marks/vector.js
var defaults20 = {
  ariaLabel: "vector",
  fill: "none",
  stroke: "currentColor",
  strokeWidth: 1.5,
  strokeLinejoin: "round",
  strokeLinecap: "round"
};
var defaultRadius = 3.5;
var wingRatio = defaultRadius * 5;
var shapeArrow = {
  draw(context, l, r) {
    const wing = l * r / wingRatio;
    context.moveTo(0, 0);
    context.lineTo(0, -l);
    context.moveTo(-wing, wing - l);
    context.lineTo(0, -l);
    context.lineTo(wing, wing - l);
  }
};
var shapeSpike = {
  draw(context, l, r) {
    context.moveTo(-r, 0);
    context.lineTo(0, -l);
    context.lineTo(r, 0);
  }
};
var shapes = /* @__PURE__ */ new Map([
  ["arrow", shapeArrow],
  ["spike", shapeSpike]
]);
function isShapeObject(value) {
  return value && typeof value.draw === "function";
}
function Shape(shape) {
  if (isShapeObject(shape))
    return shape;
  const value = shapes.get(`${shape}`.toLowerCase());
  if (value)
    return value;
  throw new Error(`invalid shape: ${shape}`);
}
var Vector = class extends Mark {
  constructor(data, options = {}) {
    const { x, y, r = defaultRadius, length: length2, rotate, shape = shapeArrow, anchor = "middle", frameAnchor } = options;
    const [vl, cl] = maybeNumberChannel(length2, 12);
    const [vr, cr] = maybeNumberChannel(rotate, 0);
    super(data, {
      x: { value: x, scale: "x", optional: true },
      y: { value: y, scale: "y", optional: true },
      length: { value: vl, scale: "length", optional: true },
      rotate: { value: vr, optional: true }
    }, options, defaults20);
    this.r = +r;
    this.length = cl;
    this.rotate = cr;
    this.shape = Shape(shape);
    this.anchor = keyword(anchor, "anchor", ["start", "middle", "end"]);
    this.frameAnchor = maybeFrameAnchor(frameAnchor);
  }
  render(index, scales, channels, dimensions, context) {
    const { x, y } = scales;
    const { x: X, y: Y, length: L, rotate: A } = channels;
    const { length: length2, rotate, anchor, shape, r } = this;
    const [cx, cy] = applyFrameAnchor(this, dimensions);
    return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, { x: X && x, y: Y && y }).call((g) => g.selectAll().data(index).enter().append("path").call(applyDirectStyles, this).attr("transform", template`translate(${X ? (i) => X[i] : cx},${Y ? (i) => Y[i] : cy})${A ? (i) => ` rotate(${A[i]})` : rotate ? ` rotate(${rotate})` : ``}${anchor === "start" ? `` : anchor === "end" ? L ? (i) => ` translate(0,${L[i]})` : ` translate(0,${length2})` : L ? (i) => ` translate(0,${L[i] / 2})` : ` translate(0,${length2 / 2})`}`).attr("d", L ? (i) => {
      const p = pathRound();
      shape.draw(p, L[i], r);
      return p;
    } : (() => {
      const p = pathRound();
      shape.draw(p, length2, r);
      return p;
    })()).call(applyChannelStyles, this, channels)).node();
  }
};
function vector(data, options = {}) {
  let { x, y, ...rest } = options;
  if (options.frameAnchor === void 0)
    [x, y] = maybeTuple(x, y);
  return new Vector(data, { ...rest, x, y });
}
function vectorX(data, options = {}) {
  const { x = identity2, ...rest } = options;
  return new Vector(data, { ...rest, x });
}
function vectorY(data, options = {}) {
  const { y = identity2, ...rest } = options;
  return new Vector(data, { ...rest, y });
}
function spike(data, options = {}) {
  const { shape = shapeSpike, stroke = defaults20.stroke, strokeWidth = 1, fill = stroke, fillOpacity = 0.3, anchor = "start", ...rest } = options;
  return vector(data, { ...rest, shape, stroke, strokeWidth, fill, fillOpacity, anchor });
}

// ../../node_modules/@observablehq/plot/dist/transforms/centroid.js
function centroid({ geometry = identity2, ...options } = {}) {
  return initializer({ ...options, x: null, y: null }, (data, facets, channels, scales, dimensions, { projection }) => {
    const G = valueof(data, geometry);
    const n = G.length;
    const X = new Float64Array(n);
    const Y = new Float64Array(n);
    const path = path_default(projection);
    for (let i = 0; i < n; ++i)
      [X[i], Y[i]] = path.centroid(G[i]);
    return { data, facets, channels: { x: { value: X }, y: { value: Y } } };
  });
}
function geoCentroid({ geometry = identity2, ...options } = {}) {
  let C;
  return {
    ...options,
    x: { transform: (data) => Float64Array.from(C = valueof(valueof(data, geometry), centroid_default), ([x]) => x) },
    y: { transform: () => Float64Array.from(C, ([, y]) => y) }
  };
}

// ../../node_modules/@observablehq/plot/dist/transforms/dodge.js
var import_interval_tree_1d = __toESM(require_interval_tree(), 1);
var anchorXLeft = ({ marginLeft }) => [1, marginLeft];
var anchorXRight = ({ width, marginRight }) => [-1, width - marginRight];
var anchorXMiddle = ({ width, marginLeft, marginRight }) => [0, (marginLeft + width - marginRight) / 2];
var anchorYTop = ({ marginTop }) => [1, marginTop];
var anchorYBottom = ({ height, marginBottom }) => [-1, height - marginBottom];
var anchorYMiddle = ({ height, marginTop, marginBottom }) => [0, (marginTop + height - marginBottom) / 2];
function maybeAnchor(anchor) {
  return typeof anchor === "string" ? { anchor } : anchor;
}
function dodgeX(dodgeOptions = {}, options = {}) {
  if (arguments.length === 1)
    [dodgeOptions, options] = mergeOptions3(dodgeOptions);
  let { anchor = "left", padding = 1 } = maybeAnchor(dodgeOptions);
  switch (`${anchor}`.toLowerCase()) {
    case "left":
      anchor = anchorXLeft;
      break;
    case "right":
      anchor = anchorXRight;
      break;
    case "middle":
      anchor = anchorXMiddle;
      break;
    default:
      throw new Error(`unknown dodge anchor: ${anchor}`);
  }
  return dodge("x", "y", anchor, number(padding), options);
}
function dodgeY(dodgeOptions = {}, options = {}) {
  if (arguments.length === 1)
    [dodgeOptions, options] = mergeOptions3(dodgeOptions);
  let { anchor = "bottom", padding = 1 } = maybeAnchor(dodgeOptions);
  switch (`${anchor}`.toLowerCase()) {
    case "top":
      anchor = anchorYTop;
      break;
    case "bottom":
      anchor = anchorYBottom;
      break;
    case "middle":
      anchor = anchorYMiddle;
      break;
    default:
      throw new Error(`unknown dodge anchor: ${anchor}`);
  }
  return dodge("y", "x", anchor, number(padding), options);
}
function mergeOptions3(options) {
  const { anchor, padding, ...rest } = options;
  return [{ anchor, padding }, rest];
}
function dodge(y, x, anchor, padding, options) {
  const { r } = options;
  if (r != null && typeof r !== "number") {
    const { channels, sort: sort3, reverse: reverse3 } = options;
    options = { ...options, channels: { r: { value: r, scale: "r" }, ...maybeNamed(channels) } };
    if (sort3 === void 0 && reverse3 === void 0)
      options.sort = { channel: "r", order: "descending" };
  }
  return initializer(options, function(data, facets, channels, scales, dimensions, context) {
    let { [x]: X, r: R } = channels;
    if (!channels[x])
      throw new Error(`missing channel: ${x}`);
    ({ [x]: X } = Position(channels, scales, context));
    const r2 = R ? void 0 : this.r !== void 0 ? this.r : options.r !== void 0 ? number(options.r) : 3;
    if (R)
      R = coerceNumbers(valueof(R.value, scales[R.scale] || identity2));
    let [ky, ty] = anchor(dimensions);
    const compare = ky ? compareAscending : compareSymmetric;
    const Y = new Float64Array(X.length);
    const radius2 = R ? (i) => R[i] : () => r2;
    for (let I of facets) {
      const tree2 = (0, import_interval_tree_1d.default)();
      I = I.filter(R ? (i) => finite(X[i]) && positive(R[i]) : (i) => finite(X[i]));
      const intervals = new Float64Array(2 * I.length + 2);
      for (const i of I) {
        const ri = radius2(i);
        const y0 = ky ? ri + padding : 0;
        const l = X[i] - ri;
        const h = X[i] + ri;
        let k = 2;
        tree2.queryInterval(l - padding, h + padding, ([, , j]) => {
          const yj = Y[j] - y0;
          const dx = X[i] - X[j];
          const dr = padding + (R ? R[i] + R[j] : 2 * r2);
          const dy = Math.sqrt(dr * dr - dx * dx);
          intervals[k++] = yj - dy;
          intervals[k++] = yj + dy;
        });
        let candidates = intervals.slice(0, k);
        if (ky)
          candidates = candidates.filter((y2) => y2 >= 0);
        out:
          for (const y2 of candidates.sort(compare)) {
            for (let j = 0; j < k; j += 2) {
              if (intervals[j] + 1e-6 < y2 && y2 < intervals[j + 1] - 1e-6) {
                continue out;
              }
            }
            Y[i] = y2 + y0;
            break;
          }
        tree2.insert([l, h, i]);
      }
    }
    if (!ky)
      ky = 1;
    for (const I of facets) {
      for (const i of I) {
        Y[i] = Y[i] * ky + ty;
      }
    }
    return {
      data,
      facets,
      channels: {
        [x]: { value: X },
        [y]: { value: Y },
        ...R && { r: { value: R } }
      }
    };
  });
}
function compareSymmetric(a, b) {
  return Math.abs(a) - Math.abs(b);
}
function compareAscending(a, b) {
  return a - b;
}

// ../../node_modules/@observablehq/plot/dist/transforms/normalize.js
function normalizeX(basis, options) {
  if (arguments.length === 1)
    ({ basis, ...options } = basis);
  return mapX(normalize(basis), options);
}
function normalizeY(basis, options) {
  if (arguments.length === 1)
    ({ basis, ...options } = basis);
  return mapY(normalize(basis), options);
}
function normalize(basis) {
  if (basis === void 0)
    return normalizeFirst;
  if (typeof basis === "function")
    return normalizeBasis((I, S) => basis(take(S, I)));
  if (/^p\d{2}$/i.test(basis))
    return normalizeAccessor(percentile(basis));
  switch (`${basis}`.toLowerCase()) {
    case "deviation":
      return normalizeDeviation;
    case "first":
      return normalizeFirst;
    case "last":
      return normalizeLast;
    case "max":
      return normalizeMax;
    case "mean":
      return normalizeMean;
    case "median":
      return normalizeMedian;
    case "min":
      return normalizeMin;
    case "sum":
      return normalizeSum;
    case "extent":
      return normalizeExtent;
  }
  throw new Error(`invalid basis: ${basis}`);
}
function normalizeBasis(basis) {
  return {
    map(I, S, T) {
      const b = +basis(I, S);
      for (const i of I) {
        T[i] = S[i] === null ? NaN : S[i] / b;
      }
    }
  };
}
function normalizeAccessor(f) {
  return normalizeBasis((I, S) => f(I, (i) => S[i]));
}
var normalizeExtent = {
  map(I, S, T) {
    const [s1, s2] = extent(I, (i) => S[i]), d = s2 - s1;
    for (const i of I) {
      T[i] = S[i] === null ? NaN : (S[i] - s1) / d;
    }
  }
};
var normalizeFirst = normalizeBasis((I, S) => {
  for (let i = 0; i < I.length; ++i) {
    const s = S[I[i]];
    if (defined(s))
      return s;
  }
});
var normalizeLast = normalizeBasis((I, S) => {
  for (let i = I.length - 1; i >= 0; --i) {
    const s = S[I[i]];
    if (defined(s))
      return s;
  }
});
var normalizeDeviation = {
  map(I, S, T) {
    const m = mean(I, (i) => S[i]);
    const d = deviation(I, (i) => S[i]);
    for (const i of I) {
      T[i] = S[i] === null ? NaN : d ? (S[i] - m) / d : 0;
    }
  }
};
var normalizeMax = normalizeAccessor(max);
var normalizeMean = normalizeAccessor(mean);
var normalizeMedian = normalizeAccessor(median);
var normalizeMin = normalizeAccessor(min);
var normalizeSum = normalizeAccessor(sum);

// ../../node_modules/@observablehq/plot/dist/transforms/window.js
function windowX(windowOptions = {}, options) {
  if (arguments.length === 1)
    options = windowOptions;
  return mapX(window2(windowOptions), options);
}
function windowY(windowOptions = {}, options) {
  if (arguments.length === 1)
    options = windowOptions;
  return mapY(window2(windowOptions), options);
}
function window2(options = {}) {
  if (typeof options === "number")
    options = { k: options };
  let { k, reduce, shift, anchor, strict } = options;
  if (anchor === void 0 && shift !== void 0) {
    anchor = maybeShift(shift);
    warn(`Warning: the shift option is deprecated; please use anchor "${anchor}" instead.`);
  }
  if (!((k = Math.floor(k)) > 0))
    throw new Error(`invalid k: ${k}`);
  return maybeReduce2(reduce)(k, maybeAnchor2(anchor, k), strict);
}
function maybeAnchor2(anchor = "middle", k) {
  switch (`${anchor}`.toLowerCase()) {
    case "middle":
      return k - 1 >> 1;
    case "start":
      return 0;
    case "end":
      return k - 1;
  }
  throw new Error(`invalid anchor: ${anchor}`);
}
function maybeShift(shift) {
  switch (`${shift}`.toLowerCase()) {
    case "centered":
      return "middle";
    case "leading":
      return "start";
    case "trailing":
      return "end";
  }
  throw new Error(`invalid shift: ${shift}`);
}
function maybeReduce2(reduce = "mean") {
  if (typeof reduce === "string") {
    if (/^p\d{2}$/i.test(reduce))
      return reduceNumbers(percentile(reduce));
    switch (reduce.toLowerCase()) {
      case "deviation":
        return reduceNumbers(deviation);
      case "max":
        return reduceArray(max);
      case "mean":
        return reduceMean;
      case "median":
        return reduceNumbers(median);
      case "min":
        return reduceArray(min);
      case "mode":
        return reduceArray(mode);
      case "sum":
        return reduceSum2;
      case "variance":
        return reduceNumbers(variance);
      case "difference":
        return reduceDifference;
      case "ratio":
        return reduceRatio;
      case "first":
        return reduceFirst2;
      case "last":
        return reduceLast2;
    }
  }
  if (typeof reduce !== "function")
    throw new Error(`invalid reduce: ${reduce}`);
  return reduceArray(reduce);
}
function slice2(I, i, j) {
  return I.subarray ? I.subarray(i, j) : I.slice(i, j);
}
function reduceNumbers(f) {
  return (k, s, strict) => strict ? {
    map(I, S, T) {
      const C = Float64Array.from(I, (i) => S[i] === null ? NaN : S[i]);
      let nans = 0;
      for (let i = 0; i < k - 1; ++i)
        if (isNaN(C[i]))
          ++nans;
      for (let i = 0, n = I.length - k + 1; i < n; ++i) {
        if (isNaN(C[i + k - 1]))
          ++nans;
        T[I[i + s]] = nans === 0 ? f(C.subarray(i, i + k)) : NaN;
        if (isNaN(C[i]))
          --nans;
      }
    }
  } : {
    map(I, S, T) {
      const C = Float64Array.from(I, (i) => S[i] === null ? NaN : S[i]);
      for (let i = -s; i < 0; ++i) {
        T[I[i + s]] = f(C.subarray(0, i + k));
      }
      for (let i = 0, n = I.length - s; i < n; ++i) {
        T[I[i + s]] = f(C.subarray(i, i + k));
      }
    }
  };
}
function reduceArray(f) {
  return (k, s, strict) => strict ? {
    map(I, S, T) {
      let count2 = 0;
      for (let i = 0; i < k - 1; ++i)
        count2 += defined(S[I[i]]);
      for (let i = 0, n = I.length - k + 1; i < n; ++i) {
        count2 += defined(S[I[i + k - 1]]);
        if (count2 === k)
          T[I[i + s]] = f(take(S, slice2(I, i, i + k)));
        count2 -= defined(S[I[i]]);
      }
    }
  } : {
    map(I, S, T) {
      for (let i = -s; i < 0; ++i) {
        T[I[i + s]] = f(take(S, slice2(I, 0, i + k)));
      }
      for (let i = 0, n = I.length - s; i < n; ++i) {
        T[I[i + s]] = f(take(S, slice2(I, i, i + k)));
      }
    }
  };
}
function reduceSum2(k, s, strict) {
  return strict ? {
    map(I, S, T) {
      let nans = 0;
      let sum2 = 0;
      for (let i = 0; i < k - 1; ++i) {
        const v = S[I[i]];
        if (v === null || isNaN(v))
          ++nans;
        else
          sum2 += +v;
      }
      for (let i = 0, n = I.length - k + 1; i < n; ++i) {
        const a = S[I[i]];
        const b = S[I[i + k - 1]];
        if (b === null || isNaN(b))
          ++nans;
        else
          sum2 += +b;
        T[I[i + s]] = nans === 0 ? sum2 : NaN;
        if (a === null || isNaN(a))
          --nans;
        else
          sum2 -= +a;
      }
    }
  } : {
    map(I, S, T) {
      let sum2 = 0;
      const n = I.length;
      for (let i = 0, j = Math.min(n, k - s - 1); i < j; ++i) {
        sum2 += +S[I[i]] || 0;
      }
      for (let i = -s, j = n - s; i < j; ++i) {
        sum2 += +S[I[i + k - 1]] || 0;
        T[I[i + s]] = sum2;
        sum2 -= +S[I[i]] || 0;
      }
    }
  };
}
function reduceMean(k, s, strict) {
  if (strict) {
    const sum2 = reduceSum2(k, s, strict);
    return {
      map(I, S, T) {
        sum2.map(I, S, T);
        for (let i = 0, n = I.length - k + 1; i < n; ++i) {
          T[I[i + s]] /= k;
        }
      }
    };
  } else {
    return {
      map(I, S, T) {
        let sum2 = 0;
        let count2 = 0;
        const n = I.length;
        for (let i = 0, j = Math.min(n, k - s - 1); i < j; ++i) {
          let v = S[I[i]];
          if (v !== null && !isNaN(v = +v))
            sum2 += v, ++count2;
        }
        for (let i = -s, j = n - s; i < j; ++i) {
          let a = S[I[i + k - 1]];
          let b = S[I[i]];
          if (a !== null && !isNaN(a = +a))
            sum2 += a, ++count2;
          T[I[i + s]] = sum2 / count2;
          if (b !== null && !isNaN(b = +b))
            sum2 -= b, --count2;
        }
      }
    };
  }
}
function firstDefined(S, I, i, k) {
  for (let j = i + k; i < j; ++i) {
    const v = S[I[i]];
    if (defined(v))
      return v;
  }
}
function lastDefined(S, I, i, k) {
  for (let j = i + k - 1; j >= i; --j) {
    const v = S[I[j]];
    if (defined(v))
      return v;
  }
}
function firstNumber(S, I, i, k) {
  for (let j = i + k; i < j; ++i) {
    let v = S[I[i]];
    if (v !== null && !isNaN(v = +v))
      return v;
  }
}
function lastNumber(S, I, i, k) {
  for (let j = i + k - 1; j >= i; --j) {
    let v = S[I[j]];
    if (v !== null && !isNaN(v = +v))
      return v;
  }
}
function reduceDifference(k, s, strict) {
  return strict ? {
    map(I, S, T) {
      for (let i = 0, n = I.length - k; i < n; ++i) {
        const a = S[I[i]];
        const b = S[I[i + k - 1]];
        T[I[i + s]] = a === null || b === null ? NaN : b - a;
      }
    }
  } : {
    map(I, S, T) {
      for (let i = -s, n = I.length - k + s + 1; i < n; ++i) {
        T[I[i + s]] = lastNumber(S, I, i, k) - firstNumber(S, I, i, k);
      }
    }
  };
}
function reduceRatio(k, s, strict) {
  return strict ? {
    map(I, S, T) {
      for (let i = 0, n = I.length - k; i < n; ++i) {
        const a = S[I[i]];
        const b = S[I[i + k - 1]];
        T[I[i + s]] = a === null || b === null ? NaN : b / a;
      }
    }
  } : {
    map(I, S, T) {
      for (let i = -s, n = I.length - k + s + 1; i < n; ++i) {
        T[I[i + s]] = lastNumber(S, I, i, k) / firstNumber(S, I, i, k);
      }
    }
  };
}
function reduceFirst2(k, s, strict) {
  return strict ? {
    map(I, S, T) {
      for (let i = 0, n = I.length - k; i < n; ++i) {
        T[I[i + s]] = S[I[i]];
      }
    }
  } : {
    map(I, S, T) {
      for (let i = -s, n = I.length - k + s + 1; i < n; ++i) {
        T[I[i + s]] = firstDefined(S, I, i, k);
      }
    }
  };
}
function reduceLast2(k, s, strict) {
  return strict ? {
    map(I, S, T) {
      for (let i = 0, n = I.length - k; i < n; ++i) {
        T[I[i + s]] = S[I[i + k - 1]];
      }
    }
  } : {
    map(I, S, T) {
      for (let i = -s, n = I.length - k + s + 1; i < n; ++i) {
        T[I[i + s]] = lastDefined(S, I, i, k);
      }
    }
  };
}

// ../../node_modules/@observablehq/plot/dist/transforms/select.js
function select(selector, options = {}) {
  if (typeof selector === "string") {
    switch (selector.toLowerCase()) {
      case "first":
        return selectFirst(options);
      case "last":
        return selectLast(options);
    }
  }
  if (typeof selector === "function") {
    return selectChannel(null, selector, options);
  }
  let key, value;
  for (key in selector) {
    if (value !== void 0)
      throw new Error("ambiguous selector; multiple inputs");
    value = maybeSelector(selector[key]);
  }
  if (value === void 0)
    throw new Error(`invalid selector: ${selector}`);
  return selectChannel(key, value, options);
}
function maybeSelector(selector) {
  if (typeof selector === "function")
    return selector;
  switch (`${selector}`.toLowerCase()) {
    case "min":
      return selectorMin;
    case "max":
      return selectorMax;
  }
  throw new Error(`unknown selector: ${selector}`);
}
function selectFirst(options) {
  return selectChannel(null, selectorFirst, options);
}
function selectLast(options) {
  return selectChannel(null, selectorLast, options);
}
function selectMinX(options) {
  return selectChannel("x", selectorMin, options);
}
function selectMinY(options) {
  return selectChannel("y", selectorMin, options);
}
function selectMaxX(options) {
  return selectChannel("x", selectorMax, options);
}
function selectMaxY(options) {
  return selectChannel("y", selectorMax, options);
}
function* selectorFirst(I) {
  yield I[0];
}
function* selectorLast(I) {
  yield I[I.length - 1];
}
function* selectorMin(I, X) {
  yield least(I, (i) => X[i]);
}
function* selectorMax(I, X) {
  yield greatest(I, (i) => X[i]);
}
function selectChannel(v, selector, options) {
  if (v != null) {
    if (options[v] == null)
      throw new Error(`missing channel: ${v}`);
    v = options[v];
  }
  const z = maybeZ(options);
  return basic(options, (data, facets) => {
    const Z = valueof(data, z);
    const V = valueof(data, v);
    const selectFacets = [];
    for (const facet of facets) {
      const selectFacet = [];
      for (const I of Z ? group(facet, (i) => Z[i]).values() : [facet]) {
        for (const i of selector(I, V)) {
          selectFacet.push(i);
        }
      }
      selectFacets.push(selectFacet);
    }
    return { data, facets: selectFacets };
  });
}
export {
  Area,
  Arrow,
  BarX,
  BarY,
  Cell,
  Contour,
  Density,
  Dot,
  Frame,
  Geo,
  Hexgrid,
  Image,
  Line,
  Link,
  Mark,
  Raster,
  Rect,
  RuleX,
  RuleY,
  Text,
  TickX,
  TickY,
  Vector,
  area,
  areaX,
  areaY,
  arrow,
  barX,
  barY,
  bin,
  binX,
  binY,
  boxX,
  boxY,
  cell,
  cellX,
  cellY,
  centroid,
  circle,
  cluster,
  column,
  contour,
  delaunayLink,
  delaunayMesh,
  density,
  dodgeX,
  dodgeY,
  dot,
  dotX,
  dotY,
  filter,
  formatIsoDate,
  formatMonth,
  formatWeekday,
  frame,
  geo,
  geoCentroid,
  graticule,
  group2 as group,
  groupX,
  groupY,
  groupZ,
  hexagon,
  hexbin,
  hexgrid,
  hull,
  identity2 as identity,
  image,
  initializer,
  interpolateNearest,
  interpolateNone,
  interpolatorBarycentric,
  interpolatorRandomWalk,
  legend,
  line,
  lineX,
  lineY,
  linearRegressionX,
  linearRegressionY,
  link,
  map3 as map,
  mapX,
  mapY,
  marks,
  normalize,
  normalizeX,
  normalizeY,
  plot,
  raster,
  rect,
  rectX,
  rectY,
  reverse2 as reverse,
  ruleX,
  ruleY,
  scale,
  select,
  selectFirst,
  selectLast,
  selectMaxX,
  selectMaxY,
  selectMinX,
  selectMinY,
  shuffle,
  sort2 as sort,
  sphere,
  spike,
  stackX,
  stackX1,
  stackX2,
  stackY,
  stackY1,
  stackY2,
  text,
  textX,
  textY,
  tickX,
  tickY,
  basic as transform,
  tree,
  treeLink,
  treeNode,
  valueof,
  vector,
  vectorX,
  vectorY,
  voronoi,
  voronoiMesh,
  window2 as window,
  windowX,
  windowY
};
//# sourceMappingURL=@observablehq_plot.js.map
