# Sanctions Screening API (`zinin/sanctions-screening`) Actor

Screen names against the live OFAC SDN and EU consolidated sanctions lists. Keyless, no login — flags potential hits with a match score so you can review before onboarding a client or counterparty.

- **URL**: https://apify.com/zinin/sanctions-screening.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 result founds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Sanctions Screening — OFAC & EU List Checker

Check a name against the two sanctions lists that actually matter before you onboard a client, counterparty or vendor — the **US Treasury OFAC SDN list** (including its published aliases) and the **EU consolidated financial sanctions list** — read live from their own public exports. No API key, no login, no third-party screening vendor.

### The problem

Anyone onboarding clients, running KYC/KYB, or vetting a new counterparty needs a sanctions check. Commercial screening tools (Refinitiv World-Check, Dow Jones, ComplyAdvantage) run hundreds to thousands of dollars a month and are built for compliance teams, not a one-off check or a lightweight internal tool. The underlying data — OFAC's SDN list and the EU's consolidated list — is public and free; this Actor reads it directly.

**This is a preliminary screening tool, not a compliance determination.** Every row carries that disclaimer. Sanctions screening in any serious compliance workflow always ends with human review of the hits — this Actor is built to make that review list, not replace it.

### What you get

- **Two official lists, screened together**: OFAC SDN (US Treasury) and the EU consolidated financial sanctions list, both fetched fresh at the start of every run — never a stale cache.
- **OFAC's published aliases are screened too**, not just primary names. OFAC's own guidance is explicit that checking primary names alone is an incomplete screen — a sanctioned party is routinely listed, and searched for, under an a.k.a./f.k.a./n.k.a. spelling. This Actor loads OFAC's own alias export alongside the primary list.
- **Honest partial-coverage flag.** If one of the two source lists fails to load for a run, every row carries `listsComplete: false` so you know exactly what wasn't checked — rather than a clean-looking row that quietly skipped half the screen.
- **Ranked candidates, not one silent guess.** `matches` returns every candidate above your score threshold (up to 25, ranked), because on a common name picking one match and hiding the rest is worse than showing you the list.
- **Tunable sensitivity.** `minScore` defaults soft, on purpose — a missed hit is worse than a false one — and it's yours to tighten.
- Runs on Apify: schedule it, monitor it, call it from the API or the MCP server, export to JSON/CSV/Excel, or push straight into your own pipeline.

### Sources

- **OFAC SDN list + aliases** (US Treasury) — `sanctionslistservice.ofac.treas.gov`, the same SDN.CSV and ALT.CSV flat-file exports OFAC itself publishes for download.
- **EU consolidated list** (financial sanctions) — `webgate.ec.europa.eu`, the EU's own public CSV export, names and aliases both.

Both are fetched fresh on every run — no scraping, no unofficial mirrors.

### Matching

Names are normalized (uppercase, diacritics stripped, punctuation removed) and compared by token overlap: a match score is the fraction of the *query's* words found in a candidate entity's name (matched against its primary name or any of its aliases, whichever hits). A single distinctive word matched inside a longer name still counts as a strong hit — e.g. checking "Wagner" against an entry like *"PRIVATE MILITARY COMPANY 'WAGNER'"* scores 1.0. This is deliberate: **a missed hit is worse than a false one**, so the default threshold (`minScore: 0.5`) is soft, and it's tunable per your own risk tolerance.

Common/ambiguous names will produce more hits now that aliases are in scope, not fewer — that's expected of any sanctions screen and is why `matches` returns everything above the threshold (up to 25, ranked by score) for you to review, rather than silently picking one.

### How to run it

1. Click **Try for free** — no card needed on the free plan.
2. Paste names into **Names**, one per row — people or companies.
3. Press **Start** and read the results from the dataset — UI, API or webhook.

### Pricing

Pay-per-event: **$0.005 per run start + $0.005 per name screened**. 100 names cost about **$0.51**; 1,000 names about **$5.01** — that's the normal case, both lists loaded.

