@civiq/entity-resolution 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.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +135 -0
  3. package/data/bioguide-fec-mapping.json +4186 -0
  4. package/data/sec-sic-data.json +10427 -0
  5. package/dist/__tests__/company-entity-resolver.test.d.ts +6 -0
  6. package/dist/__tests__/company-entity-resolver.test.d.ts.map +1 -0
  7. package/dist/__tests__/company-entity-resolver.test.js +267 -0
  8. package/dist/__tests__/company-entity-resolver.test.js.map +1 -0
  9. package/dist/__tests__/entity-resolution.test.d.ts +2 -0
  10. package/dist/__tests__/entity-resolution.test.d.ts.map +1 -0
  11. package/dist/__tests__/entity-resolution.test.js +296 -0
  12. package/dist/__tests__/entity-resolution.test.js.map +1 -0
  13. package/dist/__tests__/fec-entity-resolution.test.d.ts +2 -0
  14. package/dist/__tests__/fec-entity-resolution.test.d.ts.map +1 -0
  15. package/dist/__tests__/fec-entity-resolution.test.js +49 -0
  16. package/dist/__tests__/fec-entity-resolution.test.js.map +1 -0
  17. package/dist/bioguide-fec-mapping.d.ts +27 -0
  18. package/dist/bioguide-fec-mapping.d.ts.map +1 -0
  19. package/dist/bioguide-fec-mapping.js +57 -0
  20. package/dist/bioguide-fec-mapping.js.map +1 -0
  21. package/dist/cache.d.ts +18 -0
  22. package/dist/cache.d.ts.map +1 -0
  23. package/dist/cache.js +18 -0
  24. package/dist/cache.js.map +1 -0
  25. package/dist/committee-agency-map.d.ts +58 -0
  26. package/dist/committee-agency-map.d.ts.map +1 -0
  27. package/dist/committee-agency-map.js +658 -0
  28. package/dist/committee-agency-map.js.map +1 -0
  29. package/dist/committee-alias-table.d.ts +11 -0
  30. package/dist/committee-alias-table.d.ts.map +1 -0
  31. package/dist/committee-alias-table.js +191 -0
  32. package/dist/committee-alias-table.js.map +1 -0
  33. package/dist/company-alias-table.d.ts +36 -0
  34. package/dist/company-alias-table.d.ts.map +1 -0
  35. package/dist/company-alias-table.js +1307 -0
  36. package/dist/company-alias-table.js.map +1 -0
  37. package/dist/company-entity-resolver.d.ts +94 -0
  38. package/dist/company-entity-resolver.d.ts.map +1 -0
  39. package/dist/company-entity-resolver.js +282 -0
  40. package/dist/company-entity-resolver.js.map +1 -0
  41. package/dist/configure.d.ts +15 -0
  42. package/dist/configure.d.ts.map +1 -0
  43. package/dist/configure.js +19 -0
  44. package/dist/configure.js.map +1 -0
  45. package/dist/fec-entity-resolution.d.ts +88 -0
  46. package/dist/fec-entity-resolution.d.ts.map +1 -0
  47. package/dist/fec-entity-resolution.js +407 -0
  48. package/dist/fec-entity-resolution.js.map +1 -0
  49. package/dist/index.d.ts +30 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +33 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/industry-taxonomy.d.ts +90 -0
  54. package/dist/industry-taxonomy.d.ts.map +1 -0
  55. package/dist/industry-taxonomy.js +1026 -0
  56. package/dist/industry-taxonomy.js.map +1 -0
  57. package/dist/lda-issue-policy-map.d.ts +13 -0
  58. package/dist/lda-issue-policy-map.d.ts.map +1 -0
  59. package/dist/lda-issue-policy-map.js +193 -0
  60. package/dist/lda-issue-policy-map.js.map +1 -0
  61. package/dist/lobbying-committee-resolver.d.ts +23 -0
  62. package/dist/lobbying-committee-resolver.d.ts.map +1 -0
  63. package/dist/lobbying-committee-resolver.js +158 -0
  64. package/dist/lobbying-committee-resolver.js.map +1 -0
  65. package/dist/logger.d.ts +20 -0
  66. package/dist/logger.d.ts.map +1 -0
  67. package/dist/logger.js +20 -0
  68. package/dist/logger.js.map +1 -0
  69. package/dist/sic-sector-map.d.ts +32 -0
  70. package/dist/sic-sector-map.d.ts.map +1 -0
  71. package/dist/sic-sector-map.js +109 -0
  72. package/dist/sic-sector-map.js.map +1 -0
  73. package/dist/ticker-industry-resolver.d.ts +22 -0
  74. package/dist/ticker-industry-resolver.d.ts.map +1 -0
  75. package/dist/ticker-industry-resolver.js +254 -0
  76. package/dist/ticker-industry-resolver.js.map +1 -0
  77. package/dist/types.d.ts +30 -0
  78. package/dist/types.d.ts.map +1 -0
  79. package/dist/types.js +6 -0
  80. package/dist/types.js.map +1 -0
  81. package/package.json +51 -0
