dumbtv
dumbtv takes the ads, screen tracking and update nags out of your Fire TV over ADB. No root, none of your apps touched, every step can be undone. Free and open source.
Mask personal data and secrets before they reach an LLM, and put them back on the way out. Local detection, reversible in-memory vault.
SecurityPython · TypeScriptGitHub @lBrothOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Mask personal data and secrets before they reach an LLM, and put them back on the way out. Runs locally: a GLiNER ONNX model, recognizers and a reversible in-memory vault. Claude Code mod, gateway and npm library. Apache-2.0.
Taken from the repository README
Loading the full README.
Read the full README ↗nullpii hides personal data and secrets before your text goes to an LLM, and puts the real values back in the reply. It runs on your machine. A fine-tuned GLiNER model and a set of pattern recognizers find the values, and an in-memory vault swaps each one for a placeholder and back.
Status: before 1.0, so the API can still change between minor versions. nullpii replaces values with placeholders it can reverse, and it misses some values. This is pseudonymisation, not anonymisation, and not a compliance certification.
At the prompt of a Claude Code session (2.1.287 or later, with Node 22 or later):
/plugin marketplace add lBroth/[email protected]
/plugin install nullpii@nullpii
When Claude Code asks for the plugin's options, paste a new token from openssl rand -hex 32 into Sidecar token, then restart Claude Code. The mod starts a local nullpii sidecar, which downloads the model (1.2 GB) on its first start. Get started has a prompt that lets Claude Code do this for you, and how to check that it works. The full reference is under Claude Code mod.
npm install nullpii onnxruntime-node
You need Node 22 or later. On first use nullpii downloads the model from Hugging Face into ~/.cache/nullpii/: 1.2 GB in fp32, or 0.6 GB in fp16 on CUDA. It checks every file it downloads against a SHA-256 written into the library. To download the model ahead of time, run npx nullpii prefetch, or point NULLPII_MODEL_DIR at a copy you put there yourself. nullpii does not check the files in NULLPII_MODEL_DIR: compare them with the hashes in the model card.
On Linux x64, the install script of onnxruntime-node also downloads its CUDA support from NuGet, without checking a hash. The CPU runtime is already in the npm package, so on a machine without an NVIDIA GPU, skip that download:
ONNXRUNTIME_NODE_INSTALL=skip npm install nullpii onnxruntime-node
import { NullPii, wrapForLLM } from 'nullpii';
const np = new NullPii();
const safe = await np.sanitize('Email John Smith at [email protected] about SSN 123-45-6789');
// safe.sanitized → 'Email {{PII_PRIVATE_PERSON_0_…}} at {{PII_PRIVATE_EMAIL_0_…}} about SSN {{PII_ACCOUNT_NUMBER_0_…}}'
// Optional: tell the model to keep the placeholders as they are
const prompt = wrapForLLM(safe, 'Translate to Italian');
// … your LLM call: OpenAI, Anthropic, Gemini, Ollama, anything …
const reply = await yourLlm(prompt); // returns text with the placeholders
const back = np.restore(reply, safe.sessionId);
// back.restored → the reply with the real values
np.destroySession(safe.sessionId); // drop the session's values from memory
await np.dispose(); // when you are done with the engine
Keep one engine for the whole life of your process: loading the model (about 1.2 GB) is the slowest step. How the vault works:
Streaming restore, for replies that arrive in chunks:
import { RestoreStream } from 'nullpii';
const stream = new RestoreStream(np, safe.sessionId);
for await (const chunk of yourLlmStream(prompt)) process.stdout.write(stream.push(chunk));
process.stdout.write(stream.end().restored);
safe.modelUnscannedWords counts the words the model could not read, such as one very long minified blob. The recognizers still scanned them.
One JSON file sets the policy for the library, the CLI, the gateway and the Claude Code mod. It is ~/.config/nullpii/config.json, or the file that NULLPII_CONFIG names.
{
"disabledCategories": ["private_organization", "private_occupation"],
"categories": { "private_url": "ask" },
"urlAllowlist": { "hosts": { "*.github.com": "host" } }
}
disabledCategories: the categories left readable. It replaces the default list: dates, companies, jobs, honorifics, and demographic and sensitive attributes. [] masks every category.categories: a mode for each category you name: mask, ask or off (readable). It wins over disabledCategories for those categories. ask works in the Claude Code mod: before your prompt is sent, the mod asks you about each value of that category. The value stays masked unless you choose to send it readable (see below).categoryThresholds, threshold: confidence cuts between 0 and 1. Lower masks more.urlAllowlist: how much of a clean URL stays readable on each host: full, host or mask. Use "none" to mask every URL. By default, code hosts, package registries and documentation stay readable. A URL with a credential in its query is always masked. A code-host URL can name a person or a private repository (github.com/<user>/<repo>); if that matters to you, set that host to host or mask.restoreTools: the tools whose arguments get real values back (gateway and mod).npx nullpii config checks the file and prints it. In code, load it with resolveConfigFile() and toEngineConfig(), or pass the same options to new NullPii({...}).
An HTTP proxy for the Anthropic Messages API (/v1/messages) and the OpenAI Chat Completions API (/v1/chat/completions). Point your client's base URL at it and work as before. It masks requests before they leave your machine, and it restores responses, streaming included, before they reach you.
git clone https://github.com/lBroth/nullpii.git && cd nullpii
docker compose -f examples/claude-code/docker-compose.yml up -d # listens on 127.0.0.1:8787
export ANTHROPIC_BASE_URL=http://127.0.0.1:8787
claude
The first request downloads the model (1.2 GB) into the container's cache volume and waits for it. examples/claude-code shows how to download it first. The image is also published as ghcr.io/lbroth/nullpii-gateway.
Your API key or Claude subscription login passes through unchanged. For OpenAI Chat Completions clients (the OpenAI SDKs, Aider, LiteLLM), set OPENAI_BASE_URL=http://127.0.0.1:8787/v1. The gateway does not proxy the Responses API, so the Codex CLI, which refuses to speak Chat Completions, cannot use it.
restoreTools. By default these are the file tools that run on your machine (Read, Edit, Write, Grep, Glob, …).Bash, PowerShell, …) never gets a real value back, whatever the policy says. Web and MCP tools, and tools the upstream runs itself, keep the placeholders too.127.0.0.1.PUT /v1/sidecar/policy, which the mod's /pii uses) applies to the running gateway at once.Details, the full list of scanned fields, and the sidecar API: packages/gateway. A worked Claude Code setup: examples/claude-code.
packages/claude-code-mod masks inside Claude Code itself:
CLAUDE.md before Claude reads them.claude -p, where no one can answer, such a call is refused unless Allow all was given, and a shell command never gets one./pii shows the counts and the policy in effect.The mod talks to the gateway's local sidecar. If no sidecar answers, it starts one for the session. If it cannot reach the sidecar, it sends nothing unmasked.
/pii changes the policy at once and saves the change in the policy file:
/pii preset agent (the default), /pii preset secrets (secrets only) or /pii preset all (every category). /pii reset goes back to agent./pii mask <category…>, /pii allow <category…> (readable) and /pii ask <category…> set one mode for each category you name.For a category in ask mode, the mod asks you about each of its values in your own prompt before the prompt is sent. You can mask it, send it readable, or send it readable and stop asking for that category. If you close the question, or no one can answer it (claude -p), the value stays masked. Apart from that, values in a tool's result follow the policy without a question; the mod asks before a masked value goes out in clear to a tool outside the policy's list, or a masked object key of such a tool's result goes to Claude in clear (Ask before a value leaves). Categories: person, email, phone, address, url, ip, mac, location, passport, license, vehicle, account, secret, date, organization, occupation, demographic, sensitive, title.
To install it you need a sidecar token (set up; the mod starts the gateway itself when none answers). Then, at the prompt of a Claude Code session:
/plugin marketplace add lBroth/[email protected]
/plugin install nullpii@nullpii
Or from a shell: claude plugin marketplace add lBroth/[email protected], then claude plugin install nullpii@nullpii. The @v0.5.4 pins the mod to this release. Without it you get whatever main holds.
| Label | Examples | Source |
|---|---|---|
private_person | names | model |
private_email | emails | model + regex |
private_phone | international (with +) and IT / FR / ES formats; US numbers without +1 by the model only | model + regex |
private_address | street, city, postcode | model |
private_date | birth and other personal dates | model |
private_url | http(s)://, www. | model + regex |
private_ip | IPv4, IPv6 (private, documentation and loopback ranges left alone) | regex |
private_mac | MAC addresses (broadcast and multicast left alone) | regex |
private_passport | US / IT / FR / ES / DE / UK, and a context-anchored generic form | model + regex |
private_driver_license | US states, IT and EU countries, context-anchored | model + regex |
private_vehicle_id | VIN (checksum), plates IT / FR / DE / UK / ES / US | model + regex |
private_geolocation | coordinate pairs (range-checked), DMS notation | model + regex |
account_number | IBAN (mod-97), cards (Luhn), SSN, crypto addresses, national and tax ids (DNI, CPF, EIN, codice fiscale, Partita IVA), Medicare, NPI, insurance policy, IMEI; medical record numbers by the model only | model + regex (validated) |
secret | API keys (AWS, GitHub, OpenAI, Anthropic, Stripe and 30+ more), JWTs, private keys, passwords and PINs in context, base64-wrapped values | model + regex + base64 |
private_organization | employers, company names | model |
private_occupation | job titles, employment status, education | model |
private_demographic |
By default nullpii masks what is risky to give to a coding agent's model: names, contact details and addresses, ids and accounts, secrets. It leaves readable what the agent needs and what rarely identifies someone on its own: private_date (the model cannot tell a birth date from a deadline) and the last five categories in the table. DEFAULT_DISABLED_CATEGORIES lists these six. Health, religion or sexual orientation written in your text reaches the model by default; /pii mask sensitive (or disabledCategories) changes that. Set disabledCategories to change the list; [] masks every category. nullpii finds values that are written out. It does not infer a health condition or a belief from indirect wording. Add your own patterns with np.addRecognizer({ id, pattern, label, confidence, validate? }).
nullpii decodes hidden input before it looks for values: Unicode look-alikes and fullwidth characters, zero-width characters, spaced-out text, percent-encoding (two levels deep), numeric HTML entities (@, @), and base64 blobs.
Every test was fixed before the run, except one AB-1 scoring rule changed afterwards (see below). The results include the cases nullpii loses. How the numbers are made: METHOD.md.
AB-1 checks two things in a coding agent's traffic. What the agent must not give to the model (secrets, contact details and addresses, ids and account numbers, names) should be masked. What it needs to read (dates, versions, paths, hostnames of public services, placeholders, code identifiers) should stay readable. Each item is scored: the leak rate on items that must be hidden, and the keep rate on items that must stay readable. There is no combined score. Every tool ran on the frozen test set, and the run was redone once for every tool after an adapter fix; nullpii's rows are from the release build, which includes three rules found in end-to-end testing (below). Method and limits: AB-1 in METHOD.md.
id, uid, _postman_id) or after no key, while nullpii, and AB-1's own specification, treat a UUID as an id to keep readable. Without them nullpii lets 13.0% through, the fewest of all tools (an analysis made after the scores were read). On secrets in GitHub issues, openai's privacy-filter lets fewer through (8.2% against 11.5%), and nullpii keeps more readable (77.2% against 74.6%).strict-rule/).966 documents, 3,386 items that must be masked and 5,676 that must stay readable.
| Tool | Leak rate | Keep rate | Docs with a leak | nullpii − tool, leak | nullpii − tool, keep |
|---|---|---|---|---|---|
| rizzo-pii (tuned, +agent) | 8.1% | 44.5% | 25.1% | [−0.0, +2.6] | [+38.7, +43.4] |
| nullpii 0.5 (agent default) | 9.5% | 85.4% | 27.0% | — | — |
| openai privacy-filter (tuned, +agent) | 14.5% | 77.9% | 33.6% | [−6.9, −3.2] | [+5.0, +9.9] |
| OpenMed PII Large (tuned, +agent) | 15.7% | 82.2% | 39.7% | [−8.2, −4.4] | [+1.6, +5.0] |
| gliner-pii-large (tuned, +agent) | 15.9% | 85.5% | 37.8% | [−8.5, −4.4] | [−1.9, +1.6] |
| nemotron-pii, NVIDIA's server (tuned, +agent) | 16.0% | 75.8% | 42.8% | [−8.2, −4.9] | [+7.7, +11.9] |
| OpenMed PII Small (tuned, +agent) | 16.1% | 83.0% | 40.4% | [−8.3, −4.9] | [+0.8, +4.1] |
| gliner-stream-pii (tuned, +agent) | 16.4% | 67.5% | 43.3% | [−9.0, −4.9] | [+15.9, +19.9] |
| nemotron-pii, library (tuned, +agent) | 17.6% | 68.4% | 47.9% | [−9.9, −6.3] | [+14.6, +19.4] |
| ettin-68m (tuned, +agent) | 17.7% | 65.3% | 43.6% | [−10.1, −6.3] | [+18.0, +22.4] |
| pii-identifier (tuned, +agent) | 18.8% | 77.7% |
Each row is the tool at its tuned setting, with the agent-policy filter. Bold marks nullpii's name and the best value in each column. METHOD.md has every other row, B1 (CredData), B2 (issue secrets), the leak rate per category, and the secrets split by recognizer coverage. The raw numbers are in published-bench/ab1/.
R3 measures document anonymisation, a different job from agent traffic. It uses five datasets, frozen before any tool ran on them: REDACT, TonicAI's human-annotated Privacy-Bench, PIILO student essays, Greek and German clinical notes, and a synthetic coding-agent trace set built for this benchmark from a specification we wrote. Each has under 1% measured overlap with nullpii's training data and with the public training sets the other tools declare (three declared sources, among them rizzo-pii's Italian sets, were not compared). The score is per character and ignores labels. F2 counts recall twice as much as precision, because a missed character leaks. nullpii's rows are from the release build, with the three rules described under AB-1; they changed only documents that hold a UUID, an IP address, a loopback host or the word "Claude".
Two things compared here are built for documents: PIILO, where only the students' own names count as gold, and rizzo-pii, a document anonymiser (we run its app's own analyze(); its model and training data are Italian-first).
| Tool | Macro char-F2 | F0.5 | Recall | Precision | CI of nullpii − tool (F2) |
|---|---|---|---|---|---|
| rizzo-pii (default) | 0.770 | 0.633 | 0.869 | 0.608 | [−0.020, −0.003] |
| nullpii | 0.758 | 0.534 | 0.958 | 0.490 | — |
nemotron-pii (nvidia/gliner-PII, library) | 0.720 | 0.612 | 0.808 | 0.591 | [+0.025, +0.051] |
| OpenMed privacy-filter-multilingual-v2 | 0.717 | 0.585 | 0.841 | 0.560 | [+0.031, +0.049] |
| pii-identifier | 0.701 | 0.583 | 0.809 | 0.569 | [+0.044, +0.070] |
| ettin-68m | 0.699 | 0.563 | 0.825 | 0.545 | [+0.050, +0.068] |
| openai privacy-filter | 0.693 | 0.591 | 0.767 | 0.587 | [+0.052, +0.079] |
| OpenMed PII Large | 0.682 | 0.587 | 0.783 | 0.578 | [+0.060, +0.090] |
| OpenMed PII Small | 0.673 | 0.512 | 0.807 | 0.478 | [+0.069, +0.099] |
| gliner-pii-large | 0.656 | 0.571 | 0.811 | 0.555 | [+0.085, +0.119] |
| piiranha | 0.651 |
Bold marks nullpii's name and the best value in each column.
nullpii is measured with its five extended categories off, because the datasets do not label them. With every category masked (the default before 0.5), it scores 0.748 on the same labels, and 0.653 when everything it masks counts, because masking organisations, occupations and the like counts as over-masking here. The 0.5 default for coding agents leaves those five categories and dates readable. That default is measured on agent traffic (AB-1, above), not on these datasets, which label dates.
Where nullpii is not ahead, in detail.
sentences subset, scored by us with the leaderboard's method, not a submitted entry, with every category masked): average F2 0.851, above all 35 listed tools. Next is OpenMed's privacy-filter-multilingual-v2 at 0.836. One of the six tasks, nemotron-pii, comes from nullpii's training family: 2.5% of its sampled text overlaps nullpii's training data, and 5.2% overlaps Nemotron-PII's. Without that task nullpii averages 0.831, against 0.827 for gliner-stream-pii and 0.822 for privacy-filter-multilingual-v2. The leaderboard gives no intervals, so this lead cannot be called significant. nullpii trails on the ai4privacy, nemotron-pii and Gretel tasks, and on privy, where it masks too much.METHOD.md has the three reported (not gated) sets, the numbers per dataset, and the sensitivity checks.
nullpii is not the fastest: it is seventh of 13 tools on GPU and fifth of 15 on CPU, at 30,000 characters. Every tool runs the same coding-agent texts on the same idle machine, after a warm-up, at its default setting. nullpii has two rows: its core labels (the five extended categories off, dates on) and every category masked. Its 0.5 default, which also leaves dates readable and so asks the model for fewer labels, takes the same time as the core labels on GPU (458 ms at 30,000 characters) and about 13% less on CPU (6,104 ms); it was timed with the release build, which also matched the other nullpii rows to within 2% (METHOD).
The tables show the median time per call, in milliseconds, for texts of 2,000, 30,000 and 100,000 characters of coding-agent material (code, logs, prose, tool output). The ranks above count nullpii once and NVIDIA's two nemotron pipelines as one tool. Bold marks nullpii's name and the fastest value in each column. How the texts are chosen: METHOD.md.
GPU (Linux, NVIDIA RTX 4070 Ti; 60, 12 and 5 texts per size, three rounds). nullpii loads model_fp16.onnx on CUDA.
| Tool | 2k | 30k | 100k |
|---|---|---|---|
| ettin-68m | 11 | 157 | 544 |
| openai privacy-filter | 24 | 205 | 716 |
| OpenMed privacy-filter-multilingual-v2 | 26 | 311 | 1,103 |
| piiranha | 25 | 342 | 1,177 |
| pii-identifier | 19 | 407 | 1,411 |
| gliner-stream-pii | 30 | 412 | 1,421 |
| nullpii (core labels) | 32 | 463 | 1,650 |
| nullpii (every category masked) | 34 | 489 | 1,747 |
| rizzo-pii | 27 | 494 | 1,715 |
| deberta PII | 35 | 631 | 2,268 |
| OpenMed PII Small | 46 | 794 | 3,423 |
| OpenMed PII Large | 80 | 1,209 | 5,126 |
nemotron-pii (nvidia/gliner-PII, library) | 136 | 1,478 | 5,208 |
| gliner-pii-large-v1 | 83 | 1,892 | 6,550 |
| nemotron-pii (NVIDIA server pipeline) | 189 | 2,835 | 9,966 |
CPU (Linux, Intel Core i7-13700KF, every tool on CPU; 6, 6 and 3 texts per size, timed once, because the full plan takes hours per tool here).
| Tool | 2k | 30k | 100k |
|---|---|---|---|
| Presidio | 35 | 511 | 2,209 |
| OpenMed PII Small | 207 | 2,603 | 5,279 |
| piiranha | 386 | 6,208 | 20,493 |
| pii-identifier | 326 | 6,609 | 24,116 |
| nullpii (core labels) | 394 | 6,984 | 24,674 |
| nullpii (every category masked) | 432 | 7,655 | 27,048 |
| ettin-68m | 535 | 8,882 | 29,640 |
| rizzo-pii | 413 | 10,962 | 32,918 |
| deberta PII | 654 | 11,933 | 42,702 |
| OpenMed PII Large | 1,228 | 14,291 | 22,324 |
| gliner_multi_pii (ONNX) | 1,300 | 15,549 | 55,069 |
| gliner-stream-pii | 1,351 | 20,613 | 69,957 |
nemotron-pii (nvidia/gliner-PII, library) | 2,090 | 25,941 | 94,524 |
| gliner-pii-large-v1 | 1,336 | 35,183 | 116,889 |
| nemotron-pii (NVIDIA server pipeline) | 3,101 | 48,415 | 168,702 |
Presidio is fast because it is mostly patterns plus a small spaCy model; its macro char-F2 is 0.628. OpenMed Large's time depends a lot on the text, so its 100k figure, from three texts, is rough. gliner_multi_pii (ONNX) runs on CPU only, and Presidio has no GPU path, so neither is in the GPU table.
new NullPii({ backend: 'cpu' }); // ONNX Runtime on the CPU (the default)
new NullPii({ backend: 'cuda' }); // NVIDIA GPU, fp16 when the model ships it; falls back to the CPU
new NullPii({ backend: 'mps' }); // Apple Silicon through CoreML; slower than 'cpu' today, see below
backend: 'cuda' needs the CUDA libraries that the installed onnxruntime-node was built with. For 1.30 on Linux x64 that is CUDA 13 (libcudart.so.13, libcublas.so.13, libcublasLt.so.13) and cuDNN 9, even though its installer calls the build cuda12. If nullpii cannot start a CUDA or CoreML session (a missing library, an unsupported graph, too little memory), it runs on the CPU instead. It then emits a process warning with code NULLPII_BACKEND_FALLBACK that names the cause (listen with process.on('warning', …)). A model downloaded for CUDA has only the fp16 file. The CPU can run it too, but the benchmark measures the fp32 file (accuracy on CUDA, the CPU latency table on the CPU).
On Apple Silicon, use cpu. With CoreML the model was slower than on the CPU at every size measured (1.3 to 8 times slower, depending on the CoreML settings; measured on earlier builds). Its first call also took 18 to 26 seconds while CoreML compiled the graph, which the GLiNER head's dynamic shapes split into many parts (#51).
intraOpNumThreads and interOpNumThreads are passed to ONNX Runtime.
NULLPII_LOG_TRAFFIC=wire debug dump prints what was sent upstream, including anything the detector missed (see SECURITY.md).Grep, Read, Edit or Write, which do get real values. If you add a shell tool under another name to restoreTools, nullpii does not recognise it and gives it every value, so do not add one. If you call restore() yourself, read SECURITY.md.Report a vulnerability privately: security advisories.
Apache-2.0: see LICENSE and NOTICE. What the model was trained on, and the attributions it carries: docs/WEIGHTS_PROVENANCE.md.
The detection model builds on urchade/gliner_multi_pii-v1 (GLiNER, Zaratiana et al., NAACL 2024, on Microsoft mDeBERTa-v3 base). Training data credits: NVIDIA (Nemotron-PII), the Allen Institute for AI and Common Crawl (C4), Microsoft (presidio-research) and Norsk Regnesentral (TAB).
| gender, age, ethnicity, nationality, language |
| model |
private_sensitive | religion, political views, sexual orientation, health, when stated | model |
private_title | honorifics and titles before a name | model |
| 52.5% |
| [−11.0, −7.7] |
| [+5.7, +9.8] |
| gliner_multi_pii (ONNX) (tuned, +agent) | 19.2% | 56.9% | 44.2% | [−11.6, −7.9] | [+26.0, +31.2] |
| OpenMed privacy-filter-multilingual-v2 (tuned, +agent) | 20.1% | 81.6% | 48.3% | [−12.0, −9.1] | [+2.2, +5.6] |
| piiranha (tuned, +agent) | 23.8% | 68.8% | 56.5% | [−16.5, −12.3] | [+14.5, +18.8] |
| Presidio (tuned, +agent) | 40.6% | 82.3% | 77.9% | [−33.2, −29.0] | [+1.4, +5.1] |
| deberta PII (tuned, +agent) | 55.1% | 64.2% | 81.2% | [−48.7, −42.4] | [+18.0, +24.3] |
| 0.465 |
| 0.840 |
| 0.428 |
| [+0.092, +0.120] |
| gliner_multi_pii (ONNX) | 0.648 | 0.495 | 0.845 | 0.462 | [+0.098, +0.122] |
| Presidio | 0.628 | 0.492 | 0.790 | 0.465 | [+0.116, +0.142] |
| gliner-stream-pii | 0.568 | 0.522 | 0.714 | 0.528 | [+0.174, +0.203] |
| deberta PII (default) | 0.464 | 0.254 | 0.802 | 0.225 | [+0.282, +0.305] |
| mask everything | 0.260 |
| OpenMed privacy-filter-multilingual-v2 |
| 9,133 |
| 132,528 |
| 448,206 |
| openai privacy-filter | 9,514 | 137,526 | 467,769 |