If one of the two source lists fails to load for a run, every row that run is flagged `listsComplete: false`. In that state a **match is still charged** as usual, but a **"no match" verdict is not charged** — because that's the case where we ourselves are telling you not to treat the answer as clean. You only pay for an answer this Actor stands behind. If both lists fail to load entirely, every name in the run returns `found: false` with the reason, and none of it is charged.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `names` | array of strings | Person or company names to screen against the OFAC SDN (+aliases) and EU consolidated sanctions lists, one per row. Up to 100. |
| `minScore` | number | Minimum score (0–1) for a candidate to be reported. Default `0.5`. Lower = more (weaker) hits reported. |
| `maxConcurrency` | integer | Parallelism (1–20, default 5). |

```json
{
  "names": ["Yevgeniy Prigozhin", "Acme Trading LLC"]
}
```

### Output

One dataset row per name. This is a real row from a real run, `matches` trimmed to the top few of 25:

```json
{
  "input": "Yevgeniy Prigozhin",
  "found": true,
  "match": true,
  "matchCount": 25,
  "matches": [
    { "listName": "OFAC SDN", "entityName": "PRIGOZHIN, Yevgeniy Viktorovich", "entityType": "individual", "program": "UKRAINE-EO13661, CYBER2, ELECTION-EO13848, RUSSIA-EO14024", "matchedName": "PRIGOZHIN, Yevgeniy Viktorovich", "matchedNameType": "primary", "score": 1 },
    { "listName": "EU Consolidated", "entityName": "Yevgeniy Viktorovich PRIGOZHIN", "entityType": "individual", "program": "UKR", "matchedName": "Yevgeniy Viktorovich PRIGOZHIN", "matchedNameType": "primary", "score": 1 },
    { "listName": "OFAC SDN", "entityName": "BALYTSKYI, Yevhen Vitaliiovych", "entityType": "individual", "program": "RUSSIA-EO14024", "matchedName": "BALITSKIY, Yevgeniy", "matchedNameType": "aka", "score": 0.5 },
    "…"
  ],
  "highestScore": 1,
  "matchedName": "PRIGOZHIN, Yevgeniy Viktorovich",
  "matchedNameType": "primary",
  "listsChecked": ["OFAC SDN", "EU Consolidated"],
  "listsComplete": true,
  "disclaimer": "Screening signal only — NOT a legal/compliance determination; verify against official sources.",
  "summary": "Yevgeniy Prigozhin — 25 potential matches (highest score 1). Top hit: PRIGOZHIN, Yevgeniy Viktorovich [OFAC SDN], program UKRAINE-EO13661, CYBER2, ELECTION-EO13848, RUSSIA-EO14024.",
  "checkedAt": "2026-07-26T15:09:32.370Z"
}
```

| Field | Description |
|-------|-------------|
| `input` | The name you passed |
| `found` | Whether screening completed (`false` only if both lists failed to load) |
| `match` | Whether any candidate scored at or above `minScore` |
| `matchCount` | How many candidates cleared the threshold (capped at 25 in `matches`) |
| `matches` | Ranked list of candidates: `listName`, `entityName`, `entityType`, `program`, `score`, plus `matchedName`/`matchedNameType` when the hit came through an alias rather than the entity's primary name |
| `highestScore` | Score of the top match (0 if none) |
| `matchedName` / `matchedNameType` | The top hit's own name and whether it was the entity's primary name or an alias (`aka`/`fka`/`nka`) |
| `listsChecked` | Which source lists actually loaded and were screened this run |
| `listsComplete` | `false` when one of the two lists failed to load — a "no match" row in that state is not a clean bill of health, and is not billed either |
| `disclaimer` | Always present — this is a signal, not a determination |
| `summary` | Human-readable one-liner, notes an alias match by name when that's what fired |

#### Need the rest of the picture?

These run on the same account, take the same shape of input and bill the same way, so they slot into an existing pipeline without new plumbing.

