col-browser 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/chunks/{Distributions-DDYEbGhW.js → Distributions-CXIEJ6e6.js} +254 -233
- package/es/chunks/Distributions-CXIEJ6e6.js.map +1 -0
- package/es/chunks/TaxonBreakdown-BzDHojmp.js +210 -0
- package/es/chunks/TaxonBreakdown-BzDHojmp.js.map +1 -0
- package/es/chunks/index-BmhRLlZh.js +100 -0
- package/es/chunks/index-BmhRLlZh.js.map +1 -0
- package/es/chunks/storage-BgdCo9fV.js +20 -0
- package/es/chunks/storage-BgdCo9fV.js.map +1 -0
- package/es/index.js +1 -1
- package/es/routing.js +1 -1
- package/es/search.js +214 -207
- package/es/search.js.map +1 -1
- package/es/taxon.js +2 -2
- package/es/taxonBreakdown.js +22 -20
- package/es/taxonBreakdown.js.map +1 -1
- package/es/taxonDistribution.js +16 -14
- package/es/taxonDistribution.js.map +1 -1
- package/es/tree.js +142 -140
- package/es/tree.js.map +1 -1
- package/package.json +1 -1
- package/types/index.d.ts +11 -0
- package/umd/col-browser.js +118 -49
- package/umd/col-browser.js.map +1 -1
- package/umd/col-browser.min.js +5 -5
- package/umd/col-browser.min.js.map +1 -1
- package/es/chunks/Distributions-DDYEbGhW.js.map +0 -1
- package/es/chunks/TaxonBreakdown-BshFaQql.js +0 -205
- package/es/chunks/TaxonBreakdown-BshFaQql.js.map +0 -1
- package/es/chunks/index-CNK3JADR.js +0 -95
- package/es/chunks/index-CNK3JADR.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Distributions-DDYEbGhW.js","sources":["../../node_modules/@ant-design/icons-svg/es/asn/BookOutlined.js","../../node_modules/@ant-design/icons/es/icons/BookOutlined.js","../../src/Taxon/ReferencePopover.js","../../src/Taxon/DistributionsMap/descendantRanks.js","../../src/Taxon/DistributionsMap/descendantFetch.js","../../src/Taxon/DistributionsMap/colorAssignment.js","../../src/Taxon/DistributionsMap/IncludedTaxaLegend.js","../../src/Taxon/DistributionsMap/index.js","../../src/Taxon/Distributions.js"],"sourcesContent":["// This icon file is generated automatically.\nvar BookOutlined = { \"icon\": { \"tag\": \"svg\", \"attrs\": { \"viewBox\": \"64 64 896 896\", \"focusable\": \"false\" }, \"children\": [{ \"tag\": \"path\", \"attrs\": { \"d\": \"M832 64H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32zm-260 72h96v209.9L621.5 312 572 347.4V136zm220 752H232V136h280v296.9c0 3.3 1 6.6 3 9.3a15.9 15.9 0 0022.3 3.7l83.8-59.9 81.4 59.4c2.7 2 6 3.1 9.4 3.1 8.8 0 16-7.2 16-16V136h64v752z\" } }] }, \"name\": \"book\", \"theme\": \"outlined\" };\nexport default BookOutlined;\n","function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n// GENERATE BY ./scripts/generate.ts\n// DON NOT EDIT IT MANUALLY\n\nimport * as React from 'react';\nimport BookOutlinedSvg from \"@ant-design/icons-svg/es/asn/BookOutlined\";\nimport AntdIcon from \"../components/AntdIcon\";\nconst BookOutlined = (props, ref) => /*#__PURE__*/React.createElement(AntdIcon, _extends({}, props, {\n ref: ref,\n icon: BookOutlinedSvg\n}));\n\n/** */\nconst RefIcon = /*#__PURE__*/React.forwardRef(BookOutlined);\nif (process.env.NODE_ENV !== 'production') {\n RefIcon.displayName = 'BookOutlined';\n}\nexport default RefIcon;","import React from \"react\";\nimport { BookOutlined } from \"@ant-design/icons\";\nimport { Popover, Spin } from \"antd\";\nimport client from \"../api/client\";\nimport config from \"../config\";\nimport { get, isArray } from \"lodash-es\";\nimport ErrorMsg from \"../components/ErrorMsg\";\n\nclass ReferencePopover extends React.Component {\n constructor(props) {\n super(props);\n\n this.state = {\n reference: [],\n loading: false,\n error: null,\n };\n }\n\n getData = () => {\n const { referenceId, datasetKey, references } = this.props;\n if (referenceId) {\n const refIds = !isArray(referenceId) ? [referenceId] : referenceId;\n const reference = [];\n this.setState({ loading: true });\n Promise.allSettled(\n refIds.map((id) => get(references, id) ? Promise.resolve(reference.push(references[id])) :\n\n client(\n `${config.dataApi}dataset/${datasetKey}/reference/${id}`\n ).then((res) => reference.push(res.data)).catch(err => this.setState({error: err}))\n\n \n )\n ).then(() => this.setState({ reference, loading: false }));\n }\n };\n\n getContent = () => {\n const { error, reference, loading } = this.state;\n if (loading) {\n return <Spin />;\n } else if (error) {\n return <ErrorMsg error={error}/>;\n } else if (reference.length === 1) {\n return reference[0].citation;\n } else {\n return (\n <ul>\n {reference.map((r) => (\n <li key={r.id}>{r.citation}</li>\n ))}\n </ul>\n );\n }\n };\n\n scrollToReference = (e, id) => {\n // Default <a href=\"#col-reference-{id}\"> behaviour writes the hash into\n // window.location, which hijacks hosts using hash-based routing (the\n // GitHub Pages demo, COL portal preview). Scroll without touching the\n // URL.\n const el = document.getElementById(`col-reference-${id}`);\n if (el) {\n e.preventDefault();\n el.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n }\n };\n\n render = () => {\n const { referenceId, referenceIndexMap, trigger } = this.props;\n const refIds = !isArray(referenceId) ? [referenceId] : referenceId;\n let icon = referenceIndexMap && get(referenceIndexMap, refIds[0])\n ? refIds.map((r) => (\n <a\n key={r}\n className=\"col-reference-link\"\n href={`#col-reference-${r}`}\n onClick={(e) => this.scrollToReference(e, r)}\n >\n {`[${referenceIndexMap[r]}]`}\n </a>\n ))\n : <BookOutlined style={{ cursor: \"pointer\" }} />;\n\n return referenceId ? (\n <div id={`reference_${referenceId}`} key={`reference_${referenceId}`} style={this.props.style}>\n <Popover\n getPopupContainer={() =>\n document.getElementById(`reference_${referenceId}`)\n }\n placement={this.props.placement || \"left\"}\n title=\"Reference\"\n onOpenChange={(visible) => visible && this.getData()}\n content={<div style={{ maxWidth: \"500px\" }}>{this.getContent()}</div>}\n trigger={trigger || \"hover\"}\n >\n {icon}\n </Popover>\n </div>\n ) : (\n \"\"\n );\n };\n}\n\nexport default ReferencePopover;\n","export const INFRASPECIFIC_RANKS = [\n \"subspecies\",\n \"variety\",\n \"subvariety\",\n \"form\",\n \"subform\",\n \"infraspecific name\",\n];\n\nexport const getDescendantRanks = (focalRank, rankOrder) => {\n const focalIdx = rankOrder.indexOf(focalRank);\n if (focalIdx === -1) return [];\n return INFRASPECIFIC_RANKS.filter((r) => {\n const i = rankOrder.indexOf(r);\n return i > focalIdx;\n });\n};\n","import client from \"../../api/client\";\nimport config from \"../../config\";\nimport { getDescendantRanks } from \"./descendantRanks\";\n\nconst POOL_SIZE = 16;\n\nconst isMappable = (r) =>\n r?.area?.gazetteer !== \"text\" && !!r?.area?.globalId;\n\nconst runPool = async (items, worker, size) => {\n const results = new Array(items.length);\n let next = 0;\n const runners = Array.from({ length: Math.min(size, items.length) }, async () => {\n while (true) {\n const i = next++;\n if (i >= items.length) return;\n results[i] = await worker(items[i], i);\n }\n });\n await Promise.all(runners);\n return results;\n};\n\nconst searchDescendants = async (datasetKey, focalId, ranks) => {\n if (ranks.length === 0) return [];\n const params = new URLSearchParams();\n params.append(\"TAXON_ID\", focalId);\n ranks.forEach((r) => params.append(\"rank\", r));\n [\"accepted\", \"provisionally accepted\"].forEach((s) =>\n params.append(\"status\", s)\n );\n params.append(\"limit\", \"1000\");\n const url = `${config.dataApi}dataset/${datasetKey}/nameusage/search?${params}`;\n const res = await client(url);\n const list = res?.data?.result || [];\n return list\n .filter((u) => u?.usage?.id)\n .map((u) => ({\n id: u.usage.id,\n scientificName:\n u.usage?.name?.scientificName || u.usage?.label || u.usage.id,\n rank: u.usage?.name?.rank,\n parentId: u.usage?.parentId,\n }));\n};\n\nconst fetchDistributions = async (datasetKey, taxonId) => {\n const url = `${config.dataApi}dataset/${datasetKey}/taxon/${encodeURIComponent(taxonId)}/distribution`;\n try {\n const res = await client(url);\n return Array.isArray(res?.data) ? res.data : [];\n } catch {\n return [];\n }\n};\n\n/**\n * Fetch all infraspecific descendants of `focalTaxon` and their distributions.\n * Returns { taxa, descendantsFailed } where each taxon carries `mappable` (the\n * mappable subset of its distributions) and `distributions` (the full list).\n */\nexport const fetchDescendants = async ({ datasetKey, focalTaxon, rankOrder }) => {\n const ranks = getDescendantRanks(focalTaxon?.name?.rank, rankOrder);\n let descendantsFailed = false;\n let list = [];\n try {\n list = await searchDescendants(datasetKey, focalTaxon.id, ranks);\n } catch {\n descendantsFailed = true;\n return { taxa: [], descendantsFailed };\n }\n\n const distributions = await runPool(\n list,\n (t) => fetchDistributions(datasetKey, t.id),\n POOL_SIZE\n );\n\n const taxa = list.map((t, i) => {\n const all = distributions[i] || [];\n return { ...t, distributions: all, mappable: all.filter(isMappable) };\n });\n return { taxa, descendantsFailed };\n};\n","export const VIVID_PALETTE = [\n \"#E58606\",\n \"#5D69B1\",\n \"#52BCA3\",\n \"#99C945\",\n \"#CC61B0\",\n \"#24796C\",\n \"#DAA51B\",\n \"#2F8AC4\",\n \"#764E9F\",\n \"#ED645A\",\n \"#CC3A8E\",\n \"#A5AA99\",\n];\n\nconst rankIndex = (rank, rankOrder) => {\n const i = rankOrder.indexOf(rank);\n return i === -1 ? rankOrder.length : i;\n};\n\nexport const assignColors = (taxa, rankOrder) => {\n const sorted = [...taxa].sort((a, b) => {\n const ra = rankIndex(a.rank, rankOrder);\n const rb = rankIndex(b.rank, rankOrder);\n if (ra !== rb) return ra - rb;\n return a.scientificName.localeCompare(b.scientificName);\n });\n const out = {};\n sorted.forEach((t, i) => {\n out[t.id] = VIVID_PALETTE[i % VIVID_PALETTE.length];\n });\n return out;\n};\n","import { useState } from \"react\";\n\nconst wrapStyle = {\n position: \"absolute\",\n bottom: 8,\n left: 8,\n zIndex: 1000,\n background: \"#fff\",\n borderRadius: 4,\n boxShadow: \"0 1px 4px rgba(0,0,0,0.2)\",\n padding: \"6px 8px\",\n fontSize: 12,\n lineHeight: 1.5,\n maxWidth: 260,\n};\n\nconst scrollStyle = {\n maxHeight: 240,\n overflowY: \"auto\",\n};\n\nconst groupHeadingStyle = {\n fontWeight: 600,\n marginTop: 4,\n};\n\nconst firstGroupHeadingStyle = {\n ...groupHeadingStyle,\n marginTop: 0,\n};\n\nconst rowStyle = {\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n paddingLeft: 4,\n};\n\nconst swatchStyle = (color) => ({\n display: \"inline-block\",\n width: 12,\n height: 12,\n background: color,\n border: \"1px solid rgba(0,0,0,0.15)\",\n borderRadius: 2,\n flex: \"0 0 auto\",\n});\n\nconst footerToggleStyle = {\n marginTop: 6,\n cursor: \"pointer\",\n color: \"#1890ff\",\n fontSize: 11,\n};\n\nconst footerWrapStyle = {\n marginTop: 4,\n borderTop: \"1px solid #eee\",\n paddingTop: 4,\n color: \"#666\",\n};\n\nconst footerGroupHeadingStyle = {\n fontWeight: 600,\n marginTop: 4,\n};\n\nconst footerFirstGroupHeadingStyle = {\n ...footerGroupHeadingStyle,\n marginTop: 0,\n};\n\nconst footerNameStyle = {\n fontStyle: \"italic\",\n paddingLeft: 4,\n};\n\nconst totalCount = (groups) =>\n groups.reduce((sum, g) => sum + g.taxa.length, 0);\n\nconst GbifHexEntry = () => (\n <div style={rowStyle}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n <polygon\n points=\"3,1 9,1 11,6 9,11 3,11 1,6\"\n fill=\"#de1e6e\"\n stroke=\"rgba(0,0,0,0.25)\"\n strokeWidth=\"0.75\"\n />\n </svg>\n <span>GBIF occurrences</span>\n </div>\n);\n\nconst IncludedTaxaLegend = ({ visibleGroups, unmappableGroups, showGbif }) => {\n const [showUnmappable, setShowUnmappable] = useState(false);\n const visibleCount = totalCount(visibleGroups);\n const unmappableCount = totalCount(unmappableGroups);\n if (visibleCount === 0 && unmappableCount === 0 && !showGbif) return null;\n return (\n <div style={wrapStyle}>\n <div style={scrollStyle}>\n {visibleGroups.map((g, i) => (\n <div key={g.rank}>\n <div style={i === 0 ? firstGroupHeadingStyle : groupHeadingStyle}>\n {g.label}\n </div>\n {g.taxa.map((t) => (\n <div key={t.id} style={rowStyle}>\n <span style={swatchStyle(t.color)} />\n <span style={{ fontStyle: \"italic\" }}>\n {t.displayName || t.scientificName}\n </span>\n </div>\n ))}\n </div>\n ))}\n {showGbif && <GbifHexEntry />}\n </div>\n {unmappableCount > 0 && (\n <>\n <div\n style={footerToggleStyle}\n onClick={() => setShowUnmappable((v) => !v)}\n >\n {showUnmappable ? \"− Hide\" : \"+\"} {unmappableCount} without map data\n </div>\n {showUnmappable && (\n <div style={footerWrapStyle}>\n {unmappableGroups.map((g, i) => (\n <div key={g.rank}>\n <div\n style={\n i === 0\n ? footerFirstGroupHeadingStyle\n : footerGroupHeadingStyle\n }\n >\n {g.label}\n </div>\n {g.taxa.map((t) => (\n <div key={t.id} style={footerNameStyle}>\n {t.displayName || t.scientificName}\n </div>\n ))}\n </div>\n ))}\n </div>\n )}\n </>\n )}\n </div>\n );\n};\n\nexport default IncludedTaxaLegend;\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport maplibregl from \"maplibre-gl\";\nimport \"maplibre-gl/dist/maplibre-gl.css\";\nimport \"./treeControl.css\";\nimport client from \"../../api/client\";\nimport config from \"../../config\";\nimport { fetchDescendants } from \"./descendantFetch\";\nimport { getDescendantRanks, INFRASPECIFIC_RANKS } from \"./descendantRanks\";\nimport { assignColors } from \"./colorAssignment\";\nimport IncludedTaxaLegend from \"./IncludedTaxaLegend\";\n\nconst POPUP_FIELDS = [\n \"establishmentMeans\",\n \"degreeOfEstablishment\",\n \"pathway\",\n \"threatStatus\",\n \"year\",\n \"lifeStage\",\n];\n\nexport const ESTABLISHMENT_MEANS = [\n { key: \"nativeendemic\", label: \"Native endemic\", color: \"#0F8554\" },\n { key: \"native\", label: \"Native\", color: \"#87C55F\" },\n { key: \"nativereintroduced\", label: \"Native reintroduced\", color: \"#C9DB74\" },\n { key: \"introduced\", label: \"Introduced\", color: \"#FE88B1\" },\n {\n key: \"introducedassistedcolonisation\",\n label: \"Introduced assisted colonisation\",\n color: \"#DCB0F2\",\n },\n { key: \"vagrant\", label: \"Vagrant\", color: \"#F6CF71\" },\n { key: \"uncertain\", label: \"Uncertain\", color: \"#8BE0A4\" },\n];\n\nconst ESTABLISHMENT_COLORS = Object.fromEntries(\n ESTABLISHMENT_MEANS.map((m) => [m.key, m.color])\n);\nexport const MISSING_COLOR = \"#66C5CC\";\n\nconst normalizeKey = (v) =>\n String(v || \"\")\n .toLowerCase()\n .replace(/[^a-z]/g, \"\");\n\nconst resolveKey = (record) => {\n const raw = record?.establishmentMeans;\n if (raw == null || raw === \"\") return null;\n const k = normalizeKey(raw);\n return ESTABLISHMENT_COLORS[k] ? k : \"uncertain\";\n};\n\nconst colorFor = (record) => {\n const k = resolveKey(record);\n return k == null ? MISSING_COLOR : ESTABLISHMENT_COLORS[k];\n};\n\nconst POSITRON_STYLE =\n \"https://basemaps.cartocdn.com/gl/positron-gl-style/style.json\";\n\n// sessionStorage key for the GBIF overlay toggle. Persists across navigations\n// within a tab so a user who turns the overlay off on one taxon page sees it\n// off on the next (when that page actually has distribution polygons to fall\n// back to). GBIF-only maps ignore this and always show the overlay.\nconst GBIF_VISIBLE_STORAGE_KEY = \"col-browser:gbif-visible\";\n\nconst readStoredGbifVisible = (defaultValue) => {\n try {\n const v = window.sessionStorage.getItem(GBIF_VISIBLE_STORAGE_KEY);\n if (v === \"true\") return true;\n if (v === \"false\") return false;\n } catch {\n // sessionStorage can throw in private browsing or restrictive contexts.\n }\n return defaultValue;\n};\n\nconst writeStoredGbifVisible = (visible) => {\n try {\n window.sessionStorage.setItem(\n GBIF_VISIBLE_STORAGE_KEY,\n visible ? \"true\" : \"false\"\n );\n } catch {\n // ignore\n }\n};\n\n// GBIF v2 occurrence-density tile path (multitaxonomy). Concatenated with\n// config.gbifApi at request time.\nconst GBIF_TILE_PATH =\n \"/v2/map/occurrence/density/{z}/{x}/{y}@1x.png\" +\n \"?srs=EPSG%3A3857&style=iNaturalist.poly&bin=hex&hexPerTile=64\" +\n \"&hasCoordinate=true&hasGeospatialIssue=false&occurrenceStatus=PRESENT\" +\n \"&checklistKey={checklistKey}&taxonKey={taxonKey}\";\n\n// Layer IDs\nconst FOCAL_SOURCE = \"col-focal-distributions\";\nconst FOCAL_FILL = \"col-focal-fill\";\nconst FOCAL_LINE = \"col-focal-line\";\nconst GBIF_SOURCE = \"col-gbif-occurrences\";\nconst GBIF_LAYER = \"col-gbif-occurrences\";\nconst descendantSourceId = (id) => `col-descendant-${id}`;\nconst descendantFillId = (id) => `col-descendant-fill-${id}`;\nconst descendantLineId = (id) => `col-descendant-line-${id}`;\n\nconst cache = new Map();\n\nconst fetchShape = (gazetteer, id) => {\n const key = `${gazetteer}:${id}`;\n if (cache.has(key)) return cache.get(key);\n const url = `${config.dataApi}vocab/area/${key}`;\n const p = client(url, {\n headers: { Accept: \"application/geo+json\" },\n }).then(\n (r) => r.data,\n () => null\n );\n cache.set(key, p);\n return p;\n};\n\nconst escapeHtml = (s) =>\n String(s)\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n\nconst popupHtml = (record) => {\n const title = record?.area?.name || record?.area?.globalId || \"\";\n const rows = POPUP_FIELDS.map((f) => [f, record?.[f]])\n .filter(([, v]) => v != null && v !== \"\")\n .map(\n ([k, v]) =>\n `<div><strong>${escapeHtml(k)}:</strong> ${escapeHtml(v)}</div>`\n )\n .join(\"\");\n return `<div style=\"min-width:180px\"><div style=\"font-weight:600;margin-bottom:4px\">${escapeHtml(\n title\n )}</div>${rows}</div>`;\n};\n\nconst descendantPopupHtml = (taxon, record) => {\n const head =\n `<div style=\"font-weight:600;font-style:italic;margin-bottom:4px\">${escapeHtml(\n taxon.scientificName\n )}</div>` +\n `<div style=\"color:#888;margin-bottom:4px\">${escapeHtml(taxon.rank || \"\")}</div>`;\n return head + popupHtml(record);\n};\n\nconst RANK_LABEL_PLURAL = {\n subspecies: \"subspecies\",\n variety: \"varieties\",\n subvariety: \"subvarieties\",\n form: \"forms\",\n subform: \"subforms\",\n \"infraspecific name\": \"infraspecific names\",\n};\nconst rankLabelPlural = (rank) => RANK_LABEL_PLURAL[rank] || rank;\n\nconst epithet = (scientificName) => {\n if (!scientificName) return \"\";\n const tokens = scientificName.trim().split(/\\s+/);\n return tokens[tokens.length - 1];\n};\n\n// Hex swatch + label for the GBIF density layer.\nconst GbifLegendEntry = () => (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n <polygon\n points=\"3,1 9,1 11,6 9,11 3,11 1,6\"\n fill=\"#de1e6e\"\n stroke=\"rgba(0,0,0,0.25)\"\n strokeWidth=\"0.75\"\n />\n </svg>\n <span>GBIF occurrences</span>\n </div>\n);\n\n// Compute bounds [[minLng,minLat],[maxLng,maxLat]] of a FeatureCollection.\nconst computeBounds = (features) => {\n let minLng = Infinity,\n minLat = Infinity,\n maxLng = -Infinity,\n maxLat = -Infinity;\n const visit = (coords) => {\n if (typeof coords[0] === \"number\") {\n const [lng, lat] = coords;\n if (lng < minLng) minLng = lng;\n if (lng > maxLng) maxLng = lng;\n if (lat < minLat) minLat = lat;\n if (lat > maxLat) maxLat = lat;\n } else {\n for (let i = 0; i < coords.length; i++) visit(coords[i]);\n }\n };\n for (let i = 0; i < features.length; i++) {\n const g = features[i]?.geometry;\n if (g?.coordinates) visit(g.coordinates);\n }\n if (minLng === Infinity) return null;\n return [\n [minLng, minLat],\n [maxLng, maxLat],\n ];\n};\n\nconst flattenFeatures = (geojson) => {\n if (!geojson) return [];\n if (geojson.type === \"FeatureCollection\") return geojson.features || [];\n return [geojson];\n};\n\nconst supported = () => {\n if (typeof maplibregl?.supported === \"function\") return maplibregl.supported();\n // Newer maplibre-gl uses isWebGLSupported / no helper — assume true at SSR time.\n return typeof WebGLRenderingContext !== \"undefined\";\n};\n\nconst DistributionsMap = ({\n records,\n onUnmappable,\n datasetKey,\n focalTaxon,\n rankOrder,\n gbifChecklistKey,\n // true | null → show GBIF layer; false → GBIF API returned 0 occurrences,\n // grey out the toggle and skip loading tiles. Defaults to true so the\n // component works without the count check.\n gbifAvailable = true,\n}) => {\n const containerRef = useRef(null);\n const mapRef = useRef(null);\n const popupRef = useRef(null);\n const recordMapRef = useRef(new Map()); // recordKey → record\n const descendantTaxonMapRef = useRef(new Map()); // taxonId → taxon\n const descendantRecordMapRef = useRef(new Map()); // recordKey → { taxon, record }\n const focalAttachedRef = useRef(false);\n const gbifAttachedRef = useRef(false);\n const descendantLayersRef = useRef(new Set()); // taxonIds currently attached\n\n const [styleReady, setStyleReady] = useState(false);\n const [focalReady, setFocalReady] = useState(false);\n const [descendantState, setDescendantState] = useState({\n status: \"idle\", // idle | loading | ready | empty | error\n taxa: [],\n });\n const [focalVisible, setFocalVisible] = useState(true);\n // GBIF-only maps (no distribution polygons) always show the overlay\n // regardless of any saved preference — there's nothing else to look at.\n const isGbifOnly = !!gbifChecklistKey && (!records || records.length === 0);\n const [gbifVisible, setGbifVisible] = useState(() =>\n isGbifOnly ? true : readStoredGbifVisible(true)\n );\n const [visibleTaxonIds, setVisibleTaxonIds] = useState(new Set());\n const [controlOpen, setControlOpen] = useState(false);\n const fetchTriggeredRef = useRef(false);\n\n const handleToggleGbif = () => {\n setGbifVisible((v) => {\n const next = !v;\n // Only persist when this page has distribution polygons — otherwise\n // saving a toggle-off here would affect maps that have nothing else to\n // show, which the consumer explicitly asked us to keep visible.\n if (!isGbifOnly) writeStoredGbifVisible(next);\n return next;\n });\n };\n\n const presentMeans = useMemo(() => {\n if (!records?.length) return [];\n const seen = new Set();\n records.forEach((r) => {\n const k = resolveKey(r);\n if (k != null) seen.add(k);\n });\n return ESTABLISHMENT_MEANS.filter((m) => seen.has(m.key));\n }, [records]);\n\n const descendantColors = useMemo(() => {\n if (descendantState.status !== \"ready\") return {};\n return assignColors(\n descendantState.taxa.filter((t) => t.mappable.length > 0),\n rankOrder || []\n );\n }, [descendantState, rankOrder]);\n\n const descendantLegend = useMemo(() => {\n if (descendantState.status !== \"ready\") {\n return { visibleGroups: [], unmappableGroups: [] };\n }\n const decorate = (t) => ({\n ...t,\n color: descendantColors[t.id],\n displayName: epithet(t.scientificName),\n });\n const groupByRank = (taxa) => {\n const byRank = {};\n taxa.forEach((t) => {\n (byRank[t.rank] = byRank[t.rank] || []).push(decorate(t));\n });\n return INFRASPECIFIC_RANKS.filter((r) => byRank[r]).map((r) => ({\n rank: r,\n label: rankLabelPlural(r),\n taxa: byRank[r],\n }));\n };\n const visibleGroups = groupByRank(\n descendantState.taxa.filter(\n (t) => t.mappable.length > 0 && visibleTaxonIds.has(t.id)\n )\n );\n const unmappableGroups = groupByRank(\n descendantState.taxa.filter((t) => t.mappable.length === 0)\n );\n return { visibleGroups, unmappableGroups };\n }, [descendantState, descendantColors, visibleTaxonIds]);\n\n const showDescendantLegend = descendantLegend.visibleGroups.length > 0;\n\n // Mount map once.\n useEffect(() => {\n if (!containerRef.current || mapRef.current) return;\n if (!supported()) return;\n const map = new maplibregl.Map({\n container: containerRef.current,\n style: POSITRON_STYLE,\n center: [0, 20],\n zoom: 1,\n minZoom: 0,\n attributionControl: false,\n renderWorldCopies: true,\n });\n map.addControl(\n new maplibregl.AttributionControl({ compact: true }),\n \"bottom-right\"\n );\n map.addControl(\n new maplibregl.NavigationControl({ showCompass: false }),\n \"top-left\"\n );\n mapRef.current = map;\n\n map.on(\"load\", () => {\n setStyleReady(true);\n // Start the attribution control collapsed. MapLibre opens it by\n // default in compact mode and only closes it on drag; remove the\n // `compact-show` class to hide the inner attribution text until the\n // user clicks the (i) button.\n const attrib = map\n .getContainer()\n .querySelector(\".maplibregl-ctrl-attrib\");\n if (attrib) attrib.classList.remove(\"maplibregl-compact-show\");\n });\n\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => map.resize())\n : null;\n if (resizeObserver) resizeObserver.observe(containerRef.current);\n\n return () => {\n if (resizeObserver) resizeObserver.disconnect();\n if (popupRef.current) {\n popupRef.current.remove();\n popupRef.current = null;\n }\n map.remove();\n mapRef.current = null;\n focalAttachedRef.current = false;\n gbifAttachedRef.current = false;\n descendantLayersRef.current = new Set();\n };\n }, []);\n\n // Focal taxon polygons.\n useEffect(() => {\n if (!styleReady || !records?.length) return;\n const map = mapRef.current;\n if (!map) return;\n let cancelled = false;\n setFocalReady(false);\n\n Promise.allSettled(\n records.map((r) =>\n fetchShape(r.area.gazetteer, r.area.id).then((geojson) => ({\n record: r,\n geojson,\n }))\n )\n ).then((results) => {\n if (cancelled) return;\n const features = [];\n const recordMap = new Map();\n let failures = 0;\n results.forEach((res, i) => {\n if (res.status !== \"fulfilled\" || !res.value.geojson) {\n failures += 1;\n return;\n }\n const { record, geojson } = res.value;\n const color = colorFor(record);\n const recordKey = `focal-${i}`;\n recordMap.set(recordKey, record);\n flattenFeatures(geojson).forEach((f) => {\n features.push({\n ...f,\n properties: {\n ...(f.properties || {}),\n _recordKey: recordKey,\n _color: color,\n },\n });\n });\n });\n recordMapRef.current = recordMap;\n\n const data = { type: \"FeatureCollection\", features };\n if (map.getSource(FOCAL_SOURCE)) {\n map.getSource(FOCAL_SOURCE).setData(data);\n } else {\n // GBIF raster may already be on the map (its effect runs synchronously\n // while this one is async). Insert focal layers below GBIF so the\n // occurrence overlay always paints on top.\n const beforeId = map.getLayer(GBIF_LAYER) ? GBIF_LAYER : undefined;\n map.addSource(FOCAL_SOURCE, { type: \"geojson\", data });\n map.addLayer(\n {\n id: FOCAL_FILL,\n type: \"fill\",\n source: FOCAL_SOURCE,\n paint: {\n \"fill-color\": [\"coalesce\", [\"get\", \"_color\"], MISSING_COLOR],\n \"fill-opacity\": 0.65,\n },\n },\n beforeId\n );\n map.addLayer(\n {\n id: FOCAL_LINE,\n type: \"line\",\n source: FOCAL_SOURCE,\n paint: {\n \"line-color\": [\"coalesce\", [\"get\", \"_color\"], MISSING_COLOR],\n \"line-width\": 1,\n },\n },\n beforeId\n );\n map.on(\"click\", FOCAL_FILL, onFocalClick);\n map.on(\"mouseenter\", FOCAL_FILL, onMouseEnter);\n map.on(\"mouseleave\", FOCAL_FILL, onMouseLeave);\n focalAttachedRef.current = true;\n }\n\n if (features.length > 0) {\n const bounds = computeBounds(features);\n if (bounds) map.fitBounds(bounds, { padding: 20, animate: false });\n }\n if (typeof onUnmappable === \"function\") onUnmappable(failures);\n setFocalReady(true);\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [styleReady, records]);\n\n // Focal click handler — defined as stable closure that reads ref.\n const onFocalClick = (e) => {\n const map = mapRef.current;\n if (!map) return;\n const feature = e.features?.[0];\n const key = feature?.properties?._recordKey;\n const record = key ? recordMapRef.current.get(key) : null;\n if (!record) return;\n if (popupRef.current) popupRef.current.remove();\n popupRef.current = new maplibregl.Popup({ closeButton: true, maxWidth: \"320px\" })\n .setLngLat(e.lngLat)\n .setHTML(popupHtml(record))\n .addTo(map);\n };\n\n const onMouseEnter = () => {\n const map = mapRef.current;\n if (map) map.getCanvas().style.cursor = \"pointer\";\n };\n const onMouseLeave = () => {\n const map = mapRef.current;\n if (map) map.getCanvas().style.cursor = \"\";\n };\n\n // Sync focal visibility.\n useEffect(() => {\n const map = mapRef.current;\n if (!map || !focalAttachedRef.current) return;\n const v = focalVisible ? \"visible\" : \"none\";\n if (map.getLayer(FOCAL_FILL)) map.setLayoutProperty(FOCAL_FILL, \"visibility\", v);\n if (map.getLayer(FOCAL_LINE)) map.setLayoutProperty(FOCAL_LINE, \"visibility\", v);\n }, [focalVisible, focalReady]);\n\n // GBIF raster layer — added always last so it sits on top.\n useEffect(() => {\n if (!styleReady) return;\n const map = mapRef.current;\n if (!map) return;\n const removeGbif = () => {\n if (map.getLayer(GBIF_LAYER)) map.removeLayer(GBIF_LAYER);\n if (map.getSource(GBIF_SOURCE)) map.removeSource(GBIF_SOURCE);\n gbifAttachedRef.current = false;\n };\n removeGbif();\n if (!gbifChecklistKey || !focalTaxon?.id) return;\n // GBIF API said this taxon has 0 occurrences — skip the tile request.\n if (gbifAvailable === false) return;\n const url = (config.gbifApi + GBIF_TILE_PATH)\n .replace(\"{checklistKey}\", encodeURIComponent(gbifChecklistKey))\n .replace(\"{taxonKey}\", encodeURIComponent(focalTaxon.id));\n // Link to GBIF's multitaxonomy occurrence search for the focal taxon.\n // Lives on demo.gbif.org (config.gbifPortal) until that feature moves to\n // the production portal; same checklistKey we pass to the tile API.\n const searchUrl =\n config.gbifPortal +\n \"/occurrence/search?checklist_key=\" +\n encodeURIComponent(gbifChecklistKey) +\n \"&taxon_key=\" +\n encodeURIComponent(focalTaxon.id);\n map.addSource(GBIF_SOURCE, {\n type: \"raster\",\n tiles: [url],\n tileSize: 256,\n attribution:\n '<a href=\"' +\n searchUrl +\n '\" target=\"_blank\" rel=\"noopener\">GBIF</a> occurrence data',\n });\n map.addLayer({\n id: GBIF_LAYER,\n type: \"raster\",\n source: GBIF_SOURCE,\n paint: { \"raster-opacity\": 0.9 },\n layout: { visibility: gbifVisible ? \"visible\" : \"none\" },\n });\n gbifAttachedRef.current = true;\n // Intentionally no cleanup return: deps changes are handled by the\n // removeGbif() call at the top of the next run, and unmount is handled\n // by the mount effect's map.remove() which disposes everything. If we\n // returned removeGbif here, it could run after map.remove() (React\n // runs cleanups in reverse declaration order on unmount) and throw\n // because MapLibre nulls map.style during remove().\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [styleReady, gbifChecklistKey, focalTaxon?.id, gbifAvailable]);\n\n // Sync GBIF visibility.\n useEffect(() => {\n const map = mapRef.current;\n if (!map || !gbifAttachedRef.current) return;\n const v = gbifVisible ? \"visible\" : \"none\";\n if (map.getLayer(GBIF_LAYER)) map.setLayoutProperty(GBIF_LAYER, \"visibility\", v);\n }, [gbifVisible]);\n\n // Descendant layers — added once when state.status becomes \"ready\".\n useEffect(() => {\n if (!styleReady) return;\n const map = mapRef.current;\n if (!map) return;\n // Tear down previous descendant layers.\n descendantLayersRef.current.forEach((id) => {\n if (map.getLayer(descendantFillId(id))) map.removeLayer(descendantFillId(id));\n if (map.getLayer(descendantLineId(id))) map.removeLayer(descendantLineId(id));\n if (map.getSource(descendantSourceId(id))) map.removeSource(descendantSourceId(id));\n });\n descendantLayersRef.current = new Set();\n descendantTaxonMapRef.current = new Map();\n descendantRecordMapRef.current = new Map();\n\n if (descendantState.status !== \"ready\") return;\n const colors = descendantColors;\n descendantState.taxa.forEach((t) => {\n if (t.mappable.length === 0) return;\n descendantTaxonMapRef.current.set(t.id, t);\n Promise.allSettled(\n t.mappable.map((rec) =>\n fetchShape(rec.area.gazetteer, rec.area.id).then((geojson) => ({\n record: rec,\n geojson,\n }))\n )\n ).then((results) => {\n if (!mapRef.current) return;\n const features = [];\n results.forEach((res, i) => {\n if (res.status !== \"fulfilled\" || !res.value.geojson) return;\n const { record, geojson } = res.value;\n const recordKey = `desc-${t.id}-${i}`;\n descendantRecordMapRef.current.set(recordKey, { taxon: t, record });\n flattenFeatures(geojson).forEach((f) => {\n features.push({\n ...f,\n properties: {\n ...(f.properties || {}),\n _recordKey: recordKey,\n },\n });\n });\n });\n const color = colors[t.id] || MISSING_COLOR;\n const data = { type: \"FeatureCollection\", features };\n const srcId = descendantSourceId(t.id);\n if (mapRef.current.getSource(srcId)) {\n mapRef.current.getSource(srcId).setData(data);\n } else {\n mapRef.current.addSource(srcId, { type: \"geojson\", data });\n const fillId = descendantFillId(t.id);\n const lineId = descendantLineId(t.id);\n const beforeId = mapRef.current.getLayer(GBIF_LAYER) ? GBIF_LAYER : undefined;\n mapRef.current.addLayer(\n {\n id: fillId,\n type: \"fill\",\n source: srcId,\n paint: { \"fill-color\": color, \"fill-opacity\": 0.55 },\n layout: { visibility: \"none\" },\n },\n beforeId\n );\n mapRef.current.addLayer(\n {\n id: lineId,\n type: \"line\",\n source: srcId,\n paint: { \"line-color\": color, \"line-width\": 2 },\n layout: { visibility: \"none\" },\n },\n beforeId\n );\n mapRef.current.on(\"click\", fillId, onDescendantClick);\n mapRef.current.on(\"mouseenter\", fillId, onMouseEnter);\n mapRef.current.on(\"mouseleave\", fillId, onMouseLeave);\n descendantLayersRef.current.add(t.id);\n }\n });\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [styleReady, descendantState, descendantColors]);\n\n const onDescendantClick = (e) => {\n const map = mapRef.current;\n if (!map) return;\n const feature = e.features?.[0];\n const key = feature?.properties?._recordKey;\n const data = key ? descendantRecordMapRef.current.get(key) : null;\n if (!data) return;\n if (popupRef.current) popupRef.current.remove();\n popupRef.current = new maplibregl.Popup({ closeButton: true, maxWidth: \"320px\" })\n .setLngLat(e.lngLat)\n .setHTML(descendantPopupHtml(data.taxon, data.record))\n .addTo(map);\n };\n\n // Sync descendant visibility.\n useEffect(() => {\n const map = mapRef.current;\n if (!map) return;\n descendantLayersRef.current.forEach((id) => {\n const v = visibleTaxonIds.has(id) ? \"visible\" : \"none\";\n if (map.getLayer(descendantFillId(id))) {\n map.setLayoutProperty(descendantFillId(id), \"visibility\", v);\n }\n if (map.getLayer(descendantLineId(id))) {\n map.setLayoutProperty(descendantLineId(id), \"visibility\", v);\n }\n });\n }, [visibleTaxonIds, descendantState]);\n\n // Trigger descendant fetch (on control open).\n const triggerDescendantFetch = () => {\n if (fetchTriggeredRef.current) return;\n if (!datasetKey || !focalTaxon || !rankOrder) return;\n const focalRank = focalTaxon?.name?.rank;\n if (!focalRank) return;\n if (focalRank !== \"species\" && !INFRASPECIFIC_RANKS.includes(focalRank)) return;\n const ranks = getDescendantRanks(focalRank, rankOrder);\n if (ranks.length === 0) return;\n fetchTriggeredRef.current = true;\n setDescendantState({ status: \"loading\", taxa: [] });\n fetchDescendants({ datasetKey, focalTaxon, rankOrder }).then(\n ({ taxa, descendantsFailed }) => {\n if (descendantsFailed) {\n setDescendantState({ status: \"error\", taxa: [] });\n return;\n }\n if (taxa.length === 0) {\n setDescendantState({ status: \"empty\", taxa: [] });\n return;\n }\n setDescendantState({ status: \"ready\", taxa });\n }\n );\n };\n\n const openControl = () => {\n setControlOpen(true);\n triggerDescendantFetch();\n };\n\n // Group descendants by rank for the control panel.\n const descendantsByRank = useMemo(() => {\n if (descendantState.status !== \"ready\") return [];\n const byRank = {};\n descendantState.taxa\n .filter((t) => t.mappable.length > 0)\n .forEach((t) => {\n (byRank[t.rank] = byRank[t.rank] || []).push(t);\n });\n return INFRASPECIFIC_RANKS.filter((r) => byRank[r]).map((r) => ({\n rank: r,\n label: rankLabelPlural(r),\n taxa: byRank[r].slice().sort((a, b) =>\n a.scientificName.localeCompare(b.scientificName)\n ),\n }));\n }, [descendantState]);\n\n const toggleTaxon = (id) => {\n setVisibleTaxonIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const toggleRankGroup = (rankTaxa) => {\n setVisibleTaxonIds((prev) => {\n const next = new Set(prev);\n const allOn = rankTaxa.every((t) => prev.has(t.id));\n rankTaxa.forEach((t) => {\n if (allOn) next.delete(t.id);\n else next.add(t.id);\n });\n return next;\n });\n };\n\n if (!supported()) {\n return (\n <div\n style={{\n padding: 12,\n background: \"#fafafa\",\n border: \"1px solid #eee\",\n borderRadius: 4,\n color: \"#666\",\n fontSize: 12,\n }}\n >\n Maps require WebGL, which your browser doesn't support.\n </div>\n );\n }\n\n const focalName = focalTaxon?.name?.scientificName || \"This taxon\";\n\n return (\n <div className=\"col-distributions-map\" style={{ position: \"relative\" }}>\n <div\n ref={containerRef}\n style={{ height: 360, width: \"100%\", background: \"#f5f5f5\" }}\n />\n\n <LayerControl\n open={controlOpen}\n onOpen={openControl}\n onClose={() => setControlOpen(false)}\n focalName={focalName}\n focalReady={focalReady}\n focalVisible={focalVisible}\n onToggleFocal={() => setFocalVisible((v) => !v)}\n gbifEnabled={!!gbifChecklistKey}\n gbifVisible={gbifVisible}\n gbifAvailable={gbifAvailable}\n onToggleGbif={handleToggleGbif}\n descendantStatus={descendantState.status}\n descendantsByRank={descendantsByRank}\n descendantColors={descendantColors}\n visibleTaxonIds={visibleTaxonIds}\n onToggleTaxon={toggleTaxon}\n onToggleRankGroup={toggleRankGroup}\n onRetry={() => {\n fetchTriggeredRef.current = false;\n setDescendantState({ status: \"idle\", taxa: [] });\n triggerDescendantFetch();\n }}\n />\n\n {!showDescendantLegend &&\n (presentMeans.length > 0 ||\n (gbifChecklistKey && gbifAvailable !== false && gbifVisible)) && (\n <div\n style={{\n position: \"absolute\",\n bottom: 8,\n left: 8,\n zIndex: 1,\n background: \"#fff\",\n borderRadius: 4,\n boxShadow: \"0 1px 4px rgba(0,0,0,0.2)\",\n padding: \"6px 8px\",\n fontSize: 12,\n lineHeight: 1.5,\n }}\n >\n {presentMeans.map((m) => (\n <div\n key={m.key}\n style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}\n >\n <span\n style={{\n display: \"inline-block\",\n width: 12,\n height: 12,\n background: m.color,\n border: \"1px solid rgba(0,0,0,0.15)\",\n borderRadius: 2,\n }}\n />\n <span>{m.label}</span>\n </div>\n ))}\n {gbifChecklistKey && gbifAvailable !== false && gbifVisible && (\n <GbifLegendEntry />\n )}\n </div>\n )}\n {showDescendantLegend && (\n <IncludedTaxaLegend\n visibleGroups={descendantLegend.visibleGroups}\n unmappableGroups={descendantLegend.unmappableGroups}\n showGbif={!!gbifChecklistKey && gbifAvailable !== false && gbifVisible}\n />\n )}\n </div>\n );\n};\n\n// Layer toggle panel — collapsed \"+\" button at top-right that expands on click.\nconst LayerControl = ({\n open,\n onOpen,\n onClose,\n focalName,\n focalReady,\n focalVisible,\n onToggleFocal,\n gbifEnabled,\n gbifVisible,\n gbifAvailable,\n onToggleGbif,\n descendantStatus,\n descendantsByRank,\n descendantColors,\n visibleTaxonIds,\n onToggleTaxon,\n onToggleRankGroup,\n onRetry,\n}) => {\n if (!open) {\n return (\n <button\n type=\"button\"\n onClick={onOpen}\n onMouseEnter={onOpen}\n title=\"Layers\"\n style={{\n position: \"absolute\",\n top: 10,\n right: 10,\n zIndex: 2,\n width: 30,\n height: 30,\n background: \"#fff\",\n border: \"1px solid rgba(0,0,0,0.2)\",\n borderRadius: 4,\n cursor: \"pointer\",\n fontSize: 18,\n lineHeight: \"26px\",\n padding: 0,\n boxShadow: \"0 1px 4px rgba(0,0,0,0.2)\",\n }}\n >\n +\n </button>\n );\n }\n return (\n <div\n style={{\n position: \"absolute\",\n top: 10,\n right: 10,\n zIndex: 2,\n background: \"#fff\",\n borderRadius: 4,\n boxShadow: \"0 1px 4px rgba(0,0,0,0.2)\",\n padding: \"6px 10px\",\n fontSize: 12,\n lineHeight: 1.5,\n maxHeight: 320,\n overflowY: \"auto\",\n minWidth: 160,\n }}\n onMouseLeave={onClose}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <input\n type=\"checkbox\"\n checked={focalVisible}\n disabled={!focalReady}\n onChange={onToggleFocal}\n />\n <span style={{ fontStyle: \"italic\" }}>{focalName}</span>\n </div>\n {gbifEnabled && (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n opacity: gbifAvailable === false ? 0.5 : 1,\n }}\n title={\n gbifAvailable === false\n ? \"GBIF has no occurrence records for this taxon.\"\n : undefined\n }\n >\n <input\n type=\"checkbox\"\n checked={gbifAvailable === false ? false : gbifVisible}\n disabled={gbifAvailable === false}\n onChange={onToggleGbif}\n />\n <span>GBIF occurrences</span>\n </div>\n )}\n {descendantStatus === \"loading\" && (\n <div style={{ marginTop: 6, color: \"#888\" }}>Loading descendants…</div>\n )}\n {descendantStatus === \"error\" && (\n <div style={{ marginTop: 6, color: \"#888\" }}>\n Couldn't load descendants.{\" \"}\n <a onClick={onRetry} style={{ cursor: \"pointer\" }}>\n Retry\n </a>\n </div>\n )}\n {descendantStatus === \"ready\" &&\n descendantsByRank.map((group) => {\n const allOn = group.taxa.every((t) => visibleTaxonIds.has(t.id));\n const someOn = group.taxa.some((t) => visibleTaxonIds.has(t.id));\n return (\n <div key={group.rank} style={{ marginTop: 6 }}>\n <label\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n fontWeight: 600,\n }}\n >\n <input\n type=\"checkbox\"\n checked={allOn}\n ref={(el) => {\n if (el) el.indeterminate = !allOn && someOn;\n }}\n onChange={() => onToggleRankGroup(group.taxa)}\n />\n {group.label}\n </label>\n <div style={{ paddingLeft: 18 }}>\n {group.taxa.map((t) => (\n <label\n key={t.id}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n }}\n >\n <input\n type=\"checkbox\"\n checked={visibleTaxonIds.has(t.id)}\n onChange={() => onToggleTaxon(t.id)}\n />\n <span\n style={{\n display: \"inline-block\",\n width: 10,\n height: 10,\n background: descendantColors[t.id],\n border: \"1px solid rgba(0,0,0,0.15)\",\n borderRadius: 2,\n }}\n />\n <span style={{ fontStyle: \"italic\" }}>\n {epithet(t.scientificName)}\n </span>\n </label>\n ))}\n </div>\n </div>\n );\n })}\n </div>\n );\n};\n\nexport default DistributionsMap;\n","import { useState, useEffect } from \"react\";\nimport { Radio } from \"antd\";\nimport { get, keyBy, startCase } from \"lodash-es\";\nimport ReferencePopover from \"./ReferencePopover\";\nimport config from \"../config\";\n// publicClient (no CoL auth) for the third-party GBIF occurrence API below.\nimport client, { publicClient } from \"../api/client\";\nimport MergedDataBadge from \"../components/MergedDataBadge\";\nimport DistributionsMap from \"./DistributionsMap\";\n\nconst isMappable = (r) =>\n r?.area?.gazetteer !== \"text\" && !!r?.area?.globalId;\n\nconst ListView = ({ datasetKey, data }) => {\n const [iso3Map, setIso3Map] = useState({});\n\n useEffect(() => {\n let isIso = false;\n for (let i = 0; i < data.length; i++) {\n if (data[i].gazetteer === \"iso\") {\n isIso = true;\n break;\n }\n }\n if (isIso) {\n client(`${config.dataApi}vocab/country`).then((res) => {\n setIso3Map(keyBy(res.data, \"alpha3\"));\n });\n }\n }, []);\n\n return (\n <div>\n {data.map((s, i) => (\n <span key={i}>\n {s?.merged && (\n <MergedDataBadge\n createdBy={s?.createdBy}\n datasetKey={s.datasetKey}\n sourceDatasetKey={s?.sourceDatasetKey}\n verbatimSourceKey={s?.verbatimSourceKey}\n style={{ marginRight: \"4px\" }}\n />\n )}\n {(get(iso3Map, `[${get(s, \"area.name\")}].name`)\n ? startCase(get(iso3Map, `[${get(s, \"area.name\")}].name`))\n : null) ||\n get(s, \"area.name\") ||\n get(s, \"area.globalId\")}{\" \"}\n {s.referenceId && (\n <ReferencePopover\n datasetKey={datasetKey}\n referenceId={s.referenceId}\n placement=\"bottom\"\n />\n )}\n {i < data.length - 1 && \", \"}\n </span>\n ))}\n </div>\n );\n};\n\nconst DistributionsTable = ({\n datasetKey,\n data,\n style,\n showDistributionMap,\n focalTaxon,\n rankOrder,\n gbifChecklistKey,\n}) => {\n const mappable = data.filter(isMappable);\n const baseUnmappable = data.length - mappable.length;\n const hasGbifConfigured = !!gbifChecklistKey;\n const hasAnyRecords = data.length > 0;\n const [view, setView] = useState(\"map\");\n const [fetchFailures, setFetchFailures] = useState(0);\n\n // null = unknown (loading or unconfigured), number = occurrence count.\n const [gbifCount, setGbifCount] = useState(null);\n useEffect(() => {\n if (!gbifChecklistKey || !focalTaxon?.id) {\n setGbifCount(null);\n return undefined;\n }\n setGbifCount(null);\n let cancelled = false;\n publicClient\n .get(`${config.gbifApi}/v1/occurrence/search`, {\n params: {\n checklistKey: gbifChecklistKey,\n taxonKey: focalTaxon.id,\n hasCoordinate: true,\n hasGeospatialIssue: false,\n occurrenceStatus: 'PRESENT',\n limit: 0,\n },\n })\n .then(\n (res) => {\n if (!cancelled) setGbifCount(res?.data?.count ?? 0);\n },\n () => {\n // On API failure, treat as \"unknown\" — leave the toggle enabled\n // rather than greying it out for an outage.\n if (!cancelled) setGbifCount(null);\n }\n );\n return () => {\n cancelled = true;\n };\n }, [gbifChecklistKey, focalTaxon?.id]);\n\n // true → GBIF has occurrences (or unknown — still loading or API failed)\n // false → GBIF returned count = 0\n const gbifAvailable = !hasGbifConfigured\n ? false\n : gbifCount === null || gbifCount > 0;\n\n const allMappableFailed =\n mappable.length > 0 && fetchFailures >= mappable.length;\n const showMap =\n showDistributionMap &&\n (mappable.length > 0 || gbifAvailable) &&\n !(mappable.length > 0 && allMappableFailed && !gbifAvailable);\n\n // GBIF configured but found 0 occurrences AND nothing else mappable → say so.\n if (\n !showMap &&\n hasGbifConfigured &&\n mappable.length === 0 &&\n gbifCount === 0\n ) {\n return (\n <div style={style}>\n <span style={{ color: \"#888\" }}>\n No occurrence data on GBIF for this taxon.\n </span>\n </div>\n );\n }\n\n // Fall back to the plain list when there's no map to show.\n if (!showMap) {\n if (!hasAnyRecords) return null;\n return (\n <div style={style}>\n <ListView datasetKey={datasetKey} data={data} />\n </div>\n );\n }\n\n const unmappable = baseUnmappable + fetchFailures;\n const showToggle = hasAnyRecords;\n const activeView = showToggle ? view : \"map\";\n\n return (\n <div style={style}>\n {showToggle ? (\n <Radio.Group\n size=\"small\"\n value={activeView}\n onChange={(e) => setView(e.target.value)}\n style={{ marginBottom: 8 }}\n >\n <Radio.Button value=\"map\">Map</Radio.Button>\n <Radio.Button value=\"list\">List</Radio.Button>\n </Radio.Group>\n ) : (\n // Reserve the vertical space the Map/List toggle would occupy so the\n // map's top edge lines up with the \"Distributions\" label.\n <div style={{ height: 24, marginBottom: 8 }} />\n )}\n {activeView === \"map\" ? (\n <>\n <DistributionsMap\n records={mappable}\n onUnmappable={setFetchFailures}\n datasetKey={datasetKey}\n focalTaxon={focalTaxon}\n rankOrder={rankOrder}\n gbifChecklistKey={gbifChecklistKey}\n gbifAvailable={gbifAvailable}\n />\n {showToggle && unmappable > 0 && (\n <div style={{ marginTop: 6 }}>\n <a onClick={() => setView(\"list\")} style={{ cursor: \"pointer\" }}>\n +{unmappable} distribution{unmappable === 1 ? \"\" : \"s\"} not on\n map\n </a>\n </div>\n )}\n </>\n ) : (\n <ListView datasetKey={datasetKey} data={data} />\n )}\n </div>\n );\n};\n\nexport default DistributionsTable;\n"],"names":["BookOutlined","_extends","target","i","source","key","props","ref","React","AntdIcon","BookOutlinedSvg","RefIcon","ReferencePopover","__publicField","referenceId","datasetKey","references","refIds","isArray","reference","id","get","client","config","res","err","error","loading","Spin","jsx","ErrorMsg","r","e","el","referenceIndexMap","trigger","icon","Popover","visible","INFRASPECIFIC_RANKS","getDescendantRanks","focalRank","rankOrder","focalIdx","POOL_SIZE","isMappable","_a","_b","runPool","items","worker","size","results","next","runners","searchDescendants","focalId","ranks","params","s","url","u","_c","_e","_d","_f","fetchDistributions","taxonId","fetchDescendants","focalTaxon","descendantsFailed","list","distributions","t","all","VIVID_PALETTE","rankIndex","rank","assignColors","taxa","sorted","a","b","ra","rb","out","wrapStyle","scrollStyle","groupHeadingStyle","firstGroupHeadingStyle","rowStyle","swatchStyle","color","footerToggleStyle","footerWrapStyle","footerGroupHeadingStyle","footerFirstGroupHeadingStyle","footerNameStyle","totalCount","groups","sum","g","GbifHexEntry","jsxs","IncludedTaxaLegend","visibleGroups","unmappableGroups","showGbif","showUnmappable","setShowUnmappable","useState","visibleCount","unmappableCount","Fragment","v","POPUP_FIELDS","ESTABLISHMENT_MEANS","ESTABLISHMENT_COLORS","m","MISSING_COLOR","normalizeKey","resolveKey","record","raw","k","colorFor","POSITRON_STYLE","GBIF_VISIBLE_STORAGE_KEY","readStoredGbifVisible","defaultValue","writeStoredGbifVisible","GBIF_TILE_PATH","FOCAL_SOURCE","FOCAL_FILL","FOCAL_LINE","GBIF_SOURCE","GBIF_LAYER","descendantSourceId","descendantFillId","descendantLineId","cache","fetchShape","gazetteer","p","escapeHtml","popupHtml","title","rows","f","descendantPopupHtml","taxon","RANK_LABEL_PLURAL","rankLabelPlural","epithet","scientificName","tokens","GbifLegendEntry","computeBounds","features","minLng","minLat","maxLng","maxLat","visit","coords","lng","lat","flattenFeatures","geojson","supported","maplibregl","DistributionsMap","records","onUnmappable","gbifChecklistKey","gbifAvailable","containerRef","useRef","mapRef","popupRef","recordMapRef","descendantTaxonMapRef","descendantRecordMapRef","focalAttachedRef","gbifAttachedRef","descendantLayersRef","styleReady","setStyleReady","focalReady","setFocalReady","descendantState","setDescendantState","focalVisible","setFocalVisible","isGbifOnly","gbifVisible","setGbifVisible","visibleTaxonIds","setVisibleTaxonIds","controlOpen","setControlOpen","fetchTriggeredRef","handleToggleGbif","presentMeans","useMemo","seen","descendantColors","descendantLegend","decorate","groupByRank","byRank","showDescendantLegend","useEffect","map","attrib","resizeObserver","cancelled","recordMap","failures","recordKey","data","beforeId","onFocalClick","onMouseEnter","onMouseLeave","bounds","feature","searchUrl","colors","rec","srcId","fillId","lineId","onDescendantClick","triggerDescendantFetch","openControl","descendantsByRank","toggleTaxon","prev","toggleRankGroup","rankTaxa","allOn","focalName","LayerControl","open","onOpen","onClose","onToggleFocal","gbifEnabled","onToggleGbif","descendantStatus","onToggleTaxon","onToggleRankGroup","onRetry","group","someOn","ListView","iso3Map","setIso3Map","isIso","keyBy","MergedDataBadge","startCase","DistributionsTable","style","showDistributionMap","mappable","baseUnmappable","hasGbifConfigured","hasAnyRecords","view","setView","fetchFailures","setFetchFailures","gbifCount","setGbifCount","publicClient","allMappableFailed","showMap","unmappable","showToggle","activeView","Radio"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { j as c } from "./jsx-runtime-BzflLqGi.js";
|
|
2
|
-
import { useState as w, useEffect as N } from "react";
|
|
3
|
-
import { c as A } from "./config-BPRXv9x8.js";
|
|
4
|
-
import { u as Z, c as T } from "./router-CssZk5qZ.js";
|
|
5
|
-
import C from "highcharts";
|
|
6
|
-
import "highcharts/modules/exporting";
|
|
7
|
-
import K from "highcharts-react-official";
|
|
8
|
-
import { get as l, keyBy as ee } from "lodash-es";
|
|
9
|
-
import { Row as te, Col as S, Spin as ne, Switch as se } from "antd";
|
|
10
|
-
const E = 100, oe = [
|
|
11
|
-
"kingdom",
|
|
12
|
-
"phylum",
|
|
13
|
-
"class",
|
|
14
|
-
"order",
|
|
15
|
-
"family",
|
|
16
|
-
"genus",
|
|
17
|
-
"species"
|
|
18
|
-
], z = (t) => t ? `Not assigned ${t}` : "Not assigned", B = (t) => {
|
|
19
|
-
if (!t || t.length === 0) return [];
|
|
20
|
-
const o = [...t].sort((i, n) => (n.species || 0) - (i.species || 0));
|
|
21
|
-
return o.length <= E ? o : o.slice(0, E);
|
|
22
|
-
}, ie = (t, o) => {
|
|
23
|
-
const i = B(t || []), n = i.reduce((u, L) => u + (L.species || 0), 0);
|
|
24
|
-
return n >= o ? i : [
|
|
25
|
-
...i,
|
|
26
|
-
{
|
|
27
|
-
name: z(l(i, "[0].rank", "")),
|
|
28
|
-
species: o - n,
|
|
29
|
-
children: []
|
|
30
|
-
}
|
|
31
|
-
];
|
|
32
|
-
}, be = ({
|
|
33
|
-
taxon: t,
|
|
34
|
-
datasetKey: o,
|
|
35
|
-
rank: i = [],
|
|
36
|
-
dataset: n,
|
|
37
|
-
level: u = 1,
|
|
38
|
-
showLevelSwitch: L = !1,
|
|
39
|
-
darkMode: _
|
|
40
|
-
}) => {
|
|
41
|
-
const G = Z("taxon"), [I, H] = w(null), [W, k] = w(!1), [M, X] = w(!1), [m, R] = w(u);
|
|
42
|
-
N(() => {
|
|
43
|
-
R(u);
|
|
44
|
-
}, [u]), N(() => {
|
|
45
|
-
t != null && t.id && o && U();
|
|
46
|
-
}, [t, o, m]);
|
|
47
|
-
const P = async () => {
|
|
48
|
-
const r = await T(
|
|
49
|
-
`${A.dataApi}dataset/${o}/nameusage/search?TAXON_ID=${encodeURIComponent(
|
|
50
|
-
t.id
|
|
51
|
-
)}&facet=rank&status=accepted&status=provisionally%20accepted&limit=0`
|
|
52
|
-
);
|
|
53
|
-
return ee(l(r, "data.facets.rank", []), "value");
|
|
54
|
-
}, U = async () => {
|
|
55
|
-
k(!0);
|
|
56
|
-
try {
|
|
57
|
-
const r = await P(), d = oe;
|
|
58
|
-
let f = d.indexOf(l(t, "name.rank"));
|
|
59
|
-
if (f === -1) {
|
|
60
|
-
let s = i.indexOf(l(t, "name.rank")) + 1;
|
|
61
|
-
for (; f === -1 && s < i.length - 1; ) {
|
|
62
|
-
const h = d.indexOf(i[s]);
|
|
63
|
-
h > -1 && (f = h - 1), s++;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
let p, x = f + 1;
|
|
67
|
-
for (; !p && x < d.length; ) {
|
|
68
|
-
const s = l(d, `[${x}]`);
|
|
69
|
-
s && l(r, `${s}.count`, 0) > 0 ? p = s : x++;
|
|
70
|
-
}
|
|
71
|
-
if (!p) {
|
|
72
|
-
X(!0), k(!1);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
const y = (await T(
|
|
76
|
-
`${A.dataApi}dataset/${o}/taxon/${t.id}/breakdown?level=${m}`
|
|
77
|
-
)).data || [], j = l(r, "species.count", 0);
|
|
78
|
-
k(!1), V(y, j);
|
|
79
|
-
} catch {
|
|
80
|
-
k(!1);
|
|
81
|
-
}
|
|
82
|
-
}, V = (r, d) => {
|
|
83
|
-
const f = n.doi ? "https://doi.org/" + n.doi : null, p = C.getOptions().colors, O = (typeof _ == "boolean" ? _ : typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-color-scheme: dark)").matches) ? "#1f1f1f" : "#ffffff", y = {
|
|
84
|
-
click: (e) => {
|
|
85
|
-
e.point._id && G(e.point._id);
|
|
86
|
-
}
|
|
87
|
-
}, s = ie(r, d).map((e, a) => ({
|
|
88
|
-
name: e.name,
|
|
89
|
-
y: e.species,
|
|
90
|
-
_id: e.id,
|
|
91
|
-
color: p[a % p.length],
|
|
92
|
-
_kids: e.children
|
|
93
|
-
})), h = [], g = m >= 2 && s.some((e) => e._kids && e._kids.length > 0);
|
|
94
|
-
g && s.forEach((e) => {
|
|
95
|
-
const a = B(e._kids || []), v = a.reduce((b, $) => b + ($.species || 0), 0);
|
|
96
|
-
a.forEach((b, $) => {
|
|
97
|
-
const Y = -0.1 + (a.length > 1 ? $ / (a.length - 1) : 0) * 0.4;
|
|
98
|
-
h.push({
|
|
99
|
-
name: b.name,
|
|
100
|
-
y: b.species,
|
|
101
|
-
_id: b.id,
|
|
102
|
-
color: C.color(e.color).brighten(Y).get()
|
|
103
|
-
});
|
|
104
|
-
}), v < e.y && h.push({
|
|
105
|
-
name: z(l(a, "[0].rank", "")),
|
|
106
|
-
y: e.y - v,
|
|
107
|
-
color: O,
|
|
108
|
-
borderColor: O,
|
|
109
|
-
borderWidth: 0,
|
|
110
|
-
dataLabels: { enabled: !1 }
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
const F = (e) => e.map(({ _kids: a, ...v }) => v), J = d || s.reduce((e, a) => e + a.y, 0), Q = g ? {
|
|
114
|
-
formatter: function() {
|
|
115
|
-
return this.y > J / 10 ? this.point.name : null;
|
|
116
|
-
},
|
|
117
|
-
distance: -30,
|
|
118
|
-
style: {
|
|
119
|
-
color: "contrast",
|
|
120
|
-
textOutline: "1px contrast",
|
|
121
|
-
fontWeight: "bold"
|
|
122
|
-
}
|
|
123
|
-
} : {
|
|
124
|
-
formatter: function() {
|
|
125
|
-
return this.y > 1 ? "<b>" + this.point.name + ":</b> " + this.y.toLocaleString("en-GB") : null;
|
|
126
|
-
}
|
|
127
|
-
}, D = [
|
|
128
|
-
{
|
|
129
|
-
name: "Species",
|
|
130
|
-
data: F(s),
|
|
131
|
-
size: g ? "60%" : "85%",
|
|
132
|
-
dataLabels: Q,
|
|
133
|
-
point: { events: y }
|
|
134
|
-
}
|
|
135
|
-
];
|
|
136
|
-
g && D.push({
|
|
137
|
-
name: "Species",
|
|
138
|
-
data: h,
|
|
139
|
-
size: "85%",
|
|
140
|
-
innerSize: "60%",
|
|
141
|
-
dataLabels: {
|
|
142
|
-
formatter: function() {
|
|
143
|
-
return this.y > 1 ? "<b>" + this.point.name + ":</b> " + this.y.toLocaleString("en-GB") : null;
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
point: { events: y }
|
|
147
|
-
}), H({
|
|
148
|
-
chart: { type: "pie" },
|
|
149
|
-
credits: {
|
|
150
|
-
text: `${t.name.scientificName} in ${n.title}${n.version ? " (" + n.version + ")" : ""}. ${(n.doi ? "DOI:" + n.doi : null) || n.url || ""}`,
|
|
151
|
-
href: f || n.url || ""
|
|
152
|
-
},
|
|
153
|
-
title: { text: "" },
|
|
154
|
-
plotOptions: { pie: { shadow: !1, center: ["50%", "50%"] } },
|
|
155
|
-
tooltip: {},
|
|
156
|
-
series: D,
|
|
157
|
-
responsive: {
|
|
158
|
-
rules: [
|
|
159
|
-
{
|
|
160
|
-
condition: { maxWidth: 400 },
|
|
161
|
-
chartOptions: {
|
|
162
|
-
series: g ? [{}, { dataLabels: { enabled: !1 } }] : [{}]
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
]
|
|
166
|
-
},
|
|
167
|
-
exporting: {
|
|
168
|
-
chartOptions: {
|
|
169
|
-
plotOptions: { series: { dataLabels: { enabled: !0 } } }
|
|
170
|
-
},
|
|
171
|
-
fallbackToExportServer: !1
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
};
|
|
175
|
-
if (M) return null;
|
|
176
|
-
const q = L ? /* @__PURE__ */ c.jsx(
|
|
177
|
-
se,
|
|
178
|
-
{
|
|
179
|
-
size: "small",
|
|
180
|
-
checked: m === 2,
|
|
181
|
-
onChange: (r) => R(r ? 2 : 1),
|
|
182
|
-
checkedChildren: "lvl2",
|
|
183
|
-
unCheckedChildren: "lvl1",
|
|
184
|
-
style: {
|
|
185
|
-
position: "absolute",
|
|
186
|
-
top: 11,
|
|
187
|
-
right: 44,
|
|
188
|
-
zIndex: 2,
|
|
189
|
-
background: m === 2 ? "#8c8c8c" : "#bfbfbf"
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
) : null;
|
|
193
|
-
return /* @__PURE__ */ c.jsxs("div", { style: { position: "relative" }, children: [
|
|
194
|
-
q,
|
|
195
|
-
W || !I ? /* @__PURE__ */ c.jsxs(te, { style: { padding: "48px" }, children: [
|
|
196
|
-
/* @__PURE__ */ c.jsx(S, { flex: "auto" }),
|
|
197
|
-
/* @__PURE__ */ c.jsx(S, { children: /* @__PURE__ */ c.jsx(ne, { size: "large" }) }),
|
|
198
|
-
/* @__PURE__ */ c.jsx(S, { flex: "auto" })
|
|
199
|
-
] }) : /* @__PURE__ */ c.jsx(K, { highcharts: C, options: I })
|
|
200
|
-
] });
|
|
201
|
-
};
|
|
202
|
-
export {
|
|
203
|
-
be as T
|
|
204
|
-
};
|
|
205
|
-
//# sourceMappingURL=TaxonBreakdown-BshFaQql.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TaxonBreakdown-BshFaQql.js","sources":["../../src/Taxon/TaxonBreakdown.js"],"sourcesContent":["import React, { useState, useEffect } from \"react\";\nimport config from \"../config\";\nimport client from \"../api/client\";\nimport Highcharts from \"highcharts\";\nimport \"highcharts/modules/exporting\";\nimport HighchartsReact from \"highcharts-react-official\";\nimport { get, keyBy } from \"lodash-es\";\nimport { Spin, Row, Col, Switch } from \"antd\";\nimport { useNavigateTo } from \"../router\";\n\nconst MAX_SLICES_PER_RING = 100;\nconst canonicalRanks = [\n \"kingdom\",\n \"phylum\",\n \"class\",\n \"order\",\n \"family\",\n \"genus\",\n \"species\",\n];\n\nconst notAssignedLabel = (rk) => (rk ? `Not assigned ${rk}` : \"Not assigned\");\n\nconst sortAndClip = (nodes) => {\n if (!nodes || nodes.length === 0) return [];\n const sorted = [...nodes].sort((a, b) => (b.species || 0) - (a.species || 0));\n return sorted.length <= MAX_SLICES_PER_RING\n ? sorted\n : sorted.slice(0, MAX_SLICES_PER_RING);\n};\n\n// Append a \"Not assigned <rank>\" slice for the difference between a parent's\n// total species count and the sum of its visible children. Covers two cases:\n// 1. species that sit directly under the parent without an intermediate rank\n// 2. species under children that were clipped out by sortAndClip\nconst padNotAssigned = (kids, parentSpecies) => {\n const sorted = sortAndClip(kids || []);\n const sum = sorted.reduce((a, n) => a + (n.species || 0), 0);\n if (sum >= parentSpecies) return sorted;\n return [\n ...sorted,\n {\n name: notAssignedLabel(get(sorted, \"[0].rank\", \"\")),\n species: parentSpecies - sum,\n children: [],\n },\n ];\n};\n\nconst TaxonBreakdown = ({\n taxon,\n datasetKey,\n rank = [],\n dataset,\n level = 1,\n showLevelSwitch = false,\n darkMode,\n}) => {\n const navigateToTaxon = useNavigateTo(\"taxon\");\n const [options, setOptions] = useState(null);\n const [loading, setLoading] = useState(false);\n const [invalid, setInvalid] = useState(false);\n // The chart's effective level is controlled internally when the switch\n // is enabled, so toggling can refetch + re-render the chart. Otherwise\n // the prop drives directly.\n const [activeLevel, setActiveLevel] = useState(level);\n useEffect(() => {\n setActiveLevel(level);\n }, [level]);\n useEffect(() => {\n if (taxon?.id && datasetKey) {\n getData();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [taxon, datasetKey, activeLevel]);\n\n const getOverView = async () => {\n const res = await client(\n `${\n config.dataApi\n }dataset/${datasetKey}/nameusage/search?TAXON_ID=${encodeURIComponent(\n taxon.id\n )}&facet=rank&status=accepted&status=provisionally%20accepted&limit=0`\n );\n return keyBy(get(res, \"data.facets.rank\", []), \"value\");\n };\n\n const getData = async () => {\n setLoading(true);\n try {\n const counts = await getOverView();\n\n // confirm the focal taxon has at least one child rank with content\n const ranks = canonicalRanks;\n let taxonRankIdx = ranks.indexOf(get(taxon, \"name.rank\"));\n if (taxonRankIdx === -1) {\n let rankIndex = rank.indexOf(get(taxon, \"name.rank\")) + 1;\n while (taxonRankIdx === -1 && rankIndex < rank.length - 1) {\n const canonicalRankIndex = ranks.indexOf(rank[rankIndex]);\n if (canonicalRankIndex > -1) {\n taxonRankIdx = canonicalRankIndex - 1;\n }\n rankIndex++;\n }\n }\n let childRank;\n let childRankIndex = taxonRankIdx + 1;\n while (!childRank && childRankIndex < ranks.length) {\n const nextRank = get(ranks, `[${childRankIndex}]`);\n if (nextRank && get(counts, `${nextRank}.count`, 0) > 0) {\n childRank = nextRank;\n } else {\n childRankIndex++;\n }\n }\n if (!childRank) {\n setInvalid(true);\n setLoading(false);\n return;\n }\n\n const res = await client(\n `${config.dataApi}dataset/${datasetKey}/taxon/${taxon.id}/breakdown?level=${activeLevel}`\n );\n const children = res.data || [];\n const totalSpecies = get(counts, \"species.count\", 0);\n\n setLoading(false);\n buildChart(children, totalSpecies);\n } catch (err) {\n setLoading(false);\n }\n };\n\n const buildChart = (children, totalSpecies) => {\n const DOI = dataset.doi ? \"https://doi.org/\" + dataset.doi : null;\n const baseColors = Highcharts.getOptions().colors;\n // Colour used for outer-ring \"gap\" slices: match the page background so\n // the wedge reads as empty space rather than overlapping the inner pie.\n // Follows the explicit `darkMode` prop if given, otherwise prefers-color-scheme.\n const prefersDark =\n typeof darkMode === \"boolean\"\n ? darkMode\n : typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\" &&\n window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n const gapColor = prefersDark ? \"#1f1f1f\" : \"#ffffff\";\n const taxonClickHandler = {\n click: (e) => {\n if (e.point._id) {\n navigateToTaxon(e.point._id);\n }\n },\n };\n\n // Inner pie: direct children of the focal taxon. Pad with a single\n // \"Not assigned <rank>\" slice if focal-taxon species don't fully sum up.\n const innerNodes = padNotAssigned(children, totalSpecies);\n const innerData = innerNodes.map((n, i) => ({\n name: n.name,\n y: n.species,\n _id: n.id,\n color: baseColors[i % baseColors.length],\n _kids: n.children,\n }));\n\n // Outer ring: children of each inner slice (grandchildren of focal),\n // coloured as a monochrome brightness shift of the parent so each\n // family of arcs reads as one hue group. Only rendered when level >= 2\n // AND the response actually carries that depth. With level=1 we draw\n // a single-ring pie even if the API returned nested children.\n const outerData = [];\n const hasOuterData =\n activeLevel >= 2 && innerData.some((s) => s._kids && s._kids.length > 0);\n if (hasOuterData) {\n innerData.forEach((slice) => {\n const sorted = sortAndClip(slice._kids || []);\n const sum = sorted.reduce((a, n) => a + (n.species || 0), 0);\n sorted.forEach((g, j) => {\n const t = sorted.length > 1 ? j / (sorted.length - 1) : 0;\n const shift = -0.1 + t * 0.4;\n outerData.push({\n name: g.name,\n y: g.species,\n _id: g.id,\n color: Highcharts.color(slice.color).brighten(shift).get(),\n });\n });\n // Where children don't fully account for the inner slice, add a\n // transparent gap slice so the outer ring stays angularly aligned\n // with the inner pie but the missing portion reads as empty space\n // (rather than a labelled \"Not assigned\" wedge).\n if (sum < slice.y) {\n outerData.push({\n name: notAssignedLabel(get(sorted, \"[0].rank\", \"\")),\n y: slice.y - sum,\n color: gapColor,\n borderColor: gapColor,\n borderWidth: 0,\n dataLabels: { enabled: false },\n });\n }\n });\n }\n\n const clean = (rows) => rows.map(({ _kids, ...rest }) => rest);\n const grandTotal = totalSpecies || innerData.reduce((a, s) => a + s.y, 0);\n\n const innerLabelStyle = {\n color: \"contrast\",\n textOutline: \"1px contrast\",\n fontWeight: \"bold\",\n };\n\n // Inner-ring data labels: only positioned inside the ring when there's\n // an outer ring fighting for the external label gutter. With just one\n // ring (level=1) the labels live outside the chart, same as the outer\n // ring at level=2, with the slice name + species count.\n const innerDataLabels = hasOuterData\n ? {\n formatter: function () {\n return this.y > grandTotal / 10 ? this.point.name : null;\n },\n distance: -30,\n style: innerLabelStyle,\n }\n : {\n formatter: function () {\n return this.y > 1\n ? \"<b>\" +\n this.point.name +\n \":</b> \" +\n this.y.toLocaleString(\"en-GB\")\n : null;\n },\n };\n\n const series = [\n {\n name: \"Species\",\n data: clean(innerData),\n size: hasOuterData ? \"60%\" : \"85%\",\n dataLabels: innerDataLabels,\n point: { events: taxonClickHandler },\n },\n ];\n if (hasOuterData) {\n series.push({\n name: \"Species\",\n data: outerData,\n size: \"85%\",\n innerSize: \"60%\",\n dataLabels: {\n formatter: function () {\n return this.y > 1\n ? \"<b>\" +\n this.point.name +\n \":</b> \" +\n this.y.toLocaleString(\"en-GB\")\n : null;\n },\n },\n point: { events: taxonClickHandler },\n });\n }\n\n setOptions({\n chart: { type: \"pie\" },\n credits: {\n text: `${taxon.name.scientificName} in ${dataset.title}${\n dataset.version ? \" (\" + dataset.version + \")\" : \"\"\n }. ${(dataset.doi ? \"DOI:\" + dataset.doi : null) || dataset.url || \"\"}`,\n href: DOI || dataset.url || \"\",\n },\n title: { text: \"\" },\n plotOptions: { pie: { shadow: false, center: [\"50%\", \"50%\"] } },\n tooltip: {},\n series,\n responsive: {\n rules: [\n {\n condition: { maxWidth: 400 },\n chartOptions: {\n series: hasOuterData\n ? [{}, { dataLabels: { enabled: false } }]\n : [{}],\n },\n },\n ],\n },\n exporting: {\n chartOptions: {\n plotOptions: { series: { dataLabels: { enabled: true } } },\n },\n fallbackToExportServer: false,\n },\n });\n };\n\n if (invalid) return null;\n\n // Place the level toggle inside the chart's top-right area, just left of\n // the Highcharts context-menu (≡) icon, so it doesn't consume an extra\n // row. Colourless switch with lvl1 / lvl2 labels.\n const levelSwitch = showLevelSwitch ? (\n <Switch\n size=\"small\"\n checked={activeLevel === 2}\n onChange={(checked) => setActiveLevel(checked ? 2 : 1)}\n checkedChildren=\"lvl2\"\n unCheckedChildren=\"lvl1\"\n style={{\n position: \"absolute\",\n top: 11,\n right: 44,\n zIndex: 2,\n background: activeLevel === 2 ? \"#8c8c8c\" : \"#bfbfbf\",\n }}\n />\n ) : null;\n\n return (\n <div style={{ position: \"relative\" }}>\n {levelSwitch}\n {loading || !options ? (\n <Row style={{ padding: \"48px\" }}>\n <Col flex=\"auto\"></Col>\n <Col>\n <Spin size=\"large\" />\n </Col>\n <Col flex=\"auto\"></Col>\n </Row>\n ) : (\n <HighchartsReact highcharts={Highcharts} options={options} />\n )}\n </div>\n );\n};\n\nexport default TaxonBreakdown;\n"],"names":["MAX_SLICES_PER_RING","canonicalRanks","notAssignedLabel","rk","sortAndClip","nodes","sorted","a","b","padNotAssigned","kids","parentSpecies","sum","n","get","TaxonBreakdown","taxon","datasetKey","rank","dataset","level","showLevelSwitch","darkMode","navigateToTaxon","useNavigateTo","options","setOptions","useState","loading","setLoading","invalid","setInvalid","activeLevel","setActiveLevel","useEffect","getData","getOverView","res","client","config","keyBy","counts","ranks","taxonRankIdx","rankIndex","canonicalRankIndex","childRank","childRankIndex","nextRank","children","totalSpecies","buildChart","DOI","baseColors","Highcharts","gapColor","taxonClickHandler","innerData","i","outerData","hasOuterData","s","slice","g","j","shift","clean","rows","_kids","rest","grandTotal","innerDataLabels","series","levelSwitch","jsx","Switch","checked","jsxs","Row","Col","Spin","HighchartsReact"],"mappings":"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"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { j as K } from "./jsx-runtime-BzflLqGi.js";
|
|
2
|
-
import { useState as j, useEffect as k, useMemo as g, useCallback as T } from "react";
|
|
3
|
-
import d from "query-string";
|
|
4
|
-
const y = (n) => n === "hash", b = (n) => {
|
|
5
|
-
if (y(n)) {
|
|
6
|
-
const o = typeof window < "u" && window.location.hash || "", e = o.startsWith("#") ? o.slice(1) : o, t = e.indexOf("?");
|
|
7
|
-
return {
|
|
8
|
-
path: t >= 0 ? e.slice(0, t) : e,
|
|
9
|
-
search: t >= 0 ? e.slice(t) : ""
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
path: typeof window < "u" && window.location.pathname || "",
|
|
14
|
-
search: typeof window < "u" && window.location.search || ""
|
|
15
|
-
};
|
|
16
|
-
}, v = (n, o, e) => {
|
|
17
|
-
const t = e && Object.keys(e).length > 0 ? `?${d.stringify(e, { arrayFormat: "none" })}` : "";
|
|
18
|
-
if (y(n)) {
|
|
19
|
-
const s = `${o}${t}`;
|
|
20
|
-
window.location.hash = s;
|
|
21
|
-
} else {
|
|
22
|
-
const s = `${o}${t}`;
|
|
23
|
-
window.history.pushState(null, "", s), window.dispatchEvent(new PopStateEvent("popstate"));
|
|
24
|
-
}
|
|
25
|
-
}, E = (n, o) => {
|
|
26
|
-
const e = y(n) ? "hashchange" : "popstate";
|
|
27
|
-
return window.addEventListener(e, o), () => window.removeEventListener(e, o);
|
|
28
|
-
}, f = (n, o, e) => {
|
|
29
|
-
if (!o) return null;
|
|
30
|
-
const t = e == null || typeof e == "object" ? "" : String(e), s = typeof e == "object" && e && Object.keys(e).length > 0 ? `?${d.stringify(e, { arrayFormat: "none" })}` : "", r = `${o}${t}${s}`;
|
|
31
|
-
return y(n) ? `#${r}` : r;
|
|
32
|
-
}, p = (n, o, e, t) => {
|
|
33
|
-
if (!e) return;
|
|
34
|
-
if (o === "reload") {
|
|
35
|
-
const a = f(n, e, t);
|
|
36
|
-
a != null && typeof window < "u" && window.location.assign(a);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
let s = e, r = null;
|
|
40
|
-
typeof t == "string" || typeof t == "number" ? s = `${e}${t}` : t && typeof t == "object" && (r = t), v(n, s, r);
|
|
41
|
-
}, N = (n, o, e) => ({
|
|
42
|
-
hrefForTaxon: (t) => f(n, e.taxon, t),
|
|
43
|
-
hrefForTree: (t) => f(n, e.tree, t),
|
|
44
|
-
hrefForSearch: (t) => f(n, e.search, t),
|
|
45
|
-
hrefForSource: (t) => f(n, e.source, t),
|
|
46
|
-
onNavigateToTaxon: (t) => p(n, o, e.taxon, t),
|
|
47
|
-
onNavigateToTree: (t) => p(n, o, e.tree, t),
|
|
48
|
-
onNavigateToSearch: (t) => p(n, o, e.search, t),
|
|
49
|
-
onNavigateToSource: (t) => p(n, o, e.source, t)
|
|
50
|
-
}), u = (n, o) => {
|
|
51
|
-
if (o) {
|
|
52
|
-
if (!n.startsWith(o)) {
|
|
53
|
-
const e = n.indexOf(o);
|
|
54
|
-
return e < 0 ? void 0 : n.slice(e + o.length).split("/").filter(Boolean).pop();
|
|
55
|
-
}
|
|
56
|
-
return n.slice(o.length).split("/").filter(Boolean).pop();
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
function I(n, o) {
|
|
60
|
-
const { kind: e, mode: t = "path", navigation: s = "spa", paths: r = {} } = o, a = (m) => {
|
|
61
|
-
const [B, S] = j(0);
|
|
62
|
-
k(() => E(t, () => S((l) => l + 1)), []);
|
|
63
|
-
const { path: c, search: $ } = b(t), F = g(() => N(t, s, r), []);
|
|
64
|
-
let i = {};
|
|
65
|
-
if (e === "taxon")
|
|
66
|
-
i.taxonKey = u(c, r.taxon);
|
|
67
|
-
else if (e === "source")
|
|
68
|
-
i.sourceDatasetKey = u(c, r.source);
|
|
69
|
-
else if (e === "taxonBreakdown")
|
|
70
|
-
i.taxonId = u(c, r.taxonBreakdown);
|
|
71
|
-
else if (e === "taxonDistribution")
|
|
72
|
-
i.taxonId = u(c, r.taxonDistribution);
|
|
73
|
-
else if (e === "bibtex")
|
|
74
|
-
i.sourceDatasetKey = u(c, r.bibtex);
|
|
75
|
-
else if (e === "tree") {
|
|
76
|
-
const l = d.parse($);
|
|
77
|
-
i.expandedTaxonKey = l.taxonKey || void 0, i.onExpandedTaxonKeyChange = T((h) => {
|
|
78
|
-
const w = b(t), x = d.parse(w.search);
|
|
79
|
-
h ? x.taxonKey = h : delete x.taxonKey, v(t, w.path || r.tree || "/", x);
|
|
80
|
-
}, []);
|
|
81
|
-
} else if (e === "search") {
|
|
82
|
-
const l = d.parse($, { arrayFormat: "none" });
|
|
83
|
-
i.filters = l, i.onFiltersChange = T((h) => {
|
|
84
|
-
const w = b(t);
|
|
85
|
-
v(t, w.path || r.search || "/", h);
|
|
86
|
-
}, []);
|
|
87
|
-
}
|
|
88
|
-
return /* @__PURE__ */ K.jsx(n, { ...F, ...i, ...m });
|
|
89
|
-
};
|
|
90
|
-
return a.displayName = `withRouting(${n.displayName || n.name || "Component"})`, a;
|
|
91
|
-
}
|
|
92
|
-
export {
|
|
93
|
-
I as w
|
|
94
|
-
};
|
|
95
|
-
//# sourceMappingURL=index-CNK3JADR.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-CNK3JADR.js","sources":["../../src/url/index.js"],"sourcesContent":["import React, { useState, useEffect, useMemo, useCallback } from \"react\";\nimport qs from \"query-string\";\n\n// withRouting(Component, options): adapts a controlled col-browser\n// component to read/write the host page's URL.\n//\n// options.kind — one of \"taxon\" | \"tree\" | \"source\" | \"sourceList\" |\n// \"search\" | \"taxonBreakdown\" | \"taxonDistribution\" |\n// \"bibtex\"\n// options.mode — \"path\" (recommended for the COL portal) or \"hash\"\n// (used by the GitHub Pages demo)\n// options.navigation — \"spa\" (default) or \"reload\". Controls what the four\n// onNavigateToX callbacks do when an in-component\n// action triggers cross-page navigation (e.g. a\n// Highcharts pie segment click with no <a href>\n// fallback). \"spa\" uses history.pushState — right\n// for SPA hosts (react-router, Next.js, TanStack\n// Router). \"reload\" calls window.location.assign,\n// forcing the browser to load the target page —\n// right for static / multi-page hosts (a Jekyll\n// portal, the GitHub Pages demo, any plain HTML).\n// The in-component state callbacks\n// (onExpandedTaxonKeyChange, onFiltersChange) always\n// use pushState so they don't reload the page while\n// the user is interacting with a single component.\n// options.paths — prefix strings for the four navigation targets, e.g.\n// { taxon: \"/taxon/\", tree: \"/tree\", search: \"/search\",\n// source: \"/source/\" }. For hash mode, the prefixes\n// are applied to window.location.hash (without the\n// leading #). Both modes use plain pathnames; query\n// strings are only used for `expandedTaxonKey` (Tree)\n// and `filters` (Search).\n//\n// All wrappers provide the four hrefForX + onNavigateToX pairs, derived\n// from `paths` and the active routing mode. Kind-specific wrappers also\n// inject the controlled identifier and the appropriate change handler\n// (e.g. `filters` + `onFiltersChange` for Search).\n\nconst isHash = (mode) => mode === \"hash\";\n\nconst readLocationKind = (mode) => {\n if (isHash(mode)) {\n const raw = (typeof window !== \"undefined\" && window.location.hash) || \"\";\n const hash = raw.startsWith(\"#\") ? raw.slice(1) : raw;\n const qIdx = hash.indexOf(\"?\");\n return {\n path: qIdx >= 0 ? hash.slice(0, qIdx) : hash,\n search: qIdx >= 0 ? hash.slice(qIdx) : \"\",\n };\n }\n return {\n path: (typeof window !== \"undefined\" && window.location.pathname) || \"\",\n search: (typeof window !== \"undefined\" && window.location.search) || \"\",\n };\n};\n\nconst writeLocation = (mode, path, search) => {\n const searchStr = search && Object.keys(search).length > 0\n ? `?${qs.stringify(search, { arrayFormat: \"none\" })}`\n : \"\";\n if (isHash(mode)) {\n const next = `${path}${searchStr}`;\n window.location.hash = next;\n } else {\n const url = `${path}${searchStr}`;\n window.history.pushState(null, \"\", url);\n // notify any listeners (the adapter subscribes via popstate / hashchange)\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n }\n};\n\nconst subscribe = (mode, cb) => {\n const evt = isHash(mode) ? \"hashchange\" : \"popstate\";\n window.addEventListener(evt, cb);\n return () => window.removeEventListener(evt, cb);\n};\n\n// Build href: the URL the host would land on for each target.\nconst hrefFor = (mode, prefix, args) => {\n if (!prefix) return null;\n const arg = args == null ? \"\" : typeof args === \"object\" ? \"\" : String(args);\n const tail = typeof args === \"object\" && args && Object.keys(args).length > 0\n ? `?${qs.stringify(args, { arrayFormat: \"none\" })}`\n : \"\";\n const url = `${prefix}${arg}${tail}`;\n return isHash(mode) ? `#${url}` : url;\n};\n\nconst navigate = (mode, navigation, prefix, args) => {\n if (!prefix) return;\n if (navigation === \"reload\") {\n // Force a real browser navigation. hrefFor builds the same URL the\n // adapter would render in href= attributes, so the imperative and\n // anchor paths land on identical URLs.\n const url = hrefFor(mode, prefix, args);\n if (url != null && typeof window !== \"undefined\") {\n window.location.assign(url);\n }\n return;\n }\n // Default \"spa\" behaviour: pushState + popstate so an SPA host re-renders.\n let path = prefix;\n let search = null;\n if (typeof args === \"string\" || typeof args === \"number\") {\n path = `${prefix}${args}`;\n } else if (args && typeof args === \"object\") {\n search = args;\n }\n writeLocation(mode, path, search);\n};\n\nconst buildNavProps = (mode, navigation, paths) => ({\n hrefForTaxon: (id) => hrefFor(mode, paths.taxon, id),\n hrefForTree: (a) => hrefFor(mode, paths.tree, a),\n hrefForSearch: (a) => hrefFor(mode, paths.search, a),\n hrefForSource: (id) => hrefFor(mode, paths.source, id),\n\n onNavigateToTaxon: (id) => navigate(mode, navigation, paths.taxon, id),\n onNavigateToTree: (a) => navigate(mode, navigation, paths.tree, a),\n onNavigateToSearch: (a) => navigate(mode, navigation, paths.search, a),\n onNavigateToSource: (id) => navigate(mode, navigation, paths.source, id),\n});\n\n// Extract the last path segment after a prefix, ignoring trailing slash.\nconst lastSegmentAfter = (path, prefix) => {\n if (!prefix) return undefined;\n if (!path.startsWith(prefix)) {\n // Allow matching when the host wraps in a base path; fall back to\n // \"anything after the prefix substring\".\n const i = path.indexOf(prefix);\n if (i < 0) return undefined;\n return path.slice(i + prefix.length).split(\"/\").filter(Boolean).pop();\n }\n return path.slice(prefix.length).split(\"/\").filter(Boolean).pop();\n};\n\nexport function withRouting(Component, options) {\n const { kind, mode = \"path\", navigation = \"spa\", paths = {} } = options;\n\n const Wrapped = (props) => {\n const [tick, setTick] = useState(0);\n useEffect(() => subscribe(mode, () => setTick((t) => t + 1)), []);\n\n const { path, search } = readLocationKind(mode);\n\n const navProps = useMemo(() => buildNavProps(mode, navigation, paths), []);\n\n // Controlled identifier per kind.\n let extra = {};\n if (kind === \"taxon\") {\n extra.taxonKey = lastSegmentAfter(path, paths.taxon);\n } else if (kind === \"source\") {\n extra.sourceDatasetKey = lastSegmentAfter(path, paths.source);\n } else if (kind === \"taxonBreakdown\") {\n extra.taxonId = lastSegmentAfter(path, paths.taxonBreakdown);\n } else if (kind === \"taxonDistribution\") {\n extra.taxonId = lastSegmentAfter(path, paths.taxonDistribution);\n } else if (kind === \"bibtex\") {\n extra.sourceDatasetKey = lastSegmentAfter(path, paths.bibtex);\n } else if (kind === \"tree\") {\n const parsed = qs.parse(search);\n extra.expandedTaxonKey = parsed.taxonKey || undefined;\n extra.onExpandedTaxonKeyChange = useCallback((id) => {\n const cur = readLocationKind(mode);\n const next = qs.parse(cur.search);\n if (id) next.taxonKey = id;\n else delete next.taxonKey;\n writeLocation(mode, cur.path || paths.tree || \"/\", next);\n }, []);\n } else if (kind === \"search\") {\n const parsed = qs.parse(search, { arrayFormat: \"none\" });\n extra.filters = parsed;\n extra.onFiltersChange = useCallback((filters) => {\n const cur = readLocationKind(mode);\n writeLocation(mode, cur.path || paths.search || \"/\", filters);\n }, []);\n }\n // sourceList: no controlled identifier; only nav callbacks.\n\n return <Component {...navProps} {...extra} {...props} />;\n };\n Wrapped.displayName = `withRouting(${\n Component.displayName || Component.name || \"Component\"\n })`;\n return Wrapped;\n}\n\nexport default withRouting;\n"],"names":["isHash","mode","readLocationKind","raw","hash","qIdx","writeLocation","path","search","searchStr","qs","next","url","subscribe","cb","evt","hrefFor","prefix","args","arg","tail","navigate","navigation","buildNavProps","paths","id","a","lastSegmentAfter","i","withRouting","Component","options","kind","Wrapped","props","tick","setTick","useState","useEffect","t","navProps","useMemo","extra","parsed","useCallback","cur","filters"],"mappings":"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"}
|