fdic-mcp-server 1.16.0 → 1.17.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.
- package/dist/index.js +31 -31
- package/dist/server.js +31 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
|
32
32
|
var import_express2 = __toESM(require("express"));
|
|
33
33
|
|
|
34
34
|
// src/constants.ts
|
|
35
|
-
var VERSION = true ? "1.
|
|
35
|
+
var VERSION = true ? "1.17.0" : process.env.npm_package_version ?? "0.0.0-dev";
|
|
36
36
|
var FDIC_API_BASE_URL = "https://banks.data.fdic.gov/api";
|
|
37
37
|
var CHARACTER_LIMIT = 5e4;
|
|
38
38
|
var DEFAULT_FDIC_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
@@ -32687,19 +32687,16 @@ Common filter examples:
|
|
|
32687
32687
|
- Branches in a state: STALPBR:CA
|
|
32688
32688
|
- Branches in a city: CITYBR:"Austin"
|
|
32689
32689
|
- High-deposit branches: DEPSUMBR:[1000000 TO *]
|
|
32690
|
-
- By metro area:
|
|
32690
|
+
- By metro area (MSA code): MSABR:19100
|
|
32691
32691
|
|
|
32692
32692
|
Key returned fields:
|
|
32693
32693
|
- YEAR: Report year (as of June 30)
|
|
32694
32694
|
- CERT: FDIC Certificate Number
|
|
32695
32695
|
- BRNUM: Branch number (0 = main office)
|
|
32696
|
-
-
|
|
32697
|
-
- NAMEFULL: Full branch name
|
|
32696
|
+
- NAMEFULL: Branch or institution name
|
|
32698
32697
|
- ADDRESBR, CITYBR, STALPBR, ZIPBR: Branch address
|
|
32699
|
-
- CNTYBR: County
|
|
32700
32698
|
- DEPSUMBR: Total deposits at branch ($thousands)
|
|
32701
|
-
- MSABR: Metropolitan Statistical Area code
|
|
32702
|
-
- MSANAMEBR: MSA name
|
|
32699
|
+
- MSABR: Metropolitan Statistical Area code (numeric; 0 = non-MSA)
|
|
32703
32700
|
- LATITUDE, LONGITUDE: Coordinates
|
|
32704
32701
|
|
|
32705
32702
|
Args:
|
|
@@ -34640,7 +34637,7 @@ var CANONICAL_FIELDS = [
|
|
|
34640
34637
|
"SC",
|
|
34641
34638
|
"ASSTLT",
|
|
34642
34639
|
"VOLIAB",
|
|
34643
|
-
"
|
|
34640
|
+
"OTHBRF"
|
|
34644
34641
|
].join(",");
|
|
34645
34642
|
var FIELD_ALIASES = {
|
|
34646
34643
|
IDT1CER: ["REPTE9"],
|
|
@@ -34717,7 +34714,7 @@ function extractCanonicalMetrics(raw) {
|
|
|
34717
34714
|
const sc = asNumber(raw.SC);
|
|
34718
34715
|
const asstlt = asNumber(raw.ASSTLT);
|
|
34719
34716
|
const voliab = asNumber(raw.VOLIAB);
|
|
34720
|
-
const
|
|
34717
|
+
const othbrf = asNumber(raw.OTHBRF);
|
|
34721
34718
|
const metrics = {
|
|
34722
34719
|
// Amounts
|
|
34723
34720
|
totalAssets: direct("totalAssets", "ASSET"),
|
|
@@ -34786,8 +34783,8 @@ function extractCanonicalMetrics(raw) {
|
|
|
34786
34783
|
),
|
|
34787
34784
|
borrowedFundsToAssetsPct: derived(
|
|
34788
34785
|
"borrowedFundsToAssetsPct",
|
|
34789
|
-
() => safeDivPct(
|
|
34790
|
-
"
|
|
34786
|
+
() => safeDivPct(othbrf, asset),
|
|
34787
|
+
"OTHBRF / ASSET * 100"
|
|
34791
34788
|
)
|
|
34792
34789
|
};
|
|
34793
34790
|
for (const [key, value] of Object.entries(metrics)) {
|
|
@@ -36678,7 +36675,6 @@ var CREDIT_FIELDS = [
|
|
|
36678
36675
|
"LNCI",
|
|
36679
36676
|
"LNCON",
|
|
36680
36677
|
"LNAG",
|
|
36681
|
-
"LNOTH",
|
|
36682
36678
|
"LNREDOM",
|
|
36683
36679
|
"LNREFOR"
|
|
36684
36680
|
].join(",");
|
|
@@ -37571,7 +37567,7 @@ function buildMarketConcentration(participants) {
|
|
|
37571
37567
|
}
|
|
37572
37568
|
|
|
37573
37569
|
// src/tools/marketShareAnalysis.ts
|
|
37574
|
-
var SOD_FIELDS = "CERT,
|
|
37570
|
+
var SOD_FIELDS = "CERT,NAMEFULL,DEPSUMBR,BRNUM,MSABR,STALPBR,YEAR";
|
|
37575
37571
|
var SOD_FETCH_LIMIT = 1e4;
|
|
37576
37572
|
function fmtNum(val) {
|
|
37577
37573
|
return Math.round(val).toLocaleString("en-US");
|
|
@@ -37624,12 +37620,12 @@ function getDefaultSodYear() {
|
|
|
37624
37620
|
return (/* @__PURE__ */ new Date()).getFullYear() - 1;
|
|
37625
37621
|
}
|
|
37626
37622
|
var MarketShareInputSchema = import_zod16.z.object({
|
|
37627
|
-
msa: import_zod16.z.
|
|
37628
|
-
|
|
37623
|
+
msa: import_zod16.z.number().int().positive().optional().describe(
|
|
37624
|
+
"FDIC MSABR numeric code for the Metropolitan Statistical Area (e.g., 19100 for Dallas-Fort Worth-Arlington, 42660 for Seattle-Tacoma-Bellevue). Use fdic_search_sod with MSABR to look up codes."
|
|
37629
37625
|
),
|
|
37630
|
-
|
|
37626
|
+
city: import_zod16.z.string().optional().describe('City name (e.g., "Austin"). Requires state.'),
|
|
37631
37627
|
state: import_zod16.z.string().length(2).optional().describe(
|
|
37632
|
-
"Two-letter state abbreviation (e.g., TX). Required when using
|
|
37628
|
+
"Two-letter state abbreviation (e.g., TX). Required when using city filter."
|
|
37633
37629
|
),
|
|
37634
37630
|
year: import_zod16.z.number().int().min(1994).optional().describe("SOD report year (1994-present). Defaults to most recent."),
|
|
37635
37631
|
cert: import_zod16.z.number().int().positive().optional().describe("Highlight a specific institution in the results.")
|
|
@@ -37639,17 +37635,21 @@ function registerMarketShareAnalysisTools(server) {
|
|
|
37639
37635
|
"fdic_market_share_analysis",
|
|
37640
37636
|
{
|
|
37641
37637
|
title: "Deposit Market Share Analysis",
|
|
37642
|
-
description: `Analyze deposit market share and concentration for an MSA or
|
|
37638
|
+
description: `Analyze deposit market share and concentration for an MSA or city market using FDIC Summary of Deposits (SOD) data.
|
|
37643
37639
|
|
|
37644
37640
|
Computes market share for all institutions in a geographic market, ranks them by deposits, and calculates the Herfindahl-Hirschman Index (HHI) for market concentration analysis per DOJ/FTC merger guidelines.
|
|
37645
37641
|
|
|
37642
|
+
Two entry modes:
|
|
37643
|
+
- MSA market: provide msa as the numeric MSABR code (e.g., msa: 19100 for Dallas-Fort Worth-Arlington, msa: 42660 for Seattle-Tacoma-Bellevue). Use fdic_search_sod to look up MSABR codes.
|
|
37644
|
+
- City market: provide city (branch city name, e.g., "Austin") and state (two-letter code, e.g., "TX").
|
|
37645
|
+
|
|
37646
37646
|
Output includes:
|
|
37647
37647
|
- Market overview with total deposits, institution count, and HHI classification
|
|
37648
|
-
- Optional highlighted institution showing rank and share
|
|
37648
|
+
- Optional highlighted institution showing rank and share (provide cert)
|
|
37649
37649
|
- Top institutions ranked by deposit market share
|
|
37650
37650
|
- Structured JSON for programmatic consumption
|
|
37651
37651
|
|
|
37652
|
-
Requires at least one of: msa, or
|
|
37652
|
+
Requires at least one of: msa (numeric MSABR code), or city + state.`,
|
|
37653
37653
|
inputSchema: MarketShareInputSchema,
|
|
37654
37654
|
annotations: {
|
|
37655
37655
|
readOnlyHint: true,
|
|
@@ -37663,17 +37663,17 @@ Requires at least one of: msa, or county + state.`,
|
|
|
37663
37663
|
const timeoutId = setTimeout(() => controller.abort(), ANALYSIS_TIMEOUT_MS);
|
|
37664
37664
|
const progressToken = extra._meta?.progressToken;
|
|
37665
37665
|
try {
|
|
37666
|
-
if (!rawParams.msa && !rawParams.
|
|
37666
|
+
if (!rawParams.msa && !rawParams.city) {
|
|
37667
37667
|
return formatToolError(
|
|
37668
37668
|
new Error(
|
|
37669
|
-
"At least one of 'msa' or '
|
|
37669
|
+
"At least one of 'msa' (numeric MSABR code) or 'city' (with 'state') must be provided."
|
|
37670
37670
|
)
|
|
37671
37671
|
);
|
|
37672
37672
|
}
|
|
37673
|
-
if (rawParams.
|
|
37673
|
+
if (rawParams.city && !rawParams.state) {
|
|
37674
37674
|
return formatToolError(
|
|
37675
37675
|
new Error(
|
|
37676
|
-
"'state' is required when using '
|
|
37676
|
+
"'state' is required when using 'city' filter."
|
|
37677
37677
|
)
|
|
37678
37678
|
);
|
|
37679
37679
|
}
|
|
@@ -37681,11 +37681,11 @@ Requires at least one of: msa, or county + state.`,
|
|
|
37681
37681
|
let filterStr;
|
|
37682
37682
|
let marketName;
|
|
37683
37683
|
if (rawParams.msa) {
|
|
37684
|
-
filterStr = `
|
|
37685
|
-
marketName = rawParams.msa
|
|
37684
|
+
filterStr = `MSABR:${rawParams.msa} AND YEAR:${year}`;
|
|
37685
|
+
marketName = `MSA ${rawParams.msa}`;
|
|
37686
37686
|
} else {
|
|
37687
|
-
filterStr = `
|
|
37688
|
-
marketName = `${rawParams.
|
|
37687
|
+
filterStr = `CITYBR:"${rawParams.city}" AND STALPBR:${rawParams.state} AND YEAR:${year}`;
|
|
37688
|
+
marketName = `${rawParams.city}, ${rawParams.state}`;
|
|
37689
37689
|
}
|
|
37690
37690
|
await sendProgressNotification(
|
|
37691
37691
|
server.server,
|
|
@@ -37720,7 +37720,7 @@ Requires at least one of: msa, or county + state.`,
|
|
|
37720
37720
|
);
|
|
37721
37721
|
const branches = records.map((r) => ({
|
|
37722
37722
|
cert: Number(r.CERT),
|
|
37723
|
-
name: String(r.
|
|
37723
|
+
name: String(r.NAMEFULL ?? ""),
|
|
37724
37724
|
deposits: typeof r.DEPSUMBR === "number" ? r.DEPSUMBR : 0
|
|
37725
37725
|
}));
|
|
37726
37726
|
const participants = computeMarketShare(branches);
|
|
@@ -37767,7 +37767,7 @@ Requires at least one of: msa, or county + state.`,
|
|
|
37767
37767
|
|
|
37768
37768
|
// src/tools/franchiseFootprint.ts
|
|
37769
37769
|
var import_zod17 = require("zod");
|
|
37770
|
-
var SOD_BRANCH_FIELDS = "CERT,
|
|
37770
|
+
var SOD_BRANCH_FIELDS = "CERT,NAMEFULL,DEPSUMBR,BRNUM,MSABR,STALPBR,YEAR";
|
|
37771
37771
|
var SOD_FETCH_LIMIT2 = 1e4;
|
|
37772
37772
|
var NON_MSA_LABEL = "Non-MSA / Rural";
|
|
37773
37773
|
function fmtNum2(val) {
|
|
@@ -37889,7 +37889,7 @@ Branches outside MSAs are grouped under "Non-MSA / Rural".`,
|
|
|
37889
37889
|
);
|
|
37890
37890
|
const byMarket = /* @__PURE__ */ new Map();
|
|
37891
37891
|
for (const rec of branchRecords) {
|
|
37892
|
-
const msaName = typeof rec.
|
|
37892
|
+
const msaName = typeof rec.MSABR === "number" && rec.MSABR !== 0 ? `MSA ${rec.MSABR}` : NON_MSA_LABEL;
|
|
37893
37893
|
const deposits = typeof rec.DEPSUMBR === "number" ? rec.DEPSUMBR : 0;
|
|
37894
37894
|
const existing = byMarket.get(msaName);
|
|
37895
37895
|
if (existing) {
|
package/dist/server.js
CHANGED
|
@@ -46,7 +46,7 @@ var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
|
46
46
|
var import_express2 = __toESM(require("express"));
|
|
47
47
|
|
|
48
48
|
// src/constants.ts
|
|
49
|
-
var VERSION = true ? "1.
|
|
49
|
+
var VERSION = true ? "1.17.0" : process.env.npm_package_version ?? "0.0.0-dev";
|
|
50
50
|
var FDIC_API_BASE_URL = "https://banks.data.fdic.gov/api";
|
|
51
51
|
var CHARACTER_LIMIT = 5e4;
|
|
52
52
|
var DEFAULT_FDIC_MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
@@ -32701,19 +32701,16 @@ Common filter examples:
|
|
|
32701
32701
|
- Branches in a state: STALPBR:CA
|
|
32702
32702
|
- Branches in a city: CITYBR:"Austin"
|
|
32703
32703
|
- High-deposit branches: DEPSUMBR:[1000000 TO *]
|
|
32704
|
-
- By metro area:
|
|
32704
|
+
- By metro area (MSA code): MSABR:19100
|
|
32705
32705
|
|
|
32706
32706
|
Key returned fields:
|
|
32707
32707
|
- YEAR: Report year (as of June 30)
|
|
32708
32708
|
- CERT: FDIC Certificate Number
|
|
32709
32709
|
- BRNUM: Branch number (0 = main office)
|
|
32710
|
-
-
|
|
32711
|
-
- NAMEFULL: Full branch name
|
|
32710
|
+
- NAMEFULL: Branch or institution name
|
|
32712
32711
|
- ADDRESBR, CITYBR, STALPBR, ZIPBR: Branch address
|
|
32713
|
-
- CNTYBR: County
|
|
32714
32712
|
- DEPSUMBR: Total deposits at branch ($thousands)
|
|
32715
|
-
- MSABR: Metropolitan Statistical Area code
|
|
32716
|
-
- MSANAMEBR: MSA name
|
|
32713
|
+
- MSABR: Metropolitan Statistical Area code (numeric; 0 = non-MSA)
|
|
32717
32714
|
- LATITUDE, LONGITUDE: Coordinates
|
|
32718
32715
|
|
|
32719
32716
|
Args:
|
|
@@ -34654,7 +34651,7 @@ var CANONICAL_FIELDS = [
|
|
|
34654
34651
|
"SC",
|
|
34655
34652
|
"ASSTLT",
|
|
34656
34653
|
"VOLIAB",
|
|
34657
|
-
"
|
|
34654
|
+
"OTHBRF"
|
|
34658
34655
|
].join(",");
|
|
34659
34656
|
var FIELD_ALIASES = {
|
|
34660
34657
|
IDT1CER: ["REPTE9"],
|
|
@@ -34731,7 +34728,7 @@ function extractCanonicalMetrics(raw) {
|
|
|
34731
34728
|
const sc = asNumber(raw.SC);
|
|
34732
34729
|
const asstlt = asNumber(raw.ASSTLT);
|
|
34733
34730
|
const voliab = asNumber(raw.VOLIAB);
|
|
34734
|
-
const
|
|
34731
|
+
const othbrf = asNumber(raw.OTHBRF);
|
|
34735
34732
|
const metrics = {
|
|
34736
34733
|
// Amounts
|
|
34737
34734
|
totalAssets: direct("totalAssets", "ASSET"),
|
|
@@ -34800,8 +34797,8 @@ function extractCanonicalMetrics(raw) {
|
|
|
34800
34797
|
),
|
|
34801
34798
|
borrowedFundsToAssetsPct: derived(
|
|
34802
34799
|
"borrowedFundsToAssetsPct",
|
|
34803
|
-
() => safeDivPct(
|
|
34804
|
-
"
|
|
34800
|
+
() => safeDivPct(othbrf, asset),
|
|
34801
|
+
"OTHBRF / ASSET * 100"
|
|
34805
34802
|
)
|
|
34806
34803
|
};
|
|
34807
34804
|
for (const [key, value] of Object.entries(metrics)) {
|
|
@@ -36692,7 +36689,6 @@ var CREDIT_FIELDS = [
|
|
|
36692
36689
|
"LNCI",
|
|
36693
36690
|
"LNCON",
|
|
36694
36691
|
"LNAG",
|
|
36695
|
-
"LNOTH",
|
|
36696
36692
|
"LNREDOM",
|
|
36697
36693
|
"LNREFOR"
|
|
36698
36694
|
].join(",");
|
|
@@ -37585,7 +37581,7 @@ function buildMarketConcentration(participants) {
|
|
|
37585
37581
|
}
|
|
37586
37582
|
|
|
37587
37583
|
// src/tools/marketShareAnalysis.ts
|
|
37588
|
-
var SOD_FIELDS = "CERT,
|
|
37584
|
+
var SOD_FIELDS = "CERT,NAMEFULL,DEPSUMBR,BRNUM,MSABR,STALPBR,YEAR";
|
|
37589
37585
|
var SOD_FETCH_LIMIT = 1e4;
|
|
37590
37586
|
function fmtNum(val) {
|
|
37591
37587
|
return Math.round(val).toLocaleString("en-US");
|
|
@@ -37638,12 +37634,12 @@ function getDefaultSodYear() {
|
|
|
37638
37634
|
return (/* @__PURE__ */ new Date()).getFullYear() - 1;
|
|
37639
37635
|
}
|
|
37640
37636
|
var MarketShareInputSchema = import_zod16.z.object({
|
|
37641
|
-
msa: import_zod16.z.
|
|
37642
|
-
|
|
37637
|
+
msa: import_zod16.z.number().int().positive().optional().describe(
|
|
37638
|
+
"FDIC MSABR numeric code for the Metropolitan Statistical Area (e.g., 19100 for Dallas-Fort Worth-Arlington, 42660 for Seattle-Tacoma-Bellevue). Use fdic_search_sod with MSABR to look up codes."
|
|
37643
37639
|
),
|
|
37644
|
-
|
|
37640
|
+
city: import_zod16.z.string().optional().describe('City name (e.g., "Austin"). Requires state.'),
|
|
37645
37641
|
state: import_zod16.z.string().length(2).optional().describe(
|
|
37646
|
-
"Two-letter state abbreviation (e.g., TX). Required when using
|
|
37642
|
+
"Two-letter state abbreviation (e.g., TX). Required when using city filter."
|
|
37647
37643
|
),
|
|
37648
37644
|
year: import_zod16.z.number().int().min(1994).optional().describe("SOD report year (1994-present). Defaults to most recent."),
|
|
37649
37645
|
cert: import_zod16.z.number().int().positive().optional().describe("Highlight a specific institution in the results.")
|
|
@@ -37653,17 +37649,21 @@ function registerMarketShareAnalysisTools(server) {
|
|
|
37653
37649
|
"fdic_market_share_analysis",
|
|
37654
37650
|
{
|
|
37655
37651
|
title: "Deposit Market Share Analysis",
|
|
37656
|
-
description: `Analyze deposit market share and concentration for an MSA or
|
|
37652
|
+
description: `Analyze deposit market share and concentration for an MSA or city market using FDIC Summary of Deposits (SOD) data.
|
|
37657
37653
|
|
|
37658
37654
|
Computes market share for all institutions in a geographic market, ranks them by deposits, and calculates the Herfindahl-Hirschman Index (HHI) for market concentration analysis per DOJ/FTC merger guidelines.
|
|
37659
37655
|
|
|
37656
|
+
Two entry modes:
|
|
37657
|
+
- MSA market: provide msa as the numeric MSABR code (e.g., msa: 19100 for Dallas-Fort Worth-Arlington, msa: 42660 for Seattle-Tacoma-Bellevue). Use fdic_search_sod to look up MSABR codes.
|
|
37658
|
+
- City market: provide city (branch city name, e.g., "Austin") and state (two-letter code, e.g., "TX").
|
|
37659
|
+
|
|
37660
37660
|
Output includes:
|
|
37661
37661
|
- Market overview with total deposits, institution count, and HHI classification
|
|
37662
|
-
- Optional highlighted institution showing rank and share
|
|
37662
|
+
- Optional highlighted institution showing rank and share (provide cert)
|
|
37663
37663
|
- Top institutions ranked by deposit market share
|
|
37664
37664
|
- Structured JSON for programmatic consumption
|
|
37665
37665
|
|
|
37666
|
-
Requires at least one of: msa, or
|
|
37666
|
+
Requires at least one of: msa (numeric MSABR code), or city + state.`,
|
|
37667
37667
|
inputSchema: MarketShareInputSchema,
|
|
37668
37668
|
annotations: {
|
|
37669
37669
|
readOnlyHint: true,
|
|
@@ -37677,17 +37677,17 @@ Requires at least one of: msa, or county + state.`,
|
|
|
37677
37677
|
const timeoutId = setTimeout(() => controller.abort(), ANALYSIS_TIMEOUT_MS);
|
|
37678
37678
|
const progressToken = extra._meta?.progressToken;
|
|
37679
37679
|
try {
|
|
37680
|
-
if (!rawParams.msa && !rawParams.
|
|
37680
|
+
if (!rawParams.msa && !rawParams.city) {
|
|
37681
37681
|
return formatToolError(
|
|
37682
37682
|
new Error(
|
|
37683
|
-
"At least one of 'msa' or '
|
|
37683
|
+
"At least one of 'msa' (numeric MSABR code) or 'city' (with 'state') must be provided."
|
|
37684
37684
|
)
|
|
37685
37685
|
);
|
|
37686
37686
|
}
|
|
37687
|
-
if (rawParams.
|
|
37687
|
+
if (rawParams.city && !rawParams.state) {
|
|
37688
37688
|
return formatToolError(
|
|
37689
37689
|
new Error(
|
|
37690
|
-
"'state' is required when using '
|
|
37690
|
+
"'state' is required when using 'city' filter."
|
|
37691
37691
|
)
|
|
37692
37692
|
);
|
|
37693
37693
|
}
|
|
@@ -37695,11 +37695,11 @@ Requires at least one of: msa, or county + state.`,
|
|
|
37695
37695
|
let filterStr;
|
|
37696
37696
|
let marketName;
|
|
37697
37697
|
if (rawParams.msa) {
|
|
37698
|
-
filterStr = `
|
|
37699
|
-
marketName = rawParams.msa
|
|
37698
|
+
filterStr = `MSABR:${rawParams.msa} AND YEAR:${year}`;
|
|
37699
|
+
marketName = `MSA ${rawParams.msa}`;
|
|
37700
37700
|
} else {
|
|
37701
|
-
filterStr = `
|
|
37702
|
-
marketName = `${rawParams.
|
|
37701
|
+
filterStr = `CITYBR:"${rawParams.city}" AND STALPBR:${rawParams.state} AND YEAR:${year}`;
|
|
37702
|
+
marketName = `${rawParams.city}, ${rawParams.state}`;
|
|
37703
37703
|
}
|
|
37704
37704
|
await sendProgressNotification(
|
|
37705
37705
|
server.server,
|
|
@@ -37734,7 +37734,7 @@ Requires at least one of: msa, or county + state.`,
|
|
|
37734
37734
|
);
|
|
37735
37735
|
const branches = records.map((r) => ({
|
|
37736
37736
|
cert: Number(r.CERT),
|
|
37737
|
-
name: String(r.
|
|
37737
|
+
name: String(r.NAMEFULL ?? ""),
|
|
37738
37738
|
deposits: typeof r.DEPSUMBR === "number" ? r.DEPSUMBR : 0
|
|
37739
37739
|
}));
|
|
37740
37740
|
const participants = computeMarketShare(branches);
|
|
@@ -37781,7 +37781,7 @@ Requires at least one of: msa, or county + state.`,
|
|
|
37781
37781
|
|
|
37782
37782
|
// src/tools/franchiseFootprint.ts
|
|
37783
37783
|
var import_zod17 = require("zod");
|
|
37784
|
-
var SOD_BRANCH_FIELDS = "CERT,
|
|
37784
|
+
var SOD_BRANCH_FIELDS = "CERT,NAMEFULL,DEPSUMBR,BRNUM,MSABR,STALPBR,YEAR";
|
|
37785
37785
|
var SOD_FETCH_LIMIT2 = 1e4;
|
|
37786
37786
|
var NON_MSA_LABEL = "Non-MSA / Rural";
|
|
37787
37787
|
function fmtNum2(val) {
|
|
@@ -37903,7 +37903,7 @@ Branches outside MSAs are grouped under "Non-MSA / Rural".`,
|
|
|
37903
37903
|
);
|
|
37904
37904
|
const byMarket = /* @__PURE__ */ new Map();
|
|
37905
37905
|
for (const rec of branchRecords) {
|
|
37906
|
-
const msaName = typeof rec.
|
|
37906
|
+
const msaName = typeof rec.MSABR === "number" && rec.MSABR !== 0 ? `MSA ${rec.MSABR}` : NON_MSA_LABEL;
|
|
37907
37907
|
const deposits = typeof rec.DEPSUMBR === "number" ? rec.DEPSUMBR : 0;
|
|
37908
37908
|
const existing = byMarket.get(msaName);
|
|
37909
37909
|
if (existing) {
|