| Actor | What it does |
|---|---|
| [Company Registry Enricher](https://apify.com/zinin/company-registry-enricher) | Turn a company name, LEI or UK company number into an official registry card: legal name, status,… |
| [Gov Tender Radar](https://apify.com/zinin/gov-tender-radar) | Search EU public-sector tenders (TED Europa) by keyword or CPV code, optionally filtered by buyer country |
| [AI Crawler Access Checker](https://apify.com/zinin/ai-crawler-access-checker) | Check which AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended & more) can access your website |
| [B2B Lead Enricher](https://apify.com/zinin/b2b-lead-enricher) | Turn a list of company websites into sales-qualified lead cards: detected tech stack, a rough revenue… |
| [Clinical Trials Monitor](https://apify.com/zinin/clinical-trials-monitor) | Watch conditions, drugs or sponsors for new and updated clinical trials |

### FAQ / Limitations

**Does it need an API key or login?** No — both source lists are public, keyless exports.

**How fresh is the data?** Both lists are downloaded fresh at the start of every run, straight from OFAC and the EU — not cached.

**Is this legally sufficient for KYC/AML?** No single automated tool is. This is a preliminary screening tool, not a compliance determination — use it to build your review list, not as your only control, and always verify a hit against the official OFAC/EU sources before acting on it.

**Does it catch aliases (a.k.a. names)?** Yes. OFAC's own alias export (a.k.a./f.k.a./n.k.a.) and the EU list's alias rows are both loaded and screened alongside primary names — a hit through an alias is marked as such via `matchedNameType`. Free-text alias mentions buried in OFAC's unstructured remarks field are not indexed separately.

**What if a name is very common?** Expect more hits now that aliases are in scope, not fewer — that's the nature of sanctions screening, not a bug. Review the ranked `matches` list; lower `minScore` catches more, higher `minScore` narrows to only near-exact hits.

**What does `listsComplete: false` mean for what I'm charged?** If a source list failed to load, a "no match" answer for that run is not charged — an unverifiable clean result is free. A match, or any result from a run where both lists loaded, is charged as usual.

**Can I call it from an AI agent?** Yes — it's a standard Apify Actor, callable via the Apify API or the Apify MCP server.

**What this is NOT.** Not a legal or compliance determination, and not a substitute for your own KYC/AML program — it is an inexpensive way to build the review list a human then checks against the official sources.

Found a wrong result, or need a source list we don't cover? Open an issue on this Actor's page.

***

Built by [zinin](https://apify.com/zinin). Questions? Telegram [@timzinin](https://t.me/timzinin).

# Actor input Schema

## `names` (type: `array`):

Person or company names to screen against the OFAC SDN and EU consolidated sanctions lists, one per row.

## `minScore` (type: `number`):

Only report candidate matches scoring at or above this (0 = report everything, 1 = only a full token match). Kept soft on purpose — a missed hit is worse than a false one. At the default 0.5, a two-word name matching on one word still surfaces as a low-confidence hit.

## `maxConcurrency` (type: `integer`):

How many names to screen in parallel.

## Actor input object example

```json
{
  "names": [
    "Yevgeniy Prigozhin",
    "Acme Trading LLC"
  ],
  "minScore": 0.5,
  "maxConcurrency": 5
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "names": [
        "Yevgeniy Prigozhin",
        "Acme Trading LLC"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/sanctions-screening").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "names": [
        "Yevgeniy Prigozhin",
        "Acme Trading LLC",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("zinin/sanctions-screening").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "names": [
    "Yevgeniy Prigozhin",
    "Acme Trading LLC"
  ]
}' |
apify call zinin/sanctions-screening --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=zinin/sanctions-screening",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Sanctions Screening API",
        "description": "Screen names against the live OFAC SDN and EU consolidated sanctions lists. Keyless, no login — flags potential hits with a match score so you can review before onboarding a client or counterparty.",
        "version": "0.1",
        "x-build-id": "VkdUpf8dOzIpVfbOp"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/zinin~sanctions-screening/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-zinin-sanctions-screening",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/zinin~sanctions-screening/runs": {
            "post": {
                "operationId": "runs-sync-zinin-sanctions-screening",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/zinin~sanctions-screening/run-sync": {
            "post": {
                "operationId": "run-sync-zinin-sanctions-screening",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "names"
                ],
                "properties": {
                    "names": {
                        "title": "Names",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Person or company names to screen against the OFAC SDN and EU consolidated sanctions lists, one per row.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "minScore": {
                        "title": "Minimum match score",
                        "minimum": 0,
                        "maximum": 1,
                        "type": "number",
                        "description": "Only report candidate matches scoring at or above this (0 = report everything, 1 = only a full token match). Kept soft on purpose — a missed hit is worse than a false one. At the default 0.5, a two-word name matching on one word still surfaces as a low-confidence hit.",
                        "default": 0.5
                    },
                    "maxConcurrency": {
                        "title": "Max concurrency",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "How many names to screen in parallel.",
                        "default": 5
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
