@bufinance/gtm-graph 0.1.0

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.
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Graph path / bridge engine (plan 099; re-homed here as the published SSOT
3
+ * in plan 100 — `packages/intelligence/src/knowledge/graph-paths.ts` is now a
4
+ * re-export shim of this module).
5
+ *
6
+ * PURE module: no I/O, no clocks, no randomness — every time- or
7
+ * order-sensitive function takes explicit `now` / `seed` / `pairs` inputs so
8
+ * results are deterministic and testable, and so the UI can run the same
9
+ * code client-side over a fetched graph payload.
10
+ *
11
+ * Operates on a camelCase graph shape structurally compatible with the
12
+ * `get_knowledge_graph` RPC payload (`KnowledgeGraphData` in the BUFI desk
13
+ * repo). NOTE: that RPC's relationship objects omit `lastSeenAt`; the weight
14
+ * formula treats a missing `lastSeenAt` as "fresh" (factor 1).
15
+ *
16
+ * Weight formula (documented constants below):
17
+ * w = strength * ln(1 + evidenceCount) * recencyFactor(lastSeenAt, now)
18
+ * recencyFactor = 0.5 ^ (daysStale / 90) — halves per 90 stale days
19
+ *
20
+ * Scale ceiling: everything here is in-memory over the fetched graph —
21
+ * fine for the BUFI-internal GTM graph (thousands of edges). Past ~50k
22
+ * edges, graduate to pgRouting / an RPC (see the 2026-07-16 gtm-graph spec).
23
+ */
24
+ interface GraphEntityLike {
25
+ id: string;
26
+ }
27
+ interface GraphEdgeLike {
28
+ id: string;
29
+ sourceEntityId: string;
30
+ targetEntityId: string;
31
+ relationshipType: string;
32
+ strength?: number | null;
33
+ evidenceCount?: number | null;
34
+ lastSeenAt?: string | null;
35
+ }
36
+ interface GraphDataLike {
37
+ entities: GraphEntityLike[];
38
+ relationships: GraphEdgeLike[];
39
+ }
40
+ interface AdjacentEdge {
41
+ edgeId: string;
42
+ otherId: string;
43
+ relationshipType: string;
44
+ weight: number;
45
+ }
46
+ /** node id → undirected incident edges (both directions materialized). */
47
+ type Adjacency = Map<string, AdjacentEdge[]>;
48
+ interface GraphPath {
49
+ /** Node ids from source to target (inclusive). */
50
+ nodeIds: string[];
51
+ /** Edge ids traversed, in order (`nodeIds.length - 1` entries). */
52
+ edgeIds: string[];
53
+ /** Hop count (= edgeIds.length). */
54
+ hops: number;
55
+ /** Sum of Dijkstra costs (1/w) — lower = stronger; 0 for the trivial path. */
56
+ cost: number;
57
+ }
58
+ /** Staleness half-life: an edge unseen for this many days weighs half. */
59
+ declare const RECENCY_HALF_LIFE_DAYS = 90;
60
+ /** Default strength when the payload omits it (DB default is 1.0). */
61
+ declare const DEFAULT_STRENGTH = 1;
62
+ /** Default evidence count when the payload omits it (DB default is 1). */
63
+ declare const DEFAULT_EVIDENCE_COUNT = 1;
64
+ /** Floor so degenerate edges never divide by zero in 1/w costs. */
65
+ declare const MIN_EDGE_WEIGHT = 0.000001;
66
+ /** 0.5^(daysStale/90); missing/unparseable lastSeenAt → 1 (fresh). */
67
+ declare function recencyFactor(lastSeenAt: string | null | undefined, now: number): number;
68
+ /** w = strength * ln(1 + evidenceCount) * recencyFactor — floored at MIN_EDGE_WEIGHT. */
69
+ declare function edgeWeight(edge: GraphEdgeLike, now: number): number;
70
+ /**
71
+ * Undirected adjacency view with per-edge weights.
72
+ * `now` (epoch ms) drives the recency factor — pass a fixed value in tests.
73
+ */
74
+ declare function buildAdjacency(data: GraphDataLike, options: {
75
+ now: number;
76
+ }): Adjacency;
77
+ interface FewestHopsOptions {
78
+ now?: number;
79
+ /** Give up beyond this many hops (default: unbounded). */
80
+ maxHops?: number;
81
+ /** Reuse a prebuilt adjacency (must match `data`). */
82
+ adjacency?: Adjacency;
83
+ }
84
+ /** BFS shortest path by hop count. Null when unreachable (or beyond maxHops). */
85
+ declare function fewestHops(data: GraphDataLike, fromId: string, toId: string, options?: FewestHopsOptions): GraphPath | null;
86
+ interface StrongestPathOptions {
87
+ /** Epoch ms for the recency factor. REQUIRED for determinism. */
88
+ now: number;
89
+ adjacency?: Adjacency;
90
+ }
91
+ /**
92
+ * Dijkstra minimizing sum(1/w): prefers few, strong, recent edges.
93
+ * Can legitimately return MORE hops than `fewestHops` when a longer chain of
94
+ * strong edges beats a weak direct edge. Null when unreachable.
95
+ */
96
+ declare function strongestPath(data: GraphDataLike, fromId: string, toId: string, options: StrongestPathOptions): GraphPath | null;
97
+ interface BridgeScoreOptions {
98
+ now?: number;
99
+ /** Max sampled node pairs (default 200). */
100
+ sampleSize?: number;
101
+ /** PRNG seed — same seed + same graph → identical scores. */
102
+ seed?: number;
103
+ /** Explicit pair list overrides sampling entirely (fully deterministic). */
104
+ pairs?: Array<[string, string]>;
105
+ }
106
+ declare const DEFAULT_BRIDGE_SAMPLE_SIZE = 200;
107
+ declare const DEFAULT_BRIDGE_SEED = 99;
108
+ /**
109
+ * Approximate betweenness: run `fewestHops` over sampled node pairs and count
110
+ * how often each node sits STRICTLY INSIDE the path. Normalized to [0, 1]
111
+ * by the max count. Deterministic given (`seed` | `pairs`) + the graph.
112
+ */
113
+ declare function bridgeScores(data: GraphDataLike, options?: BridgeScoreOptions): Map<string, number>;
114
+ /**
115
+ * The sub-graph within `hops` of `centerId` (entities + every edge whose two
116
+ * endpoints are both inside). Empty graph when the center is unknown.
117
+ */
118
+ declare function neighborhood(data: GraphDataLike, centerId: string, hops: number): GraphDataLike;
119
+
120
+ /**
121
+ * GTM decorations — pure classification helpers on top of the path engine
122
+ * (plan 100). Implements the POI + bridge definitions from the 2026-07-16
123
+ * gtm-graph spec so every consumer (desk admin route, open-agents endpoint,
124
+ * Shiva MCP routes) classifies nodes identically.
125
+ *
126
+ * - POI (person of interest): persons with `champion_of` /
127
+ * `decision_maker_for` edges into OPEN deals, OR a decision-maker title
128
+ * match on their metadata.
129
+ * - Bridge: top-N nodes by sampled betweenness (`bridgeScores`) — the
130
+ * people/orgs the most shortest paths flow through.
131
+ */
132
+ interface GtmEntityLike {
133
+ id: string;
134
+ entityType: string;
135
+ entityName?: string;
136
+ metadata?: Record<string, unknown> | null;
137
+ }
138
+ interface GtmEdgeLike {
139
+ id: string;
140
+ sourceEntityId: string;
141
+ targetEntityId: string;
142
+ relationshipType: string;
143
+ strength?: number | null;
144
+ evidenceCount?: number | null;
145
+ lastSeenAt?: string | null;
146
+ metadata?: Record<string, unknown> | null;
147
+ }
148
+ interface GtmGraphLike {
149
+ entities: GtmEntityLike[];
150
+ relationships: GtmEdgeLike[];
151
+ }
152
+ type GtmNodeClass = 'poi' | 'bridge' | 'other';
153
+ /** Edge types that mark a person as tied to a deal's buying decision. */
154
+ declare const POI_EDGE_TYPES: readonly ["champion_of", "decision_maker_for"];
155
+ /**
156
+ * Canonical CLOSED pipeline stages (lowercased): deals in these stages no
157
+ * longer make their champions POIs. Mirrors `@bu/types/sales-pipeline`
158
+ * (`Activo` = won, `Nurture/Perdido` = lost) — duplicated here because this
159
+ * package is published standalone and cannot import `@bu/*`.
160
+ */
161
+ declare const DEFAULT_CLOSED_STAGES: readonly ["activo", "nurture/perdido", "won", "lost"];
162
+ /**
163
+ * Decision-maker title fragments (lowercased substring match) for the
164
+ * title-based POI rule. Derived from the current LATAM-agencies ICP
165
+ * (tasks/notes/2026-07-15-icp-enriched-r1.md in the desk repo). Hosts can
166
+ * override via `PoiOptions.titlePatterns`.
167
+ */
168
+ declare const DEFAULT_POI_TITLE_PATTERNS: readonly ["founder", "co-founder", "cofounder", "ceo", "coo", "cfo", "owner", "partner", "managing director", "director general", "general manager", "head of finance", "head of operations", "finance manager", "operations manager"];
169
+ interface PoiOptions {
170
+ /** Lowercased stage names counting as CLOSED (default: DEFAULT_CLOSED_STAGES). */
171
+ closedStages?: readonly string[];
172
+ /** Lowercased title fragments that qualify a person as POI (default: DEFAULT_POI_TITLE_PATTERNS). */
173
+ titlePatterns?: readonly string[];
174
+ }
175
+ /** True when the deal entity's `metadata.stage` is NOT in the closed set (unknown stage → open). */
176
+ declare function isOpenDeal(deal: GtmEntityLike, closedStages?: readonly string[]): boolean;
177
+ /**
178
+ * POI ids per the spec: persons with champion_of/decision_maker_for edges
179
+ * into OPEN deals, OR a decision-maker title match.
180
+ */
181
+ declare function computePoiIds(data: GtmGraphLike, options?: PoiOptions): Set<string>;
182
+ interface BridgeOptions {
183
+ /** How many top-scored nodes count as bridges (default 5). */
184
+ topN?: number;
185
+ /** Epoch ms for recency weighting (default 0 = ignore recency). */
186
+ now?: number;
187
+ /** Deterministic sampling seed forwarded to bridgeScores. */
188
+ seed?: number;
189
+ /** Explicit pair list forwarded to bridgeScores (fully deterministic). */
190
+ pairs?: Array<[string, string]>;
191
+ }
192
+ /**
193
+ * Top-N bridge node ids by sampled betweenness. Nodes with score 0 are never
194
+ * bridges, so small/star graphs can return fewer than `topN`.
195
+ */
196
+ declare function computeBridgeIds(data: GtmGraphLike, options?: BridgeOptions): Set<string>;
197
+ /** Node class from precomputed POI/bridge sets — POI wins over bridge. */
198
+ declare function classifyNode(id: string, poiIds: ReadonlySet<string>, bridgeIds: ReadonlySet<string>): GtmNodeClass;
199
+ /**
200
+ * Cap a graph at `maxNodes` keeping the highest-degree nodes (POIs/bridges
201
+ * always survive), plus every edge whose two endpoints survive.
202
+ */
203
+ declare function capGraph(data: GtmGraphLike, maxNodes: number, pinned?: ReadonlySet<string>): GtmGraphLike;
204
+
205
+ export { type Adjacency, type AdjacentEdge, type BridgeOptions, type BridgeScoreOptions, DEFAULT_BRIDGE_SAMPLE_SIZE, DEFAULT_BRIDGE_SEED, DEFAULT_CLOSED_STAGES, DEFAULT_EVIDENCE_COUNT, DEFAULT_POI_TITLE_PATTERNS, DEFAULT_STRENGTH, type FewestHopsOptions, type GraphDataLike, type GraphEdgeLike, type GraphEntityLike, type GraphPath, type GtmEdgeLike, type GtmEntityLike, type GtmGraphLike, type GtmNodeClass, MIN_EDGE_WEIGHT, POI_EDGE_TYPES, type PoiOptions, RECENCY_HALF_LIFE_DAYS, type StrongestPathOptions, bridgeScores, buildAdjacency, capGraph, classifyNode, computeBridgeIds, computePoiIds, edgeWeight, fewestHops, isOpenDeal, neighborhood, recencyFactor, strongestPath };
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Graph path / bridge engine (plan 099; re-homed here as the published SSOT
3
+ * in plan 100 — `packages/intelligence/src/knowledge/graph-paths.ts` is now a
4
+ * re-export shim of this module).
5
+ *
6
+ * PURE module: no I/O, no clocks, no randomness — every time- or
7
+ * order-sensitive function takes explicit `now` / `seed` / `pairs` inputs so
8
+ * results are deterministic and testable, and so the UI can run the same
9
+ * code client-side over a fetched graph payload.
10
+ *
11
+ * Operates on a camelCase graph shape structurally compatible with the
12
+ * `get_knowledge_graph` RPC payload (`KnowledgeGraphData` in the BUFI desk
13
+ * repo). NOTE: that RPC's relationship objects omit `lastSeenAt`; the weight
14
+ * formula treats a missing `lastSeenAt` as "fresh" (factor 1).
15
+ *
16
+ * Weight formula (documented constants below):
17
+ * w = strength * ln(1 + evidenceCount) * recencyFactor(lastSeenAt, now)
18
+ * recencyFactor = 0.5 ^ (daysStale / 90) — halves per 90 stale days
19
+ *
20
+ * Scale ceiling: everything here is in-memory over the fetched graph —
21
+ * fine for the BUFI-internal GTM graph (thousands of edges). Past ~50k
22
+ * edges, graduate to pgRouting / an RPC (see the 2026-07-16 gtm-graph spec).
23
+ */
24
+ interface GraphEntityLike {
25
+ id: string;
26
+ }
27
+ interface GraphEdgeLike {
28
+ id: string;
29
+ sourceEntityId: string;
30
+ targetEntityId: string;
31
+ relationshipType: string;
32
+ strength?: number | null;
33
+ evidenceCount?: number | null;
34
+ lastSeenAt?: string | null;
35
+ }
36
+ interface GraphDataLike {
37
+ entities: GraphEntityLike[];
38
+ relationships: GraphEdgeLike[];
39
+ }
40
+ interface AdjacentEdge {
41
+ edgeId: string;
42
+ otherId: string;
43
+ relationshipType: string;
44
+ weight: number;
45
+ }
46
+ /** node id → undirected incident edges (both directions materialized). */
47
+ type Adjacency = Map<string, AdjacentEdge[]>;
48
+ interface GraphPath {
49
+ /** Node ids from source to target (inclusive). */
50
+ nodeIds: string[];
51
+ /** Edge ids traversed, in order (`nodeIds.length - 1` entries). */
52
+ edgeIds: string[];
53
+ /** Hop count (= edgeIds.length). */
54
+ hops: number;
55
+ /** Sum of Dijkstra costs (1/w) — lower = stronger; 0 for the trivial path. */
56
+ cost: number;
57
+ }
58
+ /** Staleness half-life: an edge unseen for this many days weighs half. */
59
+ declare const RECENCY_HALF_LIFE_DAYS = 90;
60
+ /** Default strength when the payload omits it (DB default is 1.0). */
61
+ declare const DEFAULT_STRENGTH = 1;
62
+ /** Default evidence count when the payload omits it (DB default is 1). */
63
+ declare const DEFAULT_EVIDENCE_COUNT = 1;
64
+ /** Floor so degenerate edges never divide by zero in 1/w costs. */
65
+ declare const MIN_EDGE_WEIGHT = 0.000001;
66
+ /** 0.5^(daysStale/90); missing/unparseable lastSeenAt → 1 (fresh). */
67
+ declare function recencyFactor(lastSeenAt: string | null | undefined, now: number): number;
68
+ /** w = strength * ln(1 + evidenceCount) * recencyFactor — floored at MIN_EDGE_WEIGHT. */
69
+ declare function edgeWeight(edge: GraphEdgeLike, now: number): number;
70
+ /**
71
+ * Undirected adjacency view with per-edge weights.
72
+ * `now` (epoch ms) drives the recency factor — pass a fixed value in tests.
73
+ */
74
+ declare function buildAdjacency(data: GraphDataLike, options: {
75
+ now: number;
76
+ }): Adjacency;
77
+ interface FewestHopsOptions {
78
+ now?: number;
79
+ /** Give up beyond this many hops (default: unbounded). */
80
+ maxHops?: number;
81
+ /** Reuse a prebuilt adjacency (must match `data`). */
82
+ adjacency?: Adjacency;
83
+ }
84
+ /** BFS shortest path by hop count. Null when unreachable (or beyond maxHops). */
85
+ declare function fewestHops(data: GraphDataLike, fromId: string, toId: string, options?: FewestHopsOptions): GraphPath | null;
86
+ interface StrongestPathOptions {
87
+ /** Epoch ms for the recency factor. REQUIRED for determinism. */
88
+ now: number;
89
+ adjacency?: Adjacency;
90
+ }
91
+ /**
92
+ * Dijkstra minimizing sum(1/w): prefers few, strong, recent edges.
93
+ * Can legitimately return MORE hops than `fewestHops` when a longer chain of
94
+ * strong edges beats a weak direct edge. Null when unreachable.
95
+ */
96
+ declare function strongestPath(data: GraphDataLike, fromId: string, toId: string, options: StrongestPathOptions): GraphPath | null;
97
+ interface BridgeScoreOptions {
98
+ now?: number;
99
+ /** Max sampled node pairs (default 200). */
100
+ sampleSize?: number;
101
+ /** PRNG seed — same seed + same graph → identical scores. */
102
+ seed?: number;
103
+ /** Explicit pair list overrides sampling entirely (fully deterministic). */
104
+ pairs?: Array<[string, string]>;
105
+ }
106
+ declare const DEFAULT_BRIDGE_SAMPLE_SIZE = 200;
107
+ declare const DEFAULT_BRIDGE_SEED = 99;
108
+ /**
109
+ * Approximate betweenness: run `fewestHops` over sampled node pairs and count
110
+ * how often each node sits STRICTLY INSIDE the path. Normalized to [0, 1]
111
+ * by the max count. Deterministic given (`seed` | `pairs`) + the graph.
112
+ */
113
+ declare function bridgeScores(data: GraphDataLike, options?: BridgeScoreOptions): Map<string, number>;
114
+ /**
115
+ * The sub-graph within `hops` of `centerId` (entities + every edge whose two
116
+ * endpoints are both inside). Empty graph when the center is unknown.
117
+ */
118
+ declare function neighborhood(data: GraphDataLike, centerId: string, hops: number): GraphDataLike;
119
+
120
+ /**
121
+ * GTM decorations — pure classification helpers on top of the path engine
122
+ * (plan 100). Implements the POI + bridge definitions from the 2026-07-16
123
+ * gtm-graph spec so every consumer (desk admin route, open-agents endpoint,
124
+ * Shiva MCP routes) classifies nodes identically.
125
+ *
126
+ * - POI (person of interest): persons with `champion_of` /
127
+ * `decision_maker_for` edges into OPEN deals, OR a decision-maker title
128
+ * match on their metadata.
129
+ * - Bridge: top-N nodes by sampled betweenness (`bridgeScores`) — the
130
+ * people/orgs the most shortest paths flow through.
131
+ */
132
+ interface GtmEntityLike {
133
+ id: string;
134
+ entityType: string;
135
+ entityName?: string;
136
+ metadata?: Record<string, unknown> | null;
137
+ }
138
+ interface GtmEdgeLike {
139
+ id: string;
140
+ sourceEntityId: string;
141
+ targetEntityId: string;
142
+ relationshipType: string;
143
+ strength?: number | null;
144
+ evidenceCount?: number | null;
145
+ lastSeenAt?: string | null;
146
+ metadata?: Record<string, unknown> | null;
147
+ }
148
+ interface GtmGraphLike {
149
+ entities: GtmEntityLike[];
150
+ relationships: GtmEdgeLike[];
151
+ }
152
+ type GtmNodeClass = 'poi' | 'bridge' | 'other';
153
+ /** Edge types that mark a person as tied to a deal's buying decision. */
154
+ declare const POI_EDGE_TYPES: readonly ["champion_of", "decision_maker_for"];
155
+ /**
156
+ * Canonical CLOSED pipeline stages (lowercased): deals in these stages no
157
+ * longer make their champions POIs. Mirrors `@bu/types/sales-pipeline`
158
+ * (`Activo` = won, `Nurture/Perdido` = lost) — duplicated here because this
159
+ * package is published standalone and cannot import `@bu/*`.
160
+ */
161
+ declare const DEFAULT_CLOSED_STAGES: readonly ["activo", "nurture/perdido", "won", "lost"];
162
+ /**
163
+ * Decision-maker title fragments (lowercased substring match) for the
164
+ * title-based POI rule. Derived from the current LATAM-agencies ICP
165
+ * (tasks/notes/2026-07-15-icp-enriched-r1.md in the desk repo). Hosts can
166
+ * override via `PoiOptions.titlePatterns`.
167
+ */
168
+ declare const DEFAULT_POI_TITLE_PATTERNS: readonly ["founder", "co-founder", "cofounder", "ceo", "coo", "cfo", "owner", "partner", "managing director", "director general", "general manager", "head of finance", "head of operations", "finance manager", "operations manager"];
169
+ interface PoiOptions {
170
+ /** Lowercased stage names counting as CLOSED (default: DEFAULT_CLOSED_STAGES). */
171
+ closedStages?: readonly string[];
172
+ /** Lowercased title fragments that qualify a person as POI (default: DEFAULT_POI_TITLE_PATTERNS). */
173
+ titlePatterns?: readonly string[];
174
+ }
175
+ /** True when the deal entity's `metadata.stage` is NOT in the closed set (unknown stage → open). */
176
+ declare function isOpenDeal(deal: GtmEntityLike, closedStages?: readonly string[]): boolean;
177
+ /**
178
+ * POI ids per the spec: persons with champion_of/decision_maker_for edges
179
+ * into OPEN deals, OR a decision-maker title match.
180
+ */
181
+ declare function computePoiIds(data: GtmGraphLike, options?: PoiOptions): Set<string>;
182
+ interface BridgeOptions {
183
+ /** How many top-scored nodes count as bridges (default 5). */
184
+ topN?: number;
185
+ /** Epoch ms for recency weighting (default 0 = ignore recency). */
186
+ now?: number;
187
+ /** Deterministic sampling seed forwarded to bridgeScores. */
188
+ seed?: number;
189
+ /** Explicit pair list forwarded to bridgeScores (fully deterministic). */
190
+ pairs?: Array<[string, string]>;
191
+ }
192
+ /**
193
+ * Top-N bridge node ids by sampled betweenness. Nodes with score 0 are never
194
+ * bridges, so small/star graphs can return fewer than `topN`.
195
+ */
196
+ declare function computeBridgeIds(data: GtmGraphLike, options?: BridgeOptions): Set<string>;
197
+ /** Node class from precomputed POI/bridge sets — POI wins over bridge. */
198
+ declare function classifyNode(id: string, poiIds: ReadonlySet<string>, bridgeIds: ReadonlySet<string>): GtmNodeClass;
199
+ /**
200
+ * Cap a graph at `maxNodes` keeping the highest-degree nodes (POIs/bridges
201
+ * always survive), plus every edge whose two endpoints survive.
202
+ */
203
+ declare function capGraph(data: GtmGraphLike, maxNodes: number, pinned?: ReadonlySet<string>): GtmGraphLike;
204
+
205
+ export { type Adjacency, type AdjacentEdge, type BridgeOptions, type BridgeScoreOptions, DEFAULT_BRIDGE_SAMPLE_SIZE, DEFAULT_BRIDGE_SEED, DEFAULT_CLOSED_STAGES, DEFAULT_EVIDENCE_COUNT, DEFAULT_POI_TITLE_PATTERNS, DEFAULT_STRENGTH, type FewestHopsOptions, type GraphDataLike, type GraphEdgeLike, type GraphEntityLike, type GraphPath, type GtmEdgeLike, type GtmEntityLike, type GtmGraphLike, type GtmNodeClass, MIN_EDGE_WEIGHT, POI_EDGE_TYPES, type PoiOptions, RECENCY_HALF_LIFE_DAYS, type StrongestPathOptions, bridgeScores, buildAdjacency, capGraph, classifyNode, computeBridgeIds, computePoiIds, edgeWeight, fewestHops, isOpenDeal, neighborhood, recencyFactor, strongestPath };
@@ -0,0 +1,3 @@
1
+ export { DEFAULT_BRIDGE_SAMPLE_SIZE, DEFAULT_BRIDGE_SEED, DEFAULT_CLOSED_STAGES, DEFAULT_EVIDENCE_COUNT, DEFAULT_POI_TITLE_PATTERNS, DEFAULT_STRENGTH, MIN_EDGE_WEIGHT, POI_EDGE_TYPES, RECENCY_HALF_LIFE_DAYS, bridgeScores, buildAdjacency, capGraph, classifyNode, computeBridgeIds, computePoiIds, edgeWeight, fewestHops, isOpenDeal, neighborhood, recencyFactor, strongestPath } from '../chunk-MW4VOWB5.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}