import Supercluster, { ClusterFeature, PointFeature } from "supercluster";
//#region src/types.d.ts
/** Plain GeoJSON properties object used by points and clusters. */
type GeoJsonProperties = Record<string, unknown>;
/**
 * Point properties accepted by `useSupercluster`.
 *
 * The `cluster` key is reserved: generated clusters use it as a discriminator,
 * so input points must not define it. Use `isCluster` to tell features apart.
 *
 * @example
 * ```ts
 * type CityPoint = { name: string; population: number } // satisfies PointFeatureProperties
 * ```
 */
type PointFeatureProperties = GeoJsonProperties & {
  cluster?: never;
};
/** A feature returned from `useSupercluster`: either an original point or a generated cluster. */
type Cluster<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = PointFeature<TFeatureProperties> | ClusterFeature<TClusterProperties>;
/**
 * Loaded `supercluster` instance returned by the hook.
 *
 * Use it for advanced reads such as leaves, children, and expansion zoom.
 *
 * @example
 * ```ts
 * const zoom = supercluster.getClusterExpansionZoom(clusterId)
 * ```
 */
type SuperclusterInstance<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = Omit<Supercluster<TFeatureProperties, TClusterProperties>, 'load'>;
/**
 * Maps point properties to the aggregate properties used by clusters.
 *
 * Mirrors `supercluster`'s `map` option.
 *
 * @example
 * ```ts
 * type City = { name: string; population: number }
 * type CityCluster = { population: number }
 *
 * const map: MapFeatureToCluster<City, CityCluster> = (point) => ({
 *   population: point.population,
 * })
 * ```
 */
type MapFeatureToCluster<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = (feature: TFeatureProperties) => TClusterProperties;
/**
 * Merges aggregate properties while building clusters.
 *
 * Mirrors `supercluster`'s `reduce` option.
 *
 * @example
 * ```ts
 * const reduce: ReduceCluster<CityCluster> = (memo, point) => {
 *   memo.population += point.population
 * }
 * ```
 */
type ReduceCluster<TClusterProperties extends GeoJsonProperties> = (memo: TClusterProperties, feature: Readonly<TClusterProperties>) => void;
/**
 * Options passed to the underlying `supercluster` index.
 *
 * Function options should be stable between renders.
 *
 * @example
 * ```ts
 * const options = {
 *   radius: 60,
 *   maxZoom: 18,
 *   map,
 *   reduce,
 * }
 * ```
 */
type SuperclusterOptions<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = {
  minZoom?: number | undefined;
  maxZoom?: number | undefined;
  radius?: number | undefined;
  minPoints?: number | undefined;
  extent?: number | undefined;
  nodeSize?: number | undefined;
  generateId?: boolean | undefined;
  map?: MapFeatureToCluster<TFeatureProperties, TClusterProperties> | undefined;
  reduce?: ReduceCluster<TClusterProperties> | undefined;
};
type LngLatBounds = {
  toArray(): number[][];
};
type MapEventListener = (...args: unknown[]) => void;
/** Minimal structural contract satisfied by every `react-map-gl` `MapRef` flavor. */
type MapLike = {
  getBounds(): LngLatBounds | null;
  getZoom(): number;
  on(type: string, listener: MapEventListener): void;
  off(type: string, listener?: MapEventListener): void;
};
//#endregion
//#region src/use-supercluster.d.ts
/** Values returned by `useSupercluster`. */
type UseSuperclusterReturnValue<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = {
  /** Clusters for the current — optionally padded — map bounds and rounded zoom. */
  clusters: Array<Cluster<TFeatureProperties, TClusterProperties>>;
  /** Loaded index for advanced `supercluster` queries. */
  supercluster: SuperclusterInstance<TFeatureProperties, TClusterProperties>;
};
/**
 * Hook options.
 *
 * Pass `mapRef` when the map is outside `react-map-gl` context or when several maps are mounted.
 */
type UseSuperclusterOptions<MapRef extends MapLike, TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = SuperclusterOptions<TFeatureProperties, TClusterProperties> & {
  mapRef?: MapRef | undefined | null;
  /**
   * Extra viewport fraction (per side) included when querying clusters.
   *
   * Markers near the edges don't pop in and out, and pans inside the padded
   * area at the same rounded zoom skip recomputation entirely. The queried
   * area grows as `(1 + 2 * padding)²`, so large values render more
   * off-screen markers. Non-positive values disable padding.
   *
   * @default 0
   */
  boundsPadding?: number | undefined;
};
//#endregion
//#region src/is-cluster.d.ts
/**
 * Narrows a feature returned from `useSupercluster` to a generated cluster.
 *
 * @example
 * ```tsx
 * clusters.map((feature) => (isCluster(feature) ? renderCluster(feature) : renderPoint(feature)))
 * ```
 */
declare function isCluster<TFeatureProperties extends PointFeatureProperties, TClusterProperties extends GeoJsonProperties>(feature: Cluster<TFeatureProperties, TClusterProperties>): feature is ClusterFeature<TClusterProperties>;
//#endregion
export { ClusterFeature as a, PointFeatureProperties as c, Cluster as i, SuperclusterInstance as l, UseSuperclusterOptions as n, GeoJsonProperties as o, UseSuperclusterReturnValue as r, PointFeature as s, isCluster as t };