@@ -0,0 +1,407 @@
1
+ /**
2
+ * Copyright (c) 2019-2025 Mark Sandford
3
+ * Licensed under the MIT License. See LICENSE and NOTICE files.
4
+ */
5
+ /**
6
+ * FEC Entity Resolution & Name Standardization
7
+ *
8
+ * Handles entity matching, name normalization, and deduplication for:
9
+ * - Individual contributors with name variants (JOHN SMITH vs John Smith vs J. Smith)
10
+ * - Organizations/employers with variations (GOOGLE INC. vs Google Inc vs Google)
11
+ * - Recipients/disbursement entities (consulting firms, vendors)
12
+ *
13
+ * Uses string similarity algorithms and business rule heuristics to match entities.
14
+ */
15
+ import { getLogger } from './logger';
16
+ /**
17
+ * Common abbreviations used in FEC/lobbying data.
18
+ * Maps normalized short forms to canonical full names.
19
+ */
20
+ const COMMON_ABBREVIATIONS = {
21
+ jnj: 'johnson and johnson',
22
+ jj: 'johnson and johnson',
23
+ 'j and j': 'johnson and johnson',
24
+ gm: 'general motors',
25
+ ge: 'general electric',
26
+ ibm: 'international business machines',
27
+ att: 'at and t',
28
+ 'at t': 'at and t',
29
+ jpmorgan: 'jpmorgan chase',
30
+ jpm: 'jpmorgan chase',
31
+ bofa: 'bank of america',
32
+ pg: 'procter and gamble',
33
+ 'p and g': 'procter and gamble',
34
+ msft: 'microsoft',
35
+ amzn: 'amazon',
36
+ goog: 'alphabet',
37
+ aapl: 'apple',
38
+ pfizer: 'pfizer',
39
+ raytheon: 'raytheon technologies',
40
+ lockmart: 'lockheed martin',
41
+ ba: 'boeing',
42
+ };
43
+ /**
44
+ * Expand a cleaned name using the abbreviation map.
45
+ * Returns the canonical form if found, otherwise returns the original.
46
+ */
47
+ function expandAbbreviation(cleanedName) {
48
+ const lower = cleanedName.toLowerCase();
49
+ if (COMMON_ABBREVIATIONS[lower]) {
50
+ return COMMON_ABBREVIATIONS[lower].toUpperCase();
51
+ }
52
+ return cleanedName;
53
+ }
54
+ /**
55
+ * Remove common noise from names for better matching
56
+ */
57
+ function cleanNameForMatching(name) {
58
+ return (name
59
+ .trim()
60
+ .toUpperCase()
61
+ // Remove common suffixes
62
+ .replace(/\s+(INC\.?|LLC\.?|LLP\.?|CORP\.?|CORPORATION|COMPANY|CO\.?|LTD\.?)$/i, '')
63
+ // Normalize ampersand to AND before stripping punctuation
64
+ .replace(/&/g, ' AND ')
65
+ // Remove punctuation except spaces
66
+ .replace(/[^\w\s]/g, '')
67
+ // Normalize multiple spaces
68
+ .replace(/\s+/g, ' ')
69
+ .trim());
70
+ }
71
+ /**
72
+ * Standardize individual names to canonical form
73
+ * Handles: LAST, FIRST MIDDLE -> First Middle Last
74
+ */
75
+ function standardizeIndividualName(name) {
76
+ const cleaned = name.trim();
77
+ // Check if name is in "LAST, FIRST" format
78
+ if (cleaned.includes(',')) {
79
+ const parts = cleaned.split(',').map(p => p.trim());
80
+ if (parts.length === 2) {
81
+ const [last, first] = parts;
82
+ return `${first} ${last}`.replace(/\s+/g, ' ').trim();
83
+ }
84
+ }
85
+ // Already in "First Last" format
86
+ return cleaned.replace(/\s+/g, ' ').trim();
87
+ }
88
+ /**
89
+ * Calculate Levenshtein distance for string similarity
90
+ * Used to detect typos and minor variations
91
+ */
92
+ function levenshteinDistance(a, b) {
93
+ const matrix = [];
94
+ for (let i = 0; i <= b.length; i++) {
95
+ matrix[i] = [i];
96
+ }
97
+ for (let j = 0; j <= a.length; j++) {
98
+ matrix[0][j] = j;
99
+ }
100
+ for (let i = 1; i <= b.length; i++) {
101
+ for (let j = 1; j <= a.length; j++) {
102
+ if (b.charAt(i - 1) === a.charAt(j - 1)) {
103
+ matrix[i][j] = matrix[i - 1][j - 1];
104
+ }
105
+ else {
106
+ matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
107
+ matrix[i][j - 1] + 1, // insertion
108
+ matrix[i - 1][j] + 1 // deletion
109
+ );
110
+ }
111
+ }
112
+ }
113
+ return matrix[b.length][a.length];
114
+ }
115
+ /**
116
+ * Calculate similarity ratio between two strings (0-1)
117
+ */
118
+ function similarityRatio(a, b) {
119
+ const distance = levenshteinDistance(a, b);
120
+ const maxLength = Math.max(a.length, b.length);
121
+ return maxLength === 0 ? 1 : 1 - distance / maxLength;
122
+ }
123
+ /**
124
+ * Detect if name represents an individual or organization
125
+ */
126
+ function detectEntityType(name) {
127
+ const cleaned = name.toUpperCase();
128
+ // Organization indicators
129
+ const orgIndicators = [
130
+ 'INC',
131
+ 'LLC',
132
+ 'LLP',
133
+ 'CORP',
134
+ 'CORPORATION',
135
+ 'COMPANY',
136
+ 'CO',
137
+ 'LTD',
138
+ 'PARTNERSHIP',
139
+ 'COMMITTEE',
140
+ 'PAC',
141
+ 'FUND',
142
+ 'FOUNDATION',
143
+ 'ASSOCIATION',
144
+ 'SOCIETY',
145
+ 'INSTITUTE',
146
+ 'COUNCIL',
147
+ 'GROUP',
148
+ ];
149
+ if (orgIndicators.some(indicator => cleaned.includes(indicator))) {
150
+ return 'organization';
151
+ }
152
+ // Individual indicators (comma-separated name format)
153
+ if (cleaned.includes(',')) {
154
+ return 'individual';
155
+ }
156
+ // Count words - individuals typically have 2-4 words
157
+ const wordCount = cleaned.split(/\s+/).length;
158
+ if (wordCount >= 2 && wordCount <= 4) {
159
+ return 'individual';
160
+ }
161
+ return 'unknown';
162
+ }
163
+ /**
164
+ * Check if two entities should be considered the same based on name similarity
165
+ * and metadata matching
166
+ */
167
+ export function entitiesMatch(entity1, entity2, threshold = 0.85) {
168
+ const name1 = cleanNameForMatching(entity1.name);
169
+ const name2 = cleanNameForMatching(entity2.name);
170
+ // Exact match
171
+ if (name1 === name2) {
172
+ return true;
173
+ }
174
+ // Expand common abbreviations before similarity comparison
175
+ const expanded1 = expandAbbreviation(name1);
176
+ const expanded2 = expandAbbreviation(name2);
177
+ // Re-check exact match after expansion
178
+ if (expanded1 === expanded2) {
179
+ return true;
180
+ }
181
+ // Calculate similarity using expanded forms
182
+ const similarity = similarityRatio(expanded1, expanded2);
183
+ // High similarity threshold for base match
184
+ if (similarity < threshold) {
185
+ return false;
186
+ }
187
+ // Additional metadata checks to confirm match
188
+ let metadataMatches = 0;
189
+ let metadataChecks = 0;
190
+ // Check employer match (for individuals)
191
+ if (entity1.employer && entity2.employer) {
192
+ metadataChecks++;
193
+ const emp1 = cleanNameForMatching(entity1.employer);
194
+ const emp2 = cleanNameForMatching(entity2.employer);
195
+ if (emp1 === emp2 || similarityRatio(emp1, emp2) > 0.8) {
196
+ metadataMatches++;
197
+ }
198
+ }
199
+ // Check location match
200
+ if (entity1.state && entity2.state) {
201
+ metadataChecks++;
202
+ if (entity1.state.toUpperCase() === entity2.state.toUpperCase()) {
203
+ metadataMatches++;
204
+ // Same city is strong confirmation
205
+ if (entity1.city && entity2.city) {
206
+ metadataChecks++;
207
+ const city1 = cleanNameForMatching(entity1.city);
208
+ const city2 = cleanNameForMatching(entity2.city);
209
+ if (city1 === city2) {
210
+ metadataMatches++;
211
+ }
212
+ }
213
+ }
214
+ }
215
+ // If we have metadata, require at least 50% match
216
+ if (metadataChecks > 0) {
217
+ return metadataMatches / metadataChecks >= 0.5;
218
+ }
219
+ // No metadata, rely on name similarity
220
+ return similarity >= threshold;
221
+ }
222
+ /**
223
+ * Normalize a single entity name and metadata
224
+ */
225
+ export function normalizeEntity(name, metadata) {
226
+ const entityType = detectEntityType(name);
227
+ let displayName;
228
+ let normalizedName;
229
+ if (entityType === 'individual') {
230
+ displayName = standardizeIndividualName(name);
231
+ normalizedName = cleanNameForMatching(displayName);
232
+ }
233
+ else {
234
+ displayName = name.trim();
235
+ normalizedName = cleanNameForMatching(name);
236
+ }
237
+ return {
238
+ normalizedName,
239
+ displayName,
240
+ rawVariants: [name],
241
+ entityType,
242
+ metadata: metadata || {},
243
+ };
244
+ }
245
+ /**
246
+ * Deduplicate and aggregate contributions by entity
247
+ */
248
+ export function deduplicateContributions(contributions) {
249
+ const entityMap = new Map();
250
+ getLogger().debug(`[Entity Resolution] Deduplicating ${contributions.length} contributions`);
251
+ for (const contrib of contributions) {
252
+ if (!contrib.contributor_name?.trim()) {
253
+ continue;
254
+ }
255
+ const metadata = {
256
+ employer: contrib.contributor_employer,
257
+ occupation: contrib.contributor_occupation,
258
+ city: contrib.contributor_city,
259
+ state: contrib.contributor_state,
260
+ zip: contrib.contributor_zip,
261
+ };
262
+ const normalized = normalizeEntity(contrib.contributor_name, metadata);
263
+ // Check if we already have a matching entity
264
+ let matchedKey = null;
265
+ for (const [key, existing] of entityMap.entries()) {
266
+ if (entitiesMatch({
267
+ name: normalized.normalizedName,
268
+ employer: metadata.employer,
269
+ city: metadata.city,
270
+ state: metadata.state,
271
+ zip: metadata.zip,
272
+ }, {
273
+ name: existing.normalizedName,
274
+ employer: existing.metadata.employer,
275
+ city: existing.metadata.city,
276
+ state: existing.metadata.state,
277
+ zip: existing.metadata.zip,
278
+ })) {
279
+ matchedKey = key;
280
+ break;
281
+ }
282
+ }
283
+ if (matchedKey) {
284
+ // Add to existing entity
285
+ const existing = entityMap.get(matchedKey);
286
+ existing.totalAmount += contrib.contribution_receipt_amount;
287
+ existing.transactionCount++;
288
+ existing.transactions.push({
289
+ amount: contrib.contribution_receipt_amount,
290
+ date: contrib.contribution_receipt_date,
291
+ rawName: contrib.contributor_name,
292
+ });
293
+ // Add variant if not already present
294
+ if (!existing.rawVariants.includes(contrib.contributor_name)) {
295
+ existing.rawVariants.push(contrib.contributor_name);
296
+ }
297
+ // Update metadata if more complete
298
+ if (!existing.metadata.employer && metadata.employer) {
299
+ existing.metadata.employer = metadata.employer;
300
+ }
301
+ if (!existing.metadata.occupation && metadata.occupation) {
302
+ existing.metadata.occupation = metadata.occupation;
303
+ }
304
+ }
305
+ else {
306
+ // Create new entity
307
+ entityMap.set(normalized.normalizedName, {
308
+ ...normalized,
309
+ totalAmount: contrib.contribution_receipt_amount,
310
+ transactionCount: 1,
311
+ transactions: [
312
+ {
313
+ amount: contrib.contribution_receipt_amount,
314
+ date: contrib.contribution_receipt_date,
315
+ rawName: contrib.contributor_name,
316
+ },
317
+ ],
318
+ });
319
+ }
320
+ }
321
+ const result = Array.from(entityMap.values());
322
+ getLogger().debug(`[Entity Resolution] Deduplicated ${contributions.length} contributions into ${result.length} unique entities`);
323
+ return result;
324
+ }
325
+ /**
326
+ * Deduplicate and aggregate disbursements by recipient
327
+ */
328
+ export function deduplicateDisbursements(disbursements) {
329
+ const entityMap = new Map();
330
+ getLogger().debug(`[Entity Resolution] Deduplicating ${disbursements.length} disbursements`);
331
+ for (const disb of disbursements) {
332
+ if (!disb.recipient_name?.trim()) {
333
+ continue;
334
+ }
335
+ const metadata = {
336
+ city: disb.recipient_city,
337
+ state: disb.recipient_state,
338
+ };
339
+ const normalized = normalizeEntity(disb.recipient_name, metadata);
340
+ // Check if we already have a matching entity
341
+ let matchedKey = null;
342
+ for (const [key, existing] of entityMap.entries()) {
343
+ if (entitiesMatch({
344
+ name: normalized.normalizedName,
345
+ city: metadata.city,
346
+ state: metadata.state,
347
+ }, {
348
+ name: existing.normalizedName,
349
+ city: existing.metadata.city,
350
+ state: existing.metadata.state,
351
+ })) {
352
+ matchedKey = key;
353
+ break;
354
+ }
355
+ }
356
+ if (matchedKey) {
357
+ // Add to existing entity
358
+ const existing = entityMap.get(matchedKey);
359
+ existing.totalAmount += disb.disbursement_amount;
360
+ existing.transactionCount++;
361
+ existing.transactions.push({
362
+ amount: disb.disbursement_amount,
363
+ date: disb.disbursement_date,
364
+ rawName: disb.recipient_name,
365
+ });
366
+ // Add variant if not already present
367
+ if (!existing.rawVariants.includes(disb.recipient_name)) {
368
+ existing.rawVariants.push(disb.recipient_name);
369
+ }
370
+ }
371
+ else {
372
+ // Create new entity
373
+ entityMap.set(normalized.normalizedName, {
374
+ ...normalized,
375
+ totalAmount: disb.disbursement_amount,
376
+ transactionCount: 1,
377
+ transactions: [
378
+ {
379
+ amount: disb.disbursement_amount,
380
+ date: disb.disbursement_date,
381
+ rawName: disb.recipient_name,
382
+ },
383
+ ],
384
+ });
385
+ }
386
+ }
387
+ const result = Array.from(entityMap.values());
388
+ getLogger().debug(`[Entity Resolution] Deduplicated ${disbursements.length} disbursements into ${result.length} unique entities`);
389
+ return result;
390
+ }
391
+ /**
392
+ * Standardize employer/organization names for industry analysis
393
+ */
394
+ export function standardizeEmployerName(employer) {
395
+ const cleaned = employer.trim();
396
+ const entityType = detectEntityType(cleaned);
397
+ if (entityType === 'organization') {
398
+ // Return cleaned form without corporate suffixes
399
+ return cleanNameForMatching(cleaned)
400
+ .split(' ')
401
+ .map(word => word.charAt(0) + word.slice(1).toLowerCase())
402
+ .join(' ');
403
+ }
404
+ // Keep original for individuals or unknown
405
+ return cleaned;
406
+ }
407
+ //# sourceMappingURL=fec-entity-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fec-entity-resolution.js","sourceRoot":"","sources":["../src/fec-entity-resolution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @civiq/entity-resolution
3
+ *
4
+ * Entity resolution for civic data — committee/agency alias matching,
5
+ * industry taxonomy, ticker-to-sector resolution, FEC entity deduplication.
6
+ */
7
+ export { configure } from './configure';
8
+ export { setLogger, getLogger } from './logger';
9
+ export type { Logger } from './logger';
10
+ export { setCache, getCache } from './cache';
11
+ export type { CacheAdapter } from './cache';
12
+ export type { GovernmentEntityResolution, TickerResolution } from './types';
13
+ export { IndustrySector, categorizeContribution, aggregateByIndustrySector, categorizePACByName, categorizeContributionSmart, getTopCategories, } from './industry-taxonomy';
14
+ export type { IndustryCategory, CategorizedContribution } from './industry-taxonomy';
15
+ export { HOUSE_COMMITTEE_MAPPINGS, SENATE_COMMITTEE_MAPPINGS, ALL_COMMITTEE_MAPPINGS, getAgenciesForCommittee, getTopicsForCommittee, getAgenciesForCommittees, getCommitteesForAgency, getTopicsForCommittees, } from './committee-agency-map';
16
+ export type { AgencyInfo, CommitteeMapping } from './committee-agency-map';
17
+ export { COMMITTEE_ALIASES, AGENCY_ALIASES, getAllCommitteeAliasNames, } from './committee-alias-table';
18
+ export { resolveGovernmentEntity, resolveFilingEntities, getResolvedCommittees, } from './lobbying-committee-resolver';
19
+ export { sicToSector } from './sic-sector-map';
20
+ export { resolveTickerIndustry, resolveTickerIndustries } from './ticker-industry-resolver';
21
+ export { LDA_ISSUE_POLICY_MAP, getLDAIssueLabel, getPolicyAreasForLDAIssue, getAllLDAIssueCodes, } from './lda-issue-policy-map';
22
+ export { resolveCompanyName, resolveCompanyNames, normalizeCompanyName, companiesMatch, validateTokenOverlap, similarityRatio, } from './company-entity-resolver';
23
+ export type { ResolvedCompany } from './company-entity-resolver';
24
+ export { COMPANY_ALIAS_TABLE, findCompanyByAlias } from './company-alias-table';
25
+ export type { CompanyAlias } from './company-alias-table';
26
+ export { entitiesMatch, normalizeEntity, deduplicateContributions, deduplicateDisbursements, standardizeEmployerName, } from './fec-entity-resolution';
27
+ export type { StandardizedEntity, AggregatedEntity } from './fec-entity-resolution';
28
+ export { bioguideToFECMapping, getFECIdFromBioguide, hasFECMapping, addFECMapping, getBioguideFromFEC, getMappingByFEC, getMappingStats, } from './bioguide-fec-mapping';
29
+ export type { FECMapping } from './bioguide-fec-mapping';
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAChD,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,YAAY,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACnB,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAGrF,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG3E,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAG5F,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,eAAe,GAChB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChF,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1D,OAAO,EACL,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGpF,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @civiq/entity-resolution
3
+ *
4
+ * Entity resolution for civic data — committee/agency alias matching,
5
+ * industry taxonomy, ticker-to-sector resolution, FEC entity deduplication.
6
+ */
7
+ // ── Configuration ────────────────────────────────────────────────────
8
+ export { configure } from './configure';
9
+ export { setLogger, getLogger } from './logger';
10
+ export { setCache, getCache } from './cache';
11
+ // ── Industry Taxonomy ────────────────────────────────────────────────
12
+ export { IndustrySector, categorizeContribution, aggregateByIndustrySector, categorizePACByName, categorizeContributionSmart, getTopCategories, } from './industry-taxonomy';
13
+ // ── Committee-Agency Map ─────────────────────────────────────────────
14
+ export { HOUSE_COMMITTEE_MAPPINGS, SENATE_COMMITTEE_MAPPINGS, ALL_COMMITTEE_MAPPINGS, getAgenciesForCommittee, getTopicsForCommittee, getAgenciesForCommittees, getCommitteesForAgency, getTopicsForCommittees, } from './committee-agency-map';
15
+ // ── Committee Alias Table ────────────────────────────────────────────
16
+ export { COMMITTEE_ALIASES, AGENCY_ALIASES, getAllCommitteeAliasNames, } from './committee-alias-table';
17
+ // ── Lobbying Committee Resolver ──────────────────────────────────────
18
+ export { resolveGovernmentEntity, resolveFilingEntities, getResolvedCommittees, } from './lobbying-committee-resolver';
19
+ // ── SIC Sector Map ───────────────────────────────────────────────────
20
+ export { sicToSector } from './sic-sector-map';
21
+ // ── Ticker Industry Resolver ─────────────────────────────────────────
22
+ export { resolveTickerIndustry, resolveTickerIndustries } from './ticker-industry-resolver';
23
+ // ── LDA Issue Policy Map ─────────────────────────────────────────────
24
+ export { LDA_ISSUE_POLICY_MAP, getLDAIssueLabel, getPolicyAreasForLDAIssue, getAllLDAIssueCodes, } from './lda-issue-policy-map';
25
+ // ── Company Entity Resolution ────────────────────────────────────────
26
+ export { resolveCompanyName, resolveCompanyNames, normalizeCompanyName, companiesMatch, validateTokenOverlap, similarityRatio, } from './company-entity-resolver';
27
+ // ── Company Alias Table ─────────────────────────────────────────────
28
+ export { COMPANY_ALIAS_TABLE, findCompanyByAlias } from './company-alias-table';
29
+ // ── FEC Entity Resolution ────────────────────────────────────────────
30
+ export { entitiesMatch, normalizeEntity, deduplicateContributions, deduplicateDisbursements, standardizeEmployerName, } from './fec-entity-resolution';
31
+ // ── Bioguide-FEC Mapping ─────────────────────────────────────────────
32
+ export { bioguideToFECMapping, getFECIdFromBioguide, hasFECMapping, addFECMapping, getBioguideFromFEC, getMappingByFEC, getMappingStats, } from './bioguide-fec-mapping';
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wEAAwE;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM7C,wEAAwE;AACxE,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACnB,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,wEAAwE;AACxE,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAGhC,wEAAwE;AACxE,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,wEAAwE;AACxE,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AAEvC,wEAAwE;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,wEAAwE;AACxE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE5F,wEAAwE;AACxE,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAEhC,wEAAwE;AACxE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,eAAe,GAChB,MAAM,2BAA2B,CAAC;AAGnC,uEAAuE;AACvE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhF,wEAAwE;AACxE,OAAO,EACL,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAGjC,wEAAwE;AACxE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Copyright (c) 2019-2025 Mark Sandford
3
+ * Licensed under the MIT License. See LICENSE and NOTICE files.
4
+ */
5
+ /**
6
+ * Industry sector enumeration
7
+ */
8
+ export declare enum IndustrySector {
9
+ AGRIBUSINESS = "Agribusiness",
10
+ COMMUNICATIONS_ELECTRONICS = "Communications/Electronics",
11
+ CONSTRUCTION = "Construction",
12
+ DEFENSE = "Defense",
13
+ ENERGY_NATURAL_RESOURCES = "Energy/Natural Resources",
14
+ FINANCE_INSURANCE_REAL_ESTATE = "Finance/Insurance/Real Estate",
15
+ HEALTH = "Health",
16
+ LAWYERS_LOBBYISTS = "Lawyers & Lobbyists",
17
+ TRANSPORTATION = "Transportation",
18
+ MISC_BUSINESS = "Misc Business",
19
+ LABOR = "Labor",
20
+ IDEOLOGY_SINGLE_ISSUE = "Ideology/Single-Issue",
21
+ OTHER = "Other"
22
+ }
23
+ /**
24
+ * Detailed industry category under each sector
25
+ */
26
+ export interface IndustryCategory {
27
+ sector: IndustrySector;
28
+ category: string;
29
+ keywords: string[];
30
+ occupationKeywords?: string[];
31
+ }
32
+ /**
33
+ * Categorized contribution with industry classification
34
+ */
35
+ export interface CategorizedContribution {
36
+ sector: IndustrySector;
37
+ category: string;
38
+ confidence: 'high' | 'medium' | 'low';
39
+ matchedKeyword?: string;
40
+ matchSource: 'employer' | 'occupation' | 'inferred';
41
+ }
42
+ /**
43
+ * Categorize a contribution based on employer and occupation
44
+ */
45
+ export declare function categorizeContribution(employer?: string, occupation?: string): CategorizedContribution;
46
+ /**
47
+ * Aggregate contributions by industry sector.
48
+ * Uses smart categorization when contributor_name is available,
49
+ * falling back to PAC name matching for unclassified contributions.
50
+ */
51
+ export declare function aggregateByIndustrySector(contributions: Array<{
52
+ contributor_employer?: string;
53
+ contributor_occupation?: string;
54
+ contributor_name?: string;
55
+ contribution_receipt_amount: number;
56
+ }>): Array<{
57
+ sector: IndustrySector;
58
+ totalAmount: number;
59
+ contributionCount: number;
60
+ percentage: number;
61
+ categories: Map<string, {
62
+ amount: number;
63
+ count: number;
64
+ }>;
65
+ }>;
66
+ /**
67
+ * Categorize a PAC/committee by its name
68
+ * Used for committee-to-committee transfers and PAC contributions
69
+ */
70
+ export declare function categorizePACByName(committeeName?: string): CategorizedContribution;
71
+ /**
72
+ * Smart categorization: tries employer/occupation first, then falls back to contributor name (for PACs)
73
+ */
74
+ export declare function categorizeContributionSmart(employer?: string, occupation?: string, contributorName?: string): CategorizedContribution;
75
+ /**
76
+ * Get top categories across all sectors
77
+ */
78
+ export declare function getTopCategories(contributions: Array<{
79
+ contributor_employer?: string;
80
+ contributor_occupation?: string;
81
+ contributor_name?: string;
82
+ contribution_receipt_amount: number;
83
+ }>, limit?: number): Array<{
84
+ sector: IndustrySector;
85
+ category: string;
86
+ totalAmount: number;
87
+ contributionCount: number;
88
+ percentage: number;
89
+ }>;
90
+ //# sourceMappingURL=industry-taxonomy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"industry-taxonomy.d.ts","sourceRoot":"","sources":["../src/industry-taxonomy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0BH;;GAEG;AACH,oBAAY,cAAc;IACxB,YAAY,iBAAiB;IAC7B,0BAA0B,+BAA+B;IACzD,YAAY,iBAAiB;IAC7B,OAAO,YAAY;IACnB,wBAAwB,6BAA6B;IACrD,6BAA6B,kCAAkC;IAC/D,MAAM,WAAW;IACjB,iBAAiB,wBAAwB;IACzC,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,KAAK,UAAU;IACf,qBAAqB,0BAA0B;IAC/C,KAAK,UAAU;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;CACrD;AA4aD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,uBAAuB,CA+FzB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,KAAK,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2BAA2B,EAAE,MAAM,CAAC;CACrC,CAAC,GACD,KAAK,CAAC;IACP,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5D,CAAC,CAuDD;AAiUD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,uBAAuB,CA6FnF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,MAAM,GACvB,uBAAuB,CAqBzB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,KAAK,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2BAA2B,EAAE,MAAM,CAAC;CACrC,CAAC,EACF,KAAK,GAAE,MAAW,GACjB,KAAK,CAAC;IACP,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CA4CD"}