@fusedashlabs/widgets 0.4.2 → 0.4.4
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/CHANGELOG.md +12 -0
- package/dist/components/kpi-widget/lib/normalize.d.ts.map +1 -1
- package/dist/components/kpi-widget/lib/normalize.js +26 -7
- package/dist/components/kpi-widget/lib/normalize.js.map +1 -1
- package/dist/components/map-chart/lib/constants.d.ts +2 -0
- package/dist/components/map-chart/lib/constants.d.ts.map +1 -1
- package/dist/components/map-chart/lib/constants.js +6 -0
- package/dist/components/map-chart/lib/constants.js.map +1 -1
- package/dist/components/map-chart/lib/geo-index.d.ts.map +1 -1
- package/dist/components/map-chart/lib/geo-index.js +5 -1
- package/dist/components/map-chart/lib/geo-index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.4.4 — 2026-09-08
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Country join indexes `Czechia` against Natural Earth `Czech Rep.` / `Czech Republic`.
|
|
10
|
+
|
|
11
|
+
## 0.4.3 — 2026-09-07
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- KPI widget unwraps signed data-link envelopes (`data.items` / `config.items`) instead of treating the persist wrapper as a single empty KPI.
|
|
16
|
+
|
|
5
17
|
## 0.4.2 — 2026-09-07
|
|
6
18
|
|
|
7
19
|
### Fixed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAc,MAAM,YAAY,CAAC;AAyC5E,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE5D;AAgFD,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAqBrE"}
|
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
import { isAdvancedKpiItem, extractCardsFromKpi } from "./extract.js";
|
|
2
2
|
const EMPTY = { layout: "empty", cards: [], supporting: [] };
|
|
3
3
|
function isRawKpiItem(input) {
|
|
4
|
-
|
|
4
|
+
if (input == null || typeof input !== "object" || Array.isArray(input)) return false;
|
|
5
|
+
const obj = input;
|
|
6
|
+
if (Array.isArray(obj.items) || Array.isArray(obj.kpis)) return false;
|
|
7
|
+
const nested = obj.data;
|
|
8
|
+
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
9
|
+
const inner = nested;
|
|
10
|
+
if (Array.isArray(inner.items) || Array.isArray(inner.kpis)) return false;
|
|
11
|
+
}
|
|
12
|
+
return "column" in obj || "type" in obj || Array.isArray(obj.data);
|
|
13
|
+
}
|
|
14
|
+
function asItemList(input) {
|
|
15
|
+
const obj = input;
|
|
16
|
+
if (Array.isArray(obj.items) && obj.items.every((row) => row && typeof row === "object")) {
|
|
17
|
+
return obj.items;
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(obj.kpis) && obj.kpis.every((row) => row && typeof row === "object")) {
|
|
20
|
+
return obj.kpis;
|
|
21
|
+
}
|
|
22
|
+
for (const candidate of [obj.data, obj.config]) {
|
|
23
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) continue;
|
|
24
|
+
const nested = asItemList(candidate);
|
|
25
|
+
if (nested) return nested;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
5
28
|
}
|
|
6
29
|
function isNormalizedModel(input) {
|
|
7
30
|
return Array.isArray(input.cards) && "layout" in input;
|
|
@@ -76,12 +99,8 @@ function normalizeKpiData(input) {
|
|
|
76
99
|
if (typeof input === "object") {
|
|
77
100
|
if (isNormalizedModel(input)) return input;
|
|
78
101
|
const topName = typeof input.name === "string" ? input.name : void 0;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
if (Array.isArray(input.kpis)) {
|
|
83
|
-
return buildFromItems(input.kpis, topName);
|
|
84
|
-
}
|
|
102
|
+
const items = asItemList(input);
|
|
103
|
+
if (items) return buildFromItems(items, topName);
|
|
85
104
|
if (isRawKpiItem(input)) {
|
|
86
105
|
return buildFromItems([input], topName);
|
|
87
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"sourcesContent":["import { extractCardsFromKpi, isAdvancedKpiItem } from './extract.js';\nimport type { KpiWidgetData, KpiWidgetModel, RawKpiItem } from './types.js';\n\nconst EMPTY: KpiWidgetModel = { layout: 'empty', cards: [], supporting: [] };\n\nfunction isRawKpiItem(input: unknown): input is RawKpiItem {\n
|
|
1
|
+
{"version":3,"file":"normalize.js","sources":["../../../../src/components/kpi-widget/lib/normalize.ts"],"sourcesContent":["import { extractCardsFromKpi, isAdvancedKpiItem } from './extract.js';\nimport type { KpiWidgetData, KpiWidgetModel, RawKpiItem } from './types.js';\n\nconst EMPTY: KpiWidgetModel = { layout: 'empty', cards: [], supporting: [] };\n\nfunction isRawKpiItem(input: unknown): input is RawKpiItem {\n if (input == null || typeof input !== 'object' || Array.isArray(input)) return false;\n const obj = input as Record<string, unknown>;\n if (Array.isArray(obj.items) || Array.isArray(obj.kpis)) return false;\n const nested = obj.data;\n if (nested && typeof nested === 'object' && !Array.isArray(nested)) {\n const inner = nested as Record<string, unknown>;\n if (Array.isArray(inner.items) || Array.isArray(inner.kpis)) return false;\n }\n return 'column' in obj || 'type' in obj || Array.isArray(obj.data);\n}\n\nfunction asItemList(input: object): RawKpiItem[] | null {\n const obj = input as {\n items?: unknown;\n kpis?: unknown;\n data?: unknown;\n config?: unknown;\n };\n if (Array.isArray(obj.items) && obj.items.every((row) => row && typeof row === 'object')) {\n return obj.items as RawKpiItem[];\n }\n if (Array.isArray(obj.kpis) && obj.kpis.every((row) => row && typeof row === 'object')) {\n return obj.kpis as RawKpiItem[];\n }\n for (const candidate of [obj.data, obj.config]) {\n if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) continue;\n const nested = asItemList(candidate);\n if (nested) return nested;\n }\n return null;\n}\n\nfunction isNormalizedModel(input: object): input is KpiWidgetModel {\n return Array.isArray((input as KpiWidgetModel).cards) && 'layout' in input;\n}\n\n/** Client `extractGroupId` — groupName is `{label}-group-kpi-ids-{id}`. */\nexport function extractGroupId(value?: string | null): string {\n return value?.split('-group-kpi-ids-')?.[0] ?? '';\n}\n\nfunction sortItems(items: RawKpiItem[]): RawKpiItem[] {\n return [...items].sort((a, b) => {\n if (isAdvancedKpiItem(a) && !isAdvancedKpiItem(b)) return -1;\n if (!isAdvancedKpiItem(a) && isAdvancedKpiItem(b)) return 1;\n return 0;\n });\n}\n\nfunction footerFrom(items: RawKpiItem[]): Pick<\n KpiWidgetModel,\n 'target' | 'showTimestamp' | 'updatedAt'\n> {\n const first = items[0];\n return {\n target: first?.target,\n showTimestamp: first?.showTimestamp,\n updatedAt: first?.updatedAt,\n };\n}\n\nfunction sectionTitle(\n items: RawKpiItem[],\n advanced: boolean,\n topName?: string,\n): string | undefined {\n if (advanced) return undefined;\n if (items.length === 1) return items[0]?.name;\n const grouped = extractGroupId(items[0]?.groupName);\n if (grouped) return grouped;\n return topName?.trim() || undefined;\n}\n\nfunction buildFromItems(items: RawKpiItem[], topName?: string): KpiWidgetModel {\n if (!items.length) return EMPTY;\n const sorted = sortItems(items);\n const advancedIndex = sorted.findIndex(isAdvancedKpiItem);\n const advanced = advancedIndex >= 0;\n const footer = footerFrom(sorted);\n\n if (advanced) {\n const mainItem = sorted[advancedIndex]!;\n const mainCards = extractCardsFromKpi(mainItem);\n const main = mainCards[0];\n const supporting = sorted\n .filter((_, i) => i !== advancedIndex)\n .flatMap((item) => extractCardsFromKpi(item));\n const viz =\n mainItem.visualisation && typeof mainItem.visualisation === 'object'\n ? (mainItem.visualisation as Record<string, unknown>)\n : null;\n return {\n layout: 'advanced',\n title: sectionTitle(sorted, true, topName),\n cards: main ? [main, ...supporting] : supporting,\n main,\n supporting,\n visualisation: viz,\n ...footer,\n };\n }\n\n const cards = sorted.flatMap((item) => extractCardsFromKpi(item));\n const hideNames = sorted.length === 1 && cards.length >= 1;\n const titledCards = hideNames\n ? cards.map((card) => ({ ...card, hideName: true }))\n : cards;\n const layout: KpiWidgetModel['layout'] =\n titledCards.length === 0 ? 'empty' : titledCards.length === 1 ? 'single' : 'grid';\n\n return {\n layout,\n title: sectionTitle(sorted, false, topName),\n cards: titledCards,\n supporting: [],\n ...footer,\n };\n}\n\n/** Normalize chat / FuseDash KPI payloads into display cards. */\nexport function normalizeKpiData(input: KpiWidgetData): KpiWidgetModel {\n if (!input) return EMPTY;\n\n if (Array.isArray(input)) {\n if (!input.length) return EMPTY;\n return buildFromItems(input);\n }\n\n if (typeof input === 'object') {\n if (isNormalizedModel(input)) return input;\n const topName = typeof (input as { name?: unknown }).name === 'string'\n ? (input as { name: string }).name\n : undefined;\n const items = asItemList(input);\n if (items) return buildFromItems(items, topName);\n if (isRawKpiItem(input)) {\n return buildFromItems([input], topName);\n }\n }\n\n return EMPTY;\n}\n"],"names":[],"mappings":";AAGA,MAAM,QAAwB,EAAE,QAAQ,SAAS,OAAO,CAAA,GAAI,YAAY,GAAC;AAEzE,SAAS,aAAa,OAAqC;AACzD,MAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AAC/E,QAAM,MAAM;AACZ,MAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAG,QAAO;AAChE,QAAM,SAAS,IAAI;AACnB,MAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,GAAG;AAClE,UAAM,QAAQ;AACd,QAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,QAAQ,MAAM,IAAI,EAAG,QAAO;AAAA,EACtE;AACA,SAAO,YAAY,OAAO,UAAU,OAAO,MAAM,QAAQ,IAAI,IAAI;AACnE;AAEA,SAAS,WAAW,OAAoC;AACtD,QAAM,MAAM;AAMZ,MAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,IAAI,MAAM,MAAM,CAAC,QAAQ,OAAO,OAAO,QAAQ,QAAQ,GAAG;AACxF,WAAO,IAAI;AAAA,EACb;AACA,MAAI,MAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,KAAK,MAAM,CAAC,QAAQ,OAAO,OAAO,QAAQ,QAAQ,GAAG;AACtF,WAAO,IAAI;AAAA,EACb;AACA,aAAW,aAAa,CAAC,IAAI,MAAM,IAAI,MAAM,GAAG;AAC9C,QAAI,CAAC,aAAa,OAAO,cAAc,YAAY,MAAM,QAAQ,SAAS,EAAG;AAC7E,UAAM,SAAS,WAAW,SAAS;AACnC,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAwC;AACjE,SAAO,MAAM,QAAS,MAAyB,KAAK,KAAK,YAAY;AACvE;AAGO,SAAS,eAAe,OAA+B;;AAC5D,WAAO,oCAAO,MAAM,uBAAb,mBAAkC,OAAM;AACjD;AAEA,SAAS,UAAU,OAAmC;AACpD,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM;AAC/B,QAAI,kBAAkB,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAG,QAAO;AAC1D,QAAI,CAAC,kBAAkB,CAAC,KAAK,kBAAkB,CAAC,EAAG,QAAO;AAC1D,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,WAAW,OAGlB;AACA,QAAM,QAAQ,MAAM,CAAC;AACrB,SAAO;AAAA,IACL,QAAQ,+BAAO;AAAA,IACf,eAAe,+BAAO;AAAA,IACtB,WAAW,+BAAO;AAAA,EAAA;AAEtB;AAEA,SAAS,aACP,OACA,UACA,SACoB;;AACpB,MAAI,SAAU,QAAO;AACrB,MAAI,MAAM,WAAW,EAAG,SAAO,WAAM,CAAC,MAAP,mBAAU;AACzC,QAAM,UAAU,gBAAe,WAAM,CAAC,MAAP,mBAAU,SAAS;AAClD,MAAI,QAAS,QAAO;AACpB,UAAO,mCAAS,WAAU;AAC5B;AAEA,SAAS,eAAe,OAAqB,SAAkC;AAC7E,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,QAAM,SAAS,UAAU,KAAK;AAC9B,QAAM,gBAAgB,OAAO,UAAU,iBAAiB;AACxD,QAAM,WAAW,iBAAiB;AAClC,QAAM,SAAS,WAAW,MAAM;AAEhC,MAAI,UAAU;AACZ,UAAM,WAAW,OAAO,aAAa;AACrC,UAAM,YAAY,oBAAoB,QAAQ;AAC9C,UAAM,OAAO,UAAU,CAAC;AACxB,UAAM,aAAa,OAChB,OAAO,CAAC,GAAG,MAAM,MAAM,aAAa,EACpC,QAAQ,CAAC,SAAS,oBAAoB,IAAI,CAAC;AAC9C,UAAM,MACJ,SAAS,iBAAiB,OAAO,SAAS,kBAAkB,WACvD,SAAS,gBACV;AACN,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO,aAAa,QAAQ,MAAM,OAAO;AAAA,MACzC,OAAO,OAAO,CAAC,MAAM,GAAG,UAAU,IAAI;AAAA,MACtC;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,GAAG;AAAA,IAAA;AAAA,EAEP;AAEA,QAAM,QAAQ,OAAO,QAAQ,CAAC,SAAS,oBAAoB,IAAI,CAAC;AAChE,QAAM,YAAY,OAAO,WAAW,KAAK,MAAM,UAAU;AACzD,QAAM,cAAc,YAChB,MAAM,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,UAAU,KAAA,EAAO,IACjD;AACJ,QAAM,SACJ,YAAY,WAAW,IAAI,UAAU,YAAY,WAAW,IAAI,WAAW;AAE7E,SAAO;AAAA,IACL;AAAA,IACA,OAAO,aAAa,QAAQ,OAAO,OAAO;AAAA,IAC1C,OAAO;AAAA,IACP,YAAY,CAAA;AAAA,IACZ,GAAG;AAAA,EAAA;AAEP;AAGO,SAAS,iBAAiB,OAAsC;AACrE,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,QAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,WAAO,eAAe,KAAK;AAAA,EAC7B;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,kBAAkB,KAAK,EAAG,QAAO;AACrC,UAAM,UAAU,OAAQ,MAA6B,SAAS,WACzD,MAA2B,OAC5B;AACJ,UAAM,QAAQ,WAAW,KAAK;AAC9B,QAAI,MAAO,QAAO,eAAe,OAAO,OAAO;AAC/C,QAAI,aAAa,KAAK,GAAG;AACvB,aAAO,eAAe,CAAC,KAAK,GAAG,OAAO;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;"}
|
|
@@ -31,4 +31,6 @@ export declare const MAP_STYLES: {
|
|
|
31
31
|
};
|
|
32
32
|
export declare const MAPBOX_CSS_HREF = "https://api.mapbox.com/mapbox-gl-js/v3.29.0/mapbox-gl.css";
|
|
33
33
|
export declare const COUNTRY_SYNONYMS: Record<string, string[]>;
|
|
34
|
+
/** Country-level labels only — do not reuse COUNTRY_SYNONYMS (admin-1 composites). */
|
|
35
|
+
export declare const COUNTRY_LABEL_ALIASES: Record<string, string[]>;
|
|
34
36
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3F,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,eAAe,EAAE,YAAY,EAOzC,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAkB,CAAC;AACpD,eAAO,MAAM,mBAAmB,QAAoB,CAAC;AAErD,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,MAAgD,CAAC;AAE3F,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,MAA8C,CAAC;AAEvF,2FAA2F;AAC3F,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAiDzD,CAAC;AAEF,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,mBAAmB,UAAkC,CAAC;AACnE,eAAO,MAAM,sBAAsB,UAAmC,CAAC;AACvE,eAAO,MAAM,aAAa,UAAoC,CAAC;AAC/D,eAAO,MAAM,mBAAmB,UAA+B,CAAC;AAChE,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,UAAU,MAAM,CAAC;AAE9B,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAKxD,CAAC;AAEF,eAAO,MAAM,UAAU;;;;CAIb,CAAC;AAEX,eAAO,MAAM,eAAe,8DAA8D,CAAC;AAE3F,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAsBrD,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/constants.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3F,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,eAAe,EAAE,YAAY,EAOzC,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAkB,CAAC;AACpD,eAAO,MAAM,mBAAmB,QAAoB,CAAC;AAErD,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,MAAgD,CAAC;AAE3F,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,MAA8C,CAAC;AAEvF,2FAA2F;AAC3F,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,CAiDzD,CAAC;AAEF,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,mBAAmB,UAAkC,CAAC;AACnE,eAAO,MAAM,sBAAsB,UAAmC,CAAC;AACvE,eAAO,MAAM,aAAa,UAAoC,CAAC;AAC/D,eAAO,MAAM,mBAAmB,UAA+B,CAAC;AAChE,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,UAAU,MAAM,CAAC;AAE9B,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAKxD,CAAC;AAEF,eAAO,MAAM,UAAU;;;;CAIb,CAAC;AAEX,eAAO,MAAM,eAAe,8DAA8D,CAAC;AAE3F,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAsBrD,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAI1D,CAAC"}
|
|
@@ -101,8 +101,14 @@ const COUNTRY_SYNONYMS = {
|
|
|
101
101
|
Burma: ["Myanmar"],
|
|
102
102
|
"United Kingdom": ["UK", "Great Britain"]
|
|
103
103
|
};
|
|
104
|
+
const COUNTRY_LABEL_ALIASES = {
|
|
105
|
+
"Czech Rep.": ["Czechia", "Czech Republic"],
|
|
106
|
+
"Czech Republic": ["Czechia", "Czech Rep."],
|
|
107
|
+
Czechia: ["Czech Republic", "Czech Rep."]
|
|
108
|
+
};
|
|
104
109
|
export {
|
|
105
110
|
BUBBLE_RADIUS_STEPS,
|
|
111
|
+
COUNTRY_LABEL_ALIASES,
|
|
106
112
|
COUNTRY_SYNONYMS,
|
|
107
113
|
DEFAULT_BUBBLES_RADIUS,
|
|
108
114
|
DEFAULT_SPIKE_SIZES,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../../../src/components/map-chart/lib/constants.ts"],"sourcesContent":["export type MapVisualisation = 'choropleth' | 'bubbles' | 'spike' | 'markers';\n\nexport type MapAdminType = 'city' | 'county' | 'state' | 'country' | 'province' | 'region';\n\nexport interface RegionKeys {\n name: string;\n id: string;\n code: string;\n county: string;\n state: string;\n country: string;\n}\n\nexport const MAP_ADMIN_TYPES: MapAdminType[] = [\n 'city',\n 'county',\n 'state',\n 'province',\n 'region',\n 'country',\n];\n\nexport const SANITIZE_KEY_PATTERN = /[^a-zA-Z0-9]/g;\nexport const SANITIZE_ID_PATTERN = /[^a-zA-Z0-9_-]/g;\n\nexport const sanitizeKey = (key: string): string => key.replace(SANITIZE_KEY_PATTERN, '_');\n\nexport const sanitizeId = (id: string): string => id.replace(SANITIZE_ID_PATTERN, '_');\n\n/** Vendored from client MapBox/constants.ts — keep in lockstep with mcp-ui geojsonKeys. */\nexport const GEOJSON_KEYS: Record<MapAdminType, RegionKeys> = {\n city: {\n name: 'NAME_2',\n code: 'GID_0',\n id: 'GID_2',\n county: 'NAME_2',\n state: 'NAME_1',\n country: 'COUNTRY',\n },\n region: {\n name: 'name',\n code: 'iso_3166_2',\n id: 'iso_3166_2',\n county: 'name',\n state: 'name',\n country: 'admin',\n },\n county: {\n name: 'NAME_2',\n code: 'GID_0',\n id: 'GID_2',\n county: 'NAME_2',\n state: 'NAME_1',\n country: 'COUNTRY',\n },\n state: {\n name: 'NAME_1',\n code: 'GID_0',\n id: 'GID_1',\n county: 'NAME_2',\n state: 'NAME_1',\n country: 'COUNTRY',\n },\n country: {\n name: 'name',\n code: 'name',\n id: 'iso_a3',\n county: 'NAME_2',\n state: 'NAME_1',\n country: 'COUNTRY',\n },\n province: {\n name: 'name',\n code: 'iso_3166_2',\n id: 'iso_3166_2',\n county: 'name',\n state: 'name',\n country: 'admin',\n },\n};\n\nexport const MAX_COLOR_RANGE = 7;\nexport const DEFAULT_SPIKE_SIZES = [8, 12, 16, 22, 28, 34, 42, 54];\nexport const DEFAULT_BUBBLES_RADIUS = [10, 15, 20, 25, 30, 35, 40, 45];\nexport const SPIKE_HEIGHTS = [15, 25, 35, 40, 55, 70, 85, 100];\nexport const BUBBLE_RADIUS_STEPS = [10, 15, 20, 25, 30, 35, 40];\nexport const FALLBACK_FILL = '#DADAE1';\nexport const UNMATCHED_FILL = 'rgba(72, 70, 91, 0.15)';\nexport const MAX_SPIKES = 200;\n\nexport const LAYER_ORDER: Record<MapVisualisation, number> = {\n choropleth: 0,\n bubbles: 1,\n spike: 2,\n markers: 3,\n};\n\nexport const MAP_STYLES = {\n light: 'mapbox://styles/andyk1987/cm1kvt8ib00ie01pi1lty0ey4',\n dark: 'mapbox://styles/flc-designers/cm7j7z28n00ov01ryahkd2jqj',\n terrain: 'mapbox://styles/andyk1987/clnefgdzy01ze01qne2766ihi',\n} as const;\n\nexport const MAPBOX_CSS_HREF = 'https://api.mapbox.com/mapbox-gl-js/v3.29.0/mapbox-gl.css';\n\nexport const COUNTRY_SYNONYMS: Record<string, string[]> = {\n 'United States of America': ['United States', 'USA', 'US'],\n 'United Republic of Tanzania': ['Tanzania'],\n 'Hong Kong S.A.R.': ['Hong Kong'],\n 'Ivory Coast': [\"Côte d'Ivoire\", \"Cote d'Ivoire\"],\n 'Cape Verde': ['Cabo Verde'],\n 'Republic of the Congo': ['Congo', 'Congo-Brazzaville'],\n 'Democratic Republic of the Congo': ['DR Congo', 'DRC', 'Congo (Kinshasa)'],\n 'West Bank': ['Palestine', 'State of Palestine'],\n 'Caribbean Netherlands': ['Netherlands'],\n 'The Bahamas': ['Bahamas'],\n 'Republic of Serbia': ['Serbia'],\n Macedonia: ['North Macedonia'],\n 'East Timor': ['Timor-Leste', 'Timor Leste'],\n 'Federated States of Micronesia': ['Micronesia'],\n 'Guinea Bissau': ['Guinea-Bissau'],\n Swaziland: ['Eswatini'],\n 'Czech Republic': ['Czechia'],\n 'South Korea': ['Korea, Rep.', 'Republic of Korea'],\n 'North Korea': ['Korea, North', 'DPRK'],\n Burma: ['Myanmar'],\n 'United Kingdom': ['UK', 'Great Britain'],\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../../src/components/map-chart/lib/constants.ts"],"sourcesContent":["export type MapVisualisation = 'choropleth' | 'bubbles' | 'spike' | 'markers';\n\nexport type MapAdminType = 'city' | 'county' | 'state' | 'country' | 'province' | 'region';\n\nexport interface RegionKeys {\n name: string;\n id: string;\n code: string;\n county: string;\n state: string;\n country: string;\n}\n\nexport const MAP_ADMIN_TYPES: MapAdminType[] = [\n 'city',\n 'county',\n 'state',\n 'province',\n 'region',\n 'country',\n];\n\nexport const SANITIZE_KEY_PATTERN = /[^a-zA-Z0-9]/g;\nexport const SANITIZE_ID_PATTERN = /[^a-zA-Z0-9_-]/g;\n\nexport const sanitizeKey = (key: string): string => key.replace(SANITIZE_KEY_PATTERN, '_');\n\nexport const sanitizeId = (id: string): string => id.replace(SANITIZE_ID_PATTERN, '_');\n\n/** Vendored from client MapBox/constants.ts — keep in lockstep with mcp-ui geojsonKeys. */\nexport const GEOJSON_KEYS: Record<MapAdminType, RegionKeys> = {\n city: {\n name: 'NAME_2',\n code: 'GID_0',\n id: 'GID_2',\n county: 'NAME_2',\n state: 'NAME_1',\n country: 'COUNTRY',\n },\n region: {\n name: 'name',\n code: 'iso_3166_2',\n id: 'iso_3166_2',\n county: 'name',\n state: 'name',\n country: 'admin',\n },\n county: {\n name: 'NAME_2',\n code: 'GID_0',\n id: 'GID_2',\n county: 'NAME_2',\n state: 'NAME_1',\n country: 'COUNTRY',\n },\n state: {\n name: 'NAME_1',\n code: 'GID_0',\n id: 'GID_1',\n county: 'NAME_2',\n state: 'NAME_1',\n country: 'COUNTRY',\n },\n country: {\n name: 'name',\n code: 'name',\n id: 'iso_a3',\n county: 'NAME_2',\n state: 'NAME_1',\n country: 'COUNTRY',\n },\n province: {\n name: 'name',\n code: 'iso_3166_2',\n id: 'iso_3166_2',\n county: 'name',\n state: 'name',\n country: 'admin',\n },\n};\n\nexport const MAX_COLOR_RANGE = 7;\nexport const DEFAULT_SPIKE_SIZES = [8, 12, 16, 22, 28, 34, 42, 54];\nexport const DEFAULT_BUBBLES_RADIUS = [10, 15, 20, 25, 30, 35, 40, 45];\nexport const SPIKE_HEIGHTS = [15, 25, 35, 40, 55, 70, 85, 100];\nexport const BUBBLE_RADIUS_STEPS = [10, 15, 20, 25, 30, 35, 40];\nexport const FALLBACK_FILL = '#DADAE1';\nexport const UNMATCHED_FILL = 'rgba(72, 70, 91, 0.15)';\nexport const MAX_SPIKES = 200;\n\nexport const LAYER_ORDER: Record<MapVisualisation, number> = {\n choropleth: 0,\n bubbles: 1,\n spike: 2,\n markers: 3,\n};\n\nexport const MAP_STYLES = {\n light: 'mapbox://styles/andyk1987/cm1kvt8ib00ie01pi1lty0ey4',\n dark: 'mapbox://styles/flc-designers/cm7j7z28n00ov01ryahkd2jqj',\n terrain: 'mapbox://styles/andyk1987/clnefgdzy01ze01qne2766ihi',\n} as const;\n\nexport const MAPBOX_CSS_HREF = 'https://api.mapbox.com/mapbox-gl-js/v3.29.0/mapbox-gl.css';\n\nexport const COUNTRY_SYNONYMS: Record<string, string[]> = {\n 'United States of America': ['United States', 'USA', 'US'],\n 'United Republic of Tanzania': ['Tanzania'],\n 'Hong Kong S.A.R.': ['Hong Kong'],\n 'Ivory Coast': [\"Côte d'Ivoire\", \"Cote d'Ivoire\"],\n 'Cape Verde': ['Cabo Verde'],\n 'Republic of the Congo': ['Congo', 'Congo-Brazzaville'],\n 'Democratic Republic of the Congo': ['DR Congo', 'DRC', 'Congo (Kinshasa)'],\n 'West Bank': ['Palestine', 'State of Palestine'],\n 'Caribbean Netherlands': ['Netherlands'],\n 'The Bahamas': ['Bahamas'],\n 'Republic of Serbia': ['Serbia'],\n Macedonia: ['North Macedonia'],\n 'East Timor': ['Timor-Leste', 'Timor Leste'],\n 'Federated States of Micronesia': ['Micronesia'],\n 'Guinea Bissau': ['Guinea-Bissau'],\n Swaziland: ['Eswatini'],\n 'Czech Republic': ['Czechia'],\n 'South Korea': ['Korea, Rep.', 'Republic of Korea'],\n 'North Korea': ['Korea, North', 'DPRK'],\n Burma: ['Myanmar'],\n 'United Kingdom': ['UK', 'Great Britain'],\n};\n\n/** Country-level labels only — do not reuse COUNTRY_SYNONYMS (admin-1 composites). */\nexport const COUNTRY_LABEL_ALIASES: Record<string, string[]> = {\n 'Czech Rep.': ['Czechia', 'Czech Republic'],\n 'Czech Republic': ['Czechia', 'Czech Rep.'],\n Czechia: ['Czech Republic', 'Czech Rep.'],\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geo-index.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/geo-index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAWhE,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAO/E;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA+B7E;AAED,wBAAgB,gCAAgC,CAC9C,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAC7D,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,GAAG,SAAS,CAapB;AAwDD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"geo-index.d.ts","sourceRoot":"","sources":["../../../../src/components/map-chart/lib/geo-index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAWhE,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAO/E;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA+B7E;AAED,wBAAgB,gCAAgC,CAC9C,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAC7D,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,GAAG,SAAS,CAapB;AAwDD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CA4G9F;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAoBxG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { COUNTRY_SYNONYMS, GEOJSON_KEYS, MAP_ADMIN_TYPES } from "./constants.js";
|
|
1
|
+
import { COUNTRY_SYNONYMS, GEOJSON_KEYS, COUNTRY_LABEL_ALIASES, MAP_ADMIN_TYPES } from "./constants.js";
|
|
2
2
|
const CITY_NAME_VARIATIONS = {
|
|
3
3
|
kyiv: "kiev",
|
|
4
4
|
peking: "beijing",
|
|
@@ -165,6 +165,10 @@ function createFeaturesIndex(features, mapType) {
|
|
|
165
165
|
props.geounit,
|
|
166
166
|
...String(props.aliases ?? "").split("|")
|
|
167
167
|
];
|
|
168
|
+
for (const seed of [dataValue, props.name, ...aliases]) {
|
|
169
|
+
if (typeof seed !== "string" || !seed) continue;
|
|
170
|
+
aliases.push(...COUNTRY_LABEL_ALIASES[seed] ?? []);
|
|
171
|
+
}
|
|
168
172
|
for (const alias of aliases) {
|
|
169
173
|
if (typeof alias === "string" && alias && alias !== dataValue) {
|
|
170
174
|
indexAlias(byDataValue, byNormalizedValue, alias, regionId, mapType);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geo-index.js","sources":["../../../../src/components/map-chart/lib/geo-index.ts"],"sourcesContent":["import { COUNTRY_SYNONYMS, GEOJSON_KEYS, MAP_ADMIN_TYPES, type MapAdminType } from './constants.js';\nimport type { FeaturesIndex, GeoJsonFeature } from './types.js';\n\nconst CITY_NAME_VARIATIONS: Record<string, string> = {\n kyiv: 'kiev',\n peking: 'beijing',\n bombay: 'mumbai',\n calcutta: 'kolkata',\n madras: 'chennai',\n saigon: 'hochiminh',\n};\n\nexport function inferMapTypeFromKeyNames(dataKeys: string[]): string | undefined {\n for (const key of dataKeys ?? []) {\n const name = String(key).toLowerCase();\n const found = MAP_ADMIN_TYPES.find((type) => name.includes(type));\n if (found) return found;\n }\n return undefined;\n}\n\nexport function normalizeDataValue(dataValue: string, mapType: string): string {\n if (!dataValue) return '';\n\n let normalized = dataValue\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '');\n\n normalized = normalized.replace(/\\bst\\.?\\s+/g, 'saint ');\n if (mapType !== 'city') {\n normalized = normalized.replace(/['’´`.-]/g, ' ');\n }\n\n if (mapType === 'city') {\n normalized = normalized\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[''`´]/g, '')\n .replace(/[-_]/g, '');\n for (const [from, to] of Object.entries(CITY_NAME_VARIATIONS)) {\n normalized = normalized.replace(new RegExp(`\\\\b${from}\\\\b`, 'g'), to);\n }\n }\n\n if (mapType === 'country') return normalized;\n\n const parts = normalized.replace(/ /g, '').split(',');\n if (mapType === 'county') {\n return parts.map((item) => item.replace('county', '')).join(',');\n }\n return parts.join(',');\n}\n\nexport function getRegionIdFromFeatureProperties(\n featureProperties: Record<string, unknown> | null | undefined,\n mapType?: string,\n): string | undefined {\n if (!featureProperties || !mapType) return undefined;\n const keys = GEOJSON_KEYS[mapType as MapAdminType];\n if (!keys) return undefined;\n\n if (mapType === 'country') {\n const iso = featureProperties[keys.id];\n if (iso === '-99') return String(featureProperties.adm0_a3 ?? iso);\n return iso != null ? String(iso) : undefined;\n }\n\n const id = featureProperties[keys.id];\n return id != null && String(id) !== '' ? String(id) : undefined;\n}\n\nfunction getDataValueFromFeature(feature: GeoJsonFeature, mapType: string): string | undefined {\n const props = feature.properties;\n if (!props) return undefined;\n const keys = GEOJSON_KEYS[mapType as MapAdminType];\n if (!keys) return undefined;\n\n const getProp = (field: keyof typeof keys): string | undefined => {\n const value = props[keys[field]];\n return typeof value === 'string' && value ? value : undefined;\n };\n\n const buildComposite = (\n parts: Array<keyof typeof keys>,\n fallbackKey: keyof typeof keys,\n ): string | undefined => {\n const values = parts.map(getProp);\n return values.every((v) => v) ? values.join(',') : getProp(fallbackKey);\n };\n\n switch (mapType) {\n case 'city': {\n const country = getProp('country');\n const state = getProp('state');\n const name = getProp('name');\n if (country && state && name) return `${country},${state},${name}`;\n if (country && name) return `${country},${name}`;\n return name;\n }\n case 'county':\n return buildComposite(['country', 'state', 'county'], 'county');\n case 'state':\n case 'province':\n return buildComposite(['country', 'state'], 'state');\n case 'country':\n case 'region':\n return getProp('name');\n default:\n return undefined;\n }\n}\n\nfunction indexAlias(\n byDataValue: Map<string, string>,\n byNormalizedValue: Map<string, string>,\n alias: string,\n regionId: string,\n mapType: string,\n): void {\n const lower = alias.toLowerCase();\n if (!byDataValue.has(lower)) byDataValue.set(lower, regionId);\n const normalized = normalizeDataValue(alias, mapType);\n if (!byNormalizedValue.has(normalized)) byNormalizedValue.set(normalized, regionId);\n}\n\nexport function createFeaturesIndex(features: GeoJsonFeature[], mapType: string): FeaturesIndex {\n const byId = new Map<string, GeoJsonFeature>();\n const byDataValue = new Map<string, string>();\n const byNormalizedValue = new Map<string, string>();\n if (!features.length || !mapType) return { byId, byDataValue, byNormalizedValue };\n\n const ambiguousTwoPartKeys = new Set<string>();\n\n for (const feature of features) {\n const regionId = getRegionIdFromFeatureProperties(feature.properties, mapType);\n if (!regionId) continue;\n byId.set(regionId, feature);\n\n const dataValue = getDataValueFromFeature(feature, mapType);\n if (!dataValue) continue;\n\n const normalized = normalizeDataValue(dataValue, mapType);\n byDataValue.set(dataValue.toLowerCase(), regionId);\n byNormalizedValue.set(normalized, regionId);\n\n const props = feature.properties;\n if (!props) continue;\n\n if (mapType === 'city') {\n const country = props.COUNTRY;\n const state = props.NAME_1;\n const cityName = props.NAME_2;\n if (typeof country === 'string' && typeof cityName === 'string') {\n const twoPart = normalizeDataValue(`${country},${cityName}`, mapType);\n const existing = byNormalizedValue.get(twoPart);\n if (existing && existing !== regionId) ambiguousTwoPartKeys.add(twoPart);\n else byNormalizedValue.set(twoPart, regionId);\n }\n if (\n typeof country === 'string' &&\n typeof state === 'string' &&\n typeof cityName === 'string' &&\n state !== cityName\n ) {\n const stateFormat = normalizeDataValue(`${country},${state}`, mapType);\n if (!byNormalizedValue.has(stateFormat)) byNormalizedValue.set(stateFormat, regionId);\n }\n }\n\n if (mapType === 'county') {\n const country = props.COUNTRY;\n const countyName = props.NAME_2;\n if (typeof country === 'string' && typeof countyName === 'string') {\n for (const countryForm of [country, ...(COUNTRY_SYNONYMS[country] ?? [])]) {\n const twoPart = normalizeDataValue(`${countryForm},${countyName}`, mapType);\n const existing = byNormalizedValue.get(twoPart);\n if (existing && existing !== regionId) ambiguousTwoPartKeys.add(twoPart);\n else byNormalizedValue.set(twoPart, regionId);\n }\n }\n }\n\n if (mapType === 'region' || mapType === 'province') {\n const country = props.admin;\n const regionName = props.name;\n const unitNames = [regionName, props.name_en, ...String(props.aliases ?? '').split('|')].filter(\n (n): n is string => typeof n === 'string' && n.length > 0,\n );\n const countryForms =\n typeof country === 'string' ? [country, ...(COUNTRY_SYNONYMS[country] ?? [])] : [];\n for (const countryForm of countryForms) {\n for (const unitName of unitNames) {\n const composite = normalizeDataValue(`${countryForm},${unitName}`, mapType);\n if (!byNormalizedValue.has(composite)) byNormalizedValue.set(composite, regionId);\n }\n }\n for (const alias of [props.name_en, ...String(props.aliases ?? '').split('|')]) {\n if (typeof alias !== 'string' || !alias || alias === regionName) continue;\n indexAlias(byDataValue, byNormalizedValue, alias, regionId, mapType);\n }\n }\n\n if (mapType === 'state' || mapType === 'province') {\n const keys = GEOJSON_KEYS[mapType];\n const bareName = props[keys.state] ?? props[keys.name];\n if (typeof bareName === 'string' && bareName) {\n indexAlias(byDataValue, byNormalizedValue, bareName, regionId, mapType);\n }\n }\n\n if (mapType === 'country') {\n const aliases = [\n props.name_long,\n props.formal_en,\n props.brk_name,\n props.admin,\n props.geounit,\n ...String(props.aliases ?? '').split('|'),\n ];\n for (const alias of aliases) {\n if (typeof alias === 'string' && alias && alias !== dataValue) {\n indexAlias(byDataValue, byNormalizedValue, alias, regionId, mapType);\n }\n }\n }\n }\n\n for (const key of ambiguousTwoPartKeys) byNormalizedValue.delete(key);\n return { byId, byDataValue, byNormalizedValue };\n}\n\nexport function getRegionId(dataValue: string, mapType: string, index: FeaturesIndex): string | undefined {\n if (!dataValue || !mapType) return undefined;\n const direct = index.byDataValue.get(dataValue.toLowerCase());\n if (direct) return direct;\n const normalized = index.byNormalizedValue.get(normalizeDataValue(dataValue, mapType));\n if (normalized) return normalized;\n\n if (\n (mapType === 'region' || mapType === 'province' || mapType === 'county') &&\n dataValue.includes(',')\n ) {\n const lastPart = dataValue.split(',').at(-1)?.trim();\n if (lastPart) {\n return (\n index.byDataValue.get(lastPart.toLowerCase()) ??\n index.byNormalizedValue.get(normalizeDataValue(lastPart, mapType))\n );\n }\n }\n return undefined;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"geo-index.js","sources":["../../../../src/components/map-chart/lib/geo-index.ts"],"sourcesContent":["import { COUNTRY_LABEL_ALIASES, COUNTRY_SYNONYMS, GEOJSON_KEYS, MAP_ADMIN_TYPES, type MapAdminType } from './constants.js';\nimport type { FeaturesIndex, GeoJsonFeature } from './types.js';\n\nconst CITY_NAME_VARIATIONS: Record<string, string> = {\n kyiv: 'kiev',\n peking: 'beijing',\n bombay: 'mumbai',\n calcutta: 'kolkata',\n madras: 'chennai',\n saigon: 'hochiminh',\n};\n\nexport function inferMapTypeFromKeyNames(dataKeys: string[]): string | undefined {\n for (const key of dataKeys ?? []) {\n const name = String(key).toLowerCase();\n const found = MAP_ADMIN_TYPES.find((type) => name.includes(type));\n if (found) return found;\n }\n return undefined;\n}\n\nexport function normalizeDataValue(dataValue: string, mapType: string): string {\n if (!dataValue) return '';\n\n let normalized = dataValue\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '');\n\n normalized = normalized.replace(/\\bst\\.?\\s+/g, 'saint ');\n if (mapType !== 'city') {\n normalized = normalized.replace(/['’´`.-]/g, ' ');\n }\n\n if (mapType === 'city') {\n normalized = normalized\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[''`´]/g, '')\n .replace(/[-_]/g, '');\n for (const [from, to] of Object.entries(CITY_NAME_VARIATIONS)) {\n normalized = normalized.replace(new RegExp(`\\\\b${from}\\\\b`, 'g'), to);\n }\n }\n\n if (mapType === 'country') return normalized;\n\n const parts = normalized.replace(/ /g, '').split(',');\n if (mapType === 'county') {\n return parts.map((item) => item.replace('county', '')).join(',');\n }\n return parts.join(',');\n}\n\nexport function getRegionIdFromFeatureProperties(\n featureProperties: Record<string, unknown> | null | undefined,\n mapType?: string,\n): string | undefined {\n if (!featureProperties || !mapType) return undefined;\n const keys = GEOJSON_KEYS[mapType as MapAdminType];\n if (!keys) return undefined;\n\n if (mapType === 'country') {\n const iso = featureProperties[keys.id];\n if (iso === '-99') return String(featureProperties.adm0_a3 ?? iso);\n return iso != null ? String(iso) : undefined;\n }\n\n const id = featureProperties[keys.id];\n return id != null && String(id) !== '' ? String(id) : undefined;\n}\n\nfunction getDataValueFromFeature(feature: GeoJsonFeature, mapType: string): string | undefined {\n const props = feature.properties;\n if (!props) return undefined;\n const keys = GEOJSON_KEYS[mapType as MapAdminType];\n if (!keys) return undefined;\n\n const getProp = (field: keyof typeof keys): string | undefined => {\n const value = props[keys[field]];\n return typeof value === 'string' && value ? value : undefined;\n };\n\n const buildComposite = (\n parts: Array<keyof typeof keys>,\n fallbackKey: keyof typeof keys,\n ): string | undefined => {\n const values = parts.map(getProp);\n return values.every((v) => v) ? values.join(',') : getProp(fallbackKey);\n };\n\n switch (mapType) {\n case 'city': {\n const country = getProp('country');\n const state = getProp('state');\n const name = getProp('name');\n if (country && state && name) return `${country},${state},${name}`;\n if (country && name) return `${country},${name}`;\n return name;\n }\n case 'county':\n return buildComposite(['country', 'state', 'county'], 'county');\n case 'state':\n case 'province':\n return buildComposite(['country', 'state'], 'state');\n case 'country':\n case 'region':\n return getProp('name');\n default:\n return undefined;\n }\n}\n\nfunction indexAlias(\n byDataValue: Map<string, string>,\n byNormalizedValue: Map<string, string>,\n alias: string,\n regionId: string,\n mapType: string,\n): void {\n const lower = alias.toLowerCase();\n if (!byDataValue.has(lower)) byDataValue.set(lower, regionId);\n const normalized = normalizeDataValue(alias, mapType);\n if (!byNormalizedValue.has(normalized)) byNormalizedValue.set(normalized, regionId);\n}\n\nexport function createFeaturesIndex(features: GeoJsonFeature[], mapType: string): FeaturesIndex {\n const byId = new Map<string, GeoJsonFeature>();\n const byDataValue = new Map<string, string>();\n const byNormalizedValue = new Map<string, string>();\n if (!features.length || !mapType) return { byId, byDataValue, byNormalizedValue };\n\n const ambiguousTwoPartKeys = new Set<string>();\n\n for (const feature of features) {\n const regionId = getRegionIdFromFeatureProperties(feature.properties, mapType);\n if (!regionId) continue;\n byId.set(regionId, feature);\n\n const dataValue = getDataValueFromFeature(feature, mapType);\n if (!dataValue) continue;\n\n const normalized = normalizeDataValue(dataValue, mapType);\n byDataValue.set(dataValue.toLowerCase(), regionId);\n byNormalizedValue.set(normalized, regionId);\n\n const props = feature.properties;\n if (!props) continue;\n\n if (mapType === 'city') {\n const country = props.COUNTRY;\n const state = props.NAME_1;\n const cityName = props.NAME_2;\n if (typeof country === 'string' && typeof cityName === 'string') {\n const twoPart = normalizeDataValue(`${country},${cityName}`, mapType);\n const existing = byNormalizedValue.get(twoPart);\n if (existing && existing !== regionId) ambiguousTwoPartKeys.add(twoPart);\n else byNormalizedValue.set(twoPart, regionId);\n }\n if (\n typeof country === 'string' &&\n typeof state === 'string' &&\n typeof cityName === 'string' &&\n state !== cityName\n ) {\n const stateFormat = normalizeDataValue(`${country},${state}`, mapType);\n if (!byNormalizedValue.has(stateFormat)) byNormalizedValue.set(stateFormat, regionId);\n }\n }\n\n if (mapType === 'county') {\n const country = props.COUNTRY;\n const countyName = props.NAME_2;\n if (typeof country === 'string' && typeof countyName === 'string') {\n for (const countryForm of [country, ...(COUNTRY_SYNONYMS[country] ?? [])]) {\n const twoPart = normalizeDataValue(`${countryForm},${countyName}`, mapType);\n const existing = byNormalizedValue.get(twoPart);\n if (existing && existing !== regionId) ambiguousTwoPartKeys.add(twoPart);\n else byNormalizedValue.set(twoPart, regionId);\n }\n }\n }\n\n if (mapType === 'region' || mapType === 'province') {\n const country = props.admin;\n const regionName = props.name;\n const unitNames = [regionName, props.name_en, ...String(props.aliases ?? '').split('|')].filter(\n (n): n is string => typeof n === 'string' && n.length > 0,\n );\n const countryForms =\n typeof country === 'string' ? [country, ...(COUNTRY_SYNONYMS[country] ?? [])] : [];\n for (const countryForm of countryForms) {\n for (const unitName of unitNames) {\n const composite = normalizeDataValue(`${countryForm},${unitName}`, mapType);\n if (!byNormalizedValue.has(composite)) byNormalizedValue.set(composite, regionId);\n }\n }\n for (const alias of [props.name_en, ...String(props.aliases ?? '').split('|')]) {\n if (typeof alias !== 'string' || !alias || alias === regionName) continue;\n indexAlias(byDataValue, byNormalizedValue, alias, regionId, mapType);\n }\n }\n\n if (mapType === 'state' || mapType === 'province') {\n const keys = GEOJSON_KEYS[mapType];\n const bareName = props[keys.state] ?? props[keys.name];\n if (typeof bareName === 'string' && bareName) {\n indexAlias(byDataValue, byNormalizedValue, bareName, regionId, mapType);\n }\n }\n\n if (mapType === 'country') {\n const aliases = [\n props.name_long,\n props.formal_en,\n props.brk_name,\n props.admin,\n props.geounit,\n ...String(props.aliases ?? '').split('|'),\n ];\n for (const seed of [dataValue, props.name, ...aliases]) {\n if (typeof seed !== 'string' || !seed) continue;\n aliases.push(...(COUNTRY_LABEL_ALIASES[seed] ?? []));\n }\n for (const alias of aliases) {\n if (typeof alias === 'string' && alias && alias !== dataValue) {\n indexAlias(byDataValue, byNormalizedValue, alias, regionId, mapType);\n }\n }\n }\n }\n\n for (const key of ambiguousTwoPartKeys) byNormalizedValue.delete(key);\n return { byId, byDataValue, byNormalizedValue };\n}\n\nexport function getRegionId(dataValue: string, mapType: string, index: FeaturesIndex): string | undefined {\n if (!dataValue || !mapType) return undefined;\n const direct = index.byDataValue.get(dataValue.toLowerCase());\n if (direct) return direct;\n const normalized = index.byNormalizedValue.get(normalizeDataValue(dataValue, mapType));\n if (normalized) return normalized;\n\n if (\n (mapType === 'region' || mapType === 'province' || mapType === 'county') &&\n dataValue.includes(',')\n ) {\n const lastPart = dataValue.split(',').at(-1)?.trim();\n if (lastPart) {\n return (\n index.byDataValue.get(lastPart.toLowerCase()) ??\n index.byNormalizedValue.get(normalizeDataValue(lastPart, mapType))\n );\n }\n }\n return undefined;\n}\n"],"names":[],"mappings":"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"}
|