Blog Articles
This page collects the main technical articles on haotianblog, with emphasis on machine learning, algorithm implementation, deep learning math, network protocols, AI security, and battery modeling. The goal is to publish explanations with context, implementation details, code, or experiment output rather than short summaries.
If this is your first visit, start by topic. The machine learning route begins with data and evaluation. The algorithm route begins with eight queens and K-means. The networking route moves from DNS, TCP, and TLS into proxies and caching. The AI security route starts from threat modeling and safe toy labs.
Current reading routes
- Machine Learning From Scratch: workflow, model evaluation, K-means, and Python/C practice.
- Deep Learning Tutorials: neural networks, matrix calculus, backpropagation, optimizers, convolution, attention, and CIFAR-10 Tiny CNN.
- Network Fundamentals Visualized: DNS, CIDR, TCP, TLS, HTTP caching, proxy tunnels, and reverse-proxy health checks.
- AI Security Engineering: threat modeling, adversarial examples, poisoning, model privacy, RAG, and agent safety.
- Battery Modeling for AI: PyBaMM, EIS data, aging simulation, and SOH/RUL training.
How to evaluate an article here
The site is trying to avoid pages that are only concept summaries or link lists. A useful technical article should state the question, show the input, explain the implementation, preserve evidence, and describe the boundary of the result. For algorithms and machine learning, that evidence may be intermediate state, metrics, error cases, source code, or downloadable files. For network protocols, it may be headers, status codes, cache state, timing phases, and reproduction commands.
If a page is only a route, index, or tool surface, it should point clearly to the stronger article that carries the explanation. That keeps the site easier to evaluate: a reader can tell whether a page is a learning route, an experiment entry, a resource page, or a complete tutorial.
Content Type and Evidence Standard
| Content type | Question it should answer | Evidence the page should keep visible |
|---|---|---|
| Machine learning implementation | How does data enter the model, and why should the metric be trusted? | Split strategy, baseline, run command, error cases, and metric definition. |
| Algorithm and C/Python code | Which state changes, and where are the boundary cases? | Input format, loop invariant, complexity, output example, and failing input. |
| Network protocol debugging | Is the issue in DNS, TLS, proxying, caching, or the application layer? | Headers, status codes, timing sequence, cache state, and reproduction commands. |
| AI security experiment | What does the demo prove, and what does it not prove? | Authorization boundary, toy-lab setup, metric, mitigation, and misuse limits. |
Current maintenance focus
New and revised articles will continue to emphasize reproducibility and explanation. Machine learning pages should include split strategy, baselines, error analysis, and experiment notes. Network pages should show layered evidence from browser, CDN, Nginx, and application behavior. AI security pages should keep authorization boundaries, toy-lab limits, and defensive review methods visible.
Older articles are revised against actual reproduction results. Broken commands need replacements, dependency changes need versions, and conclusion-only passages need derivations or run evidence. A reader should be able to tell whether a claim comes from an equation, program output, protocol response, or controlled experiment.
Article index
The index below is generated from the current site categories. Tool, survey, and share pages are not treated as core articles; readers should prioritize posts with complete body text, code, and experiment notes.
Categorized blog
Read by project
Posts are grouped into networking, battery modeling, AI, 2D animation, algorithm implementation, and site-building projects, with level, reading time, and stack metadata.
Series
Deep Learning Math Visualized
Five posts move from matrix calculus, backpropagation, optimizers, convolution, and attention, each with hand calculation, code, figures, and animation.
5 postsMatrix Calculus for Neural Networks
Derive dL/dW for y = Wx + b and verify it with finite differences.
Backpropagation as a Computation Graph
Trace local gradients through ReLU and softmax cross-entropy in a two-layer MLP.
Gradient Descent and Optimizer Geometry
Compare gradient descent, momentum, and Adam on a visible quadratic loss surface.
Convolution and Receptive Field Math
Compute convolution output size, receptive fields, channel mixing, and im2col layout.
Transformer Attention Math
Hand-calculate Q/K/V scores, softmax weights, masks, multi-head structure, and KV cache.
Project category
Network Fundamentals
A reproducible route through DNS, TCP, TLS, HTTP/3, proxy tunnels, load balancing, and shared caches with code and figures.
14 postsSharing a Secret Is Easy; Sharing State Is Not: Six Traps in Cross-Machine SSO
Extending a single-machine login gate into SSO across subdomains makes key distribution the easy part — state is the hard one. This records the problems from running one gate on three machines: why replay protection became per-site, how a second copy of the key produced "gate passes, application returns 401", how an allowlist preservation rule in a deploy script silently switched login off, and why comparing generated codes manufactures phantom failures.
Authenticated Is Not Protected: Auditing an Authorisation Boundary
After putting a two-factor gate in front of a self-hosted file manager, I asked what the gate actually protected. It protected the interface, not the files — the same bytes were reachable by two URLs, and while verifying that I found the gate had never been in the request path at all. This covers the audit, two nginx traps in the patch, and the edge cache that kept serving for nearly a year after the origin was closed.
Does Inbound Actually Work? Probing a Home Line From the Outside
Every port looks open when you scan from the machine itself, and nothing outside can connect. This covers why local probing is guaranteed to mislead, why a control port is not optional, and a full measurement run: public IPv4 that is not CGNAT, ports 80 and 443 filtered rather than closed, a real IPv6 address with inbound entirely dropped, and why an AAAA record must not come from an echo service.
A Certificate Is Not HTTPS: Debugging a Subdomain Reported as “Uncertified”
Someone told me a subdomain had no SSL certificate. It did — a wildcard covered it. But the investigation surfaced something worse: that subdomain served its mail login page over plain HTTP, password field and all, with no redirect. Plus two things that sent me the wrong way: openssl failing on every target at once, and DNS enumeration being meaningless behind a transparent proxy.
DNS Resolution Explained: Build a TTL Cache and Packet Parser in Python
A runnable DNS guide covering resolution paths, response headers, TTL cache latency, and deterministic Python/C experiments.
CIDR, Longest Prefix Match, and MTU: Calculate IP Routing Step by Step
Calculate CIDR ranges, longest-prefix route choice, and MTU/MSS payload segmentation with runnable Python and C examples.
TCP Reliability and Congestion Window: A Runnable Sequence Number Experiment
Track TCP sequence numbers, cumulative ACKs, loss, retransmission, and congestion-window changes with safe local experiments.
HTTPS and TLS 1.3 Handshake: Keys, Certificates, and RTT in Practice
Understand TLS 1.3 message flights, certificate authentication, ephemeral key agreement, and handshake latency with a safe teaching model.
HTTP/2, HTTP/3, and CDN Caching: Read Page Speed from a Waterfall
A deterministic browser-waterfall model for HTTP/2, HTTP/3, QUIC streams, and CDN cache hits or misses.
Forward Proxy vs Reverse Proxy: Connection Paths, Trust Boundaries, and Latency
A reproducible guide to forward proxies, reverse proxies, tunnels, TLS boundaries, and latency segments.
HTTP CONNECT and HTTPS Proxy Tunnels: TLS Boundaries and Handshake Latency
An RFC-based explanation of CONNECT tunnels, encrypted HTTPS payloads, and modeled first-request latency.
SOCKS5 Proxy Explained: Protocol Bytes, DNS Resolution Boundaries, and Leakage Risk
Decode safe SOCKS5 CONNECT bytes and compare local-DNS and proxy-side hostname resolution boundaries.
Reverse Proxy Load Balancing: Queues, Health Checks, and a Reproducible Scheduler
Compare round robin and load-aware queue selection while reasoning about health checks and retry boundaries.
Proxy Cache Revalidation: Cache-Control, ETag, and Observable Correctness
Use an RFC 9111 shared-cache model to calculate MISS, HIT, and 304 revalidation latency and correctness boundaries.
Project category
Battery Modeling for AI
A reproducible research path from PyBaMM, EIS, and aging simulation to AI labels and risk-controlled parameter identification.
11 postsReading PyBaMM Fast: Architecture for Battery Modeling and AI Data
A PhD-level guide to PyBaMM expression trees, Simulation, model options, metadata, and AI dataset design.
PyBaMM EIS Data Generation: Impedance Features and AI Labels
Use PyBaMM core EISSimulation to generate impedance spectra, extract features, and align them with aging labels.
Generate Battery Aging and EIS AI Datasets with PyBaMM
Build a reproducible PyBaMM data factory for SOH, RUL, LLI, LAM, plating, and impedance-feature labels.
Training a Battery AI Model with PyBaMM: Predicting SOH and RUL
Train scikit-learn regressors on PyBaMM-style EIS features and operating metadata to predict battery SOH and RUL.
What PyBaMM’s Capacity Numbers Measure: “80% capacity”, Capacity [A.h] and Loss of Capacity to SEI
PyBaMM has several different things called capacity, and degradation studies quietly mix them: termination="80% capacity" compares a zero-current eSOH capacity, not a measured discharge; summary variables are read at the end of each cycle; 'Loss of capacity to X' is lithium, not capacity; and the default parameter set gains capacity as it loses lithium. Measured in PyBaMM 26.5, with an audit function.
PyBaMM SEI and Lithium Plating Pitfalls: Clock-Driven SEI, Placeholder Rates, Temperature and Pore Clogging
The choices that decide a PyBaMM fade curve never raise an error: OKane2022's SEI grows with time alone, so rests change cycle count but not the end-of-life date; the SEI rate constants are generic placeholders that differ 450-fold between options; activation energy is zero in every other set; a cold plating clog is overstated 5-fold on the default mesh; and 'irreversible' plating deposits lithium at rest. Measured in PyBaMM 26.5, with a pre-flight check.
PyBaMM Thermal Models, Measured: Zero Heating, Missing Entropy and a Cold Start at 25 °C
PyBaMM's thermal options run without complaint, and each of these set-ups returns a plausible temperature curve: isothermal heating variables are zero by construction, four parameter sets have no reversible heat, four describe a single electrode sheet cooled on both faces, and a cold-start run that sets only the ambient temperature begins at 25 °C. Measured on eight parameter sets, with an audit function.
PyBaMM Experiments That Finish and Are Wrong: Five Traps, Measured
PyBaMM's Experiment API almost never raises, and each of these five mistakes returns a normal-looking solution: steps in amps stop silently at 24 hours, a flat step list overstates cycle life fourfold, save_at_cycles leaves None in the list, period never changes PyBaMM's answers but can break yours, and initial_soc=1 is not 4.2 V. Includes a completion check.
PyBaMM’s Built-in Parameter Sets, Measured: Four Ways They Fail Silently
The same experiments run on all 18 built-in parameter sets in PyBaMM 26.5. The sets that error are not the problem; the ones that finish and are wrong are. "1C" on the default set is really 0.78C, Chen2020 loses 0.6% of its capacity at −10°C, an experiment string charges an LFP cell to 4.2 V with zero warnings, and SEI runs on borrowed example parameters. Includes a check you can run.
Fitting PyBaMM Parameters: Why the Optimiser’s Numbers May Mean Nothing
The top search result, pybamm-param, is deprecated; PyBOP just restructured its API; and identifiability means an optimiser handed fifty free parameters returns fifty meaningless numbers. Includes a protocol separating a fit from a decoration.
PyBaMM Solver Convergence Failures: Numerics or Physics
When a long degradation run dies at cycle 300, reaching for tolerances is usually wrong. Tell numerics from physics with an SPMe cross-check, plus every IDAKLU option default and one trap that fails silently.
Project category
AI Learning Project
A practical route from AI concepts to machine learning workflow, evaluation, neural networks, Python practice, handwritten digits, a CIFAR-10 CNN, adversarial traffic-defense notes, and AI security.
28 postsHow to Choose a Machine Learning Algorithm: Classification, Regression, Clustering and Recommendation
Choose a machine learning algorithm by task type, data size, interpretability and deployment cost, covering logistic regression, decision trees, random forests, K-means and tabular baselines.
Getting Started with Feature Engineering: Missing Values, Categorical Variables and Scaling in scikit-learn
Build a feature engineering pipeline with scikit-learn Pipeline and ColumnTransformer, handling missing values, categorical variables and numeric standardisation while avoiding data leakage.
How to Fix Overfitting and Underfitting: A Practical Model Tuning Guide
Diagnose overfitting and underfitting from training and validation scores, then tune the model through complexity, regularisation, cross-validation and feature engineering.
AI Basics Learning Roadmap
Separate AI, machine learning, and deep learning before going into implementation details.
Machine Learning Workflow
Follow the practical path from data and features to training, prediction, and evaluation.
Model Training and Evaluation
Understand loss, overfitting, train/test splits, accuracy, recall, and F1.
Neural Network Basics
Move from perceptrons to activation, forward propagation, backpropagation, and training loops.
Matrix Calculus for Neural Networks
Derive dL/dW for y = Wx + b and verify it with finite differences.
Backpropagation as a Computation Graph
Trace local gradients through ReLU and softmax cross-entropy in a two-layer MLP.
Gradient Descent and Optimizer Geometry
Compare gradient descent, momentum, and Adam on a visible quadratic loss surface.
Convolution and Receptive Field Math
Compute convolution output size, receptive fields, channel mixing, and im2col layout.
Transformer Attention Math
Hand-calculate Q/K/V scores, softmax weights, masks, multi-head structure, and KV cache.
Python AI Mini Practice
Run a small scikit-learn classification task and read the experiment output.
Handwritten Digit Dataset Basics
Read train.csv, test.csv, labels, and the flattened 28 by 28 pixel layout before training the classifier.
Handwritten Digit Softmax in C
Follow the C implementation from logits and softmax probabilities to confusion matrices and submission export.
Handwritten Digit Playground Notes
See how the offline classifier was adapted into a browser demo with drawing input and probability output.
CIFAR-10 Tiny CNN Tutorial in C
Build and train a small convolutional neural network for CIFAR-10 image classification, then read its loss and accuracy output.
High-Entropy Traffic Defense Notes
Study encrypted metadata leaks, entropy, traffic classifiers, and a defensive Python chaffing prototype.
AI Security Threat Modeling
Build a defense map with NIST adversarial ML, MITRE ATLAS, and OWASP LLM risks.
Adversarial Examples and Robust Evaluation
Evaluate clean and perturbed accuracy with an FGSM-style digits experiment.
Data Poisoning and Backdoor Defense
Study poison rate, trigger behavior, attack success rate, and training pipeline controls.
Model Privacy and Extraction Defense
Measure membership inference signal and surrogate fidelity against a local toy model.
LLM, RAG, and Agent Security
Separate instructions from data and enforce tool permissions against indirect prompt injection.
Large Language Models From a Developer’s Angle: Word Association at Scale
What an LLM is doing underneath the marketing: next-token prediction driven by the Transformer. Covers the architectural workflow, running an 8B model locally in Python, the hardware pitfalls encountered on the way, and what actually matters for developers building on top of these models.
Multimodal LLM Architecture: How Vision Gets Aligned With Language
The crux of multimodal models is modality alignment. Covers the end-to-end architecture, the mathematics behind Q-Former and cross-attention, an MLP projection layer implemented in PyTorch, and why a linear projection and a two-layer MLP behave differently in production.
KV Cache VRAM Explosion When Deploying Multimodal LLMs
Deploying LLaVA, Qwen-VL or InternVL runs into the same wall: KV cache memory. Covers the derivation of KV cache consumption, how AnyRes and dynamic resolution mitigate visual token explosion, 4-bit quantised inference with llama.cpp, and the engineering traps behind each.
Visual Instruction Tuning: Where the Loss Function Actually Applies
The mechanics of visual instruction tuning, focusing on loss construction. Covers multimodal auto-regressive next-token prediction, the data flow from JSON to masked labels, the PyTorch label-masking implementation, and the production pitfalls that follow from getting the mask wrong.
Deep Learning Frameworks: Why You Stop Writing Backpropagation by Hand
A reproducible CPU comparison of PyTorch and TensorFlow using one fixed linear layer. Align weight layouts, losses and gradients, then check SGD updates, microbatch weighting, target broadcasting and save/load behavior against explicit references.
Project category
2D Animation Principles
A route from character segmentation and SVG assets through bone matrices, two-bone IK, skinning weights, seam repair, and keyframe interpolation.
11 postsThe Animate Timeline and Symbol Model: How Graphic and Movie Clip Resolve Frames
Derive the frame-resolution formulas behind Graphic symbol loop modes, explain why a Movie Clip shows only frame 1 while authoring and collapses during frame-by-frame export, and why lip sync requires Graphic.
Shape Tweening and Vector Morphing: Vertex Correspondence, Shape Hints, and SVG Paths
Shape tween explosions come from start-offset ambiguity on closed contours. Derive the correspondence cost function, show how shape hints act as constraints, and map it onto modern SVG path morphing.
Modern 2D Skeletal Runtimes: Mesh Deformation, Draw Order, and Constraints
Linear blend skinning cannot express folds, draw order or follow-through. Why mesh deformation must be applied in bind space, why draw order is a discrete track, and how Live2D's parameter-driven keyforms produce pseudo-3D.
Animate’s HTML5 Canvas Runtime: Display List, Repaint Cost, and Caching
Publishing compiles the timeline into a CreateJS display tree, and the canvas repaints entirely every frame. Why vectors pay rasterisation per frame, the three cache parameter traps, and why filters require caching.
Character Image to SVG Animation Asset Pipeline: ComfyUI, Grounded-SAM, OpenPose, and vtracer
The first article in the 2D animation principles column: use ComfyUI IP-Adapter, OpenPose exploded layout, Grounded-SAM matting, and vtracer to build rig assets.
2D Skeletal Animation Math: Local Space, Pivot Matrices, and Forward Kinematics
Derive 2D forward kinematics from homogeneous matrices, pivot rotation, and parent-child transforms, then verify end-point coordinates interactively.
Two-Bone Inverse Kinematics in 2D: Law of Cosines, Reachability, and Elbow Flips
Solve 2D shoulder and elbow angles analytically with the law of cosines while handling unreachable targets, numeric boundaries, and elbow continuity.
Secondary Motion: Damped Springs for Hair and Tails
The keyframes are dialled in and the character still reads as stiff, because secondary motion is missing — the parts dragged along by the primary action that arrive a beat late. This covers parameterising a damped spring as frequency and damping ratio, and five traps in wiring it into a 2D skeletal system: why explicit Euler is unconditionally unstable, frame-rate dependent results, root-to-tip chain ordering, springing angles rather than positions, and why teleports blow it up.
Squash and Stretch: Why Non-Uniform Scale Cannot Pass Through a Rotation
Wire squash and stretch into a skeletal system and nearly all the difficulty comes from one fact: non-uniform scale does not propagate down a hierarchy as safely as rotation and translation. This covers area preservation in 2D and the two things it does not preserve, why the wrong pivot sinks a ball into the floor, and the core trap — a parent scale times a child rotation contains shear, so only the rotated parts come out skewed.
Linear Blend Skinning for 2D Animation: Weights, Joint Deformation, and Seam Repair
Derive linear blend skinning and explain normalized weights, inverse bind matrices, joint collapse, alpha contamination, and SVG seam dots.
2D Keyframe Interpolation: Linear, Smoothstep, Bezier, and Frame-Rate-Independent Motion
Use derivatives to compare linear and eased velocity, then derive smoothstep, cubic Bezier curves, and frame-rate-independent timeline sampling.
Project category
Algorithm Implementation Project
Implementation-focused notes around backtracking, bit operations, clustering, code, diagrams, and downloads.
5 postsA Contour Tracer’s Stopping Condition: Three Lines Out of Order, Twenty Times the Area
Jacob's stopping criterion for Moore-neighbourhood tracing requires position and direction to match. I checked before updating the direction, using the previous iteration's leftover value, so the condition almost never fired — the tracer looped until the iteration cap, and the shoelace formula then closed the unclosed point list straight across the region.
Getting Started with Backtracking: Solving Eight Queens in C and Python
Explain the state representation, conflict checks, recursive process and complete solution of the eight queens backtracking search in C and Python.
Backtracking, Advanced: Optimising Eight Queens with Bitwise Operations (C / Python)
Optimise the eight queens search with bitmasks to cut the cost of state checks, with matching implementations in C and Python.
Getting Started with K-means Clustering: A C Implementation on the Iris Dataset
Work through K-means++ initialisation, iterative convergence and result analysis using Iris.csv, C source code, a flowchart and a visualisation.
Image to Unicode Quadrant ANSI: Principles, Implementation and a Browser Tool
Explain how any image is compressed into truecolor Unicode quadrant ANSI: 2 x 2 pixel blocks, minimum-error two-colour approximation, .ans files and browser-side privacy boundaries.
Project category
Site Building Project
Notes on the bilingual site structure, content sync, categories, comments, and deployment workflow.
12 postsAuditing My Own Site’s Structure: A Metric That Was Wrong by 8x
Trying to quantify whether my articles all look the same, I first measured 92% and wrote it into my conclusions. That number counted the theme template as article structure; corrected, it is 12%. This is about the measurement: defining "shape", where I drew the boundary wrong, why one metric hides the real problem, and the accidental control that finally killed it.
Moving an Entire Image Pipeline Into the Browser: It Saves More Than CPU
A tool that takes character images, cuts them out, separates layers and produces an SVG asset library — with nothing uploaded. The original motivation was a single-core origin that could not host server-side image processing; what it actually saved was storage, moderation, privacy obligations and concurrency. Covers the five-step implementation, the price of IndexedDB, replacing a compression library with ZIP stored mode, and the one unavoidable cost.
Featured Image Set, og:image Empty: Yoast’s Stale Indexable Cache
I attached featured images to 19 posts. The admin looked right, the page source had no og:image — and the JSON-LD on the same page already pointed at the new cover. That pairing is the diagnosis: the two outputs travel different paths, one computed live and one read from a precomputed index table.
Only 276 MB of 8.3 GB Was Unique: Forensics Before a Delete
The server hit 86% disk with deploy backups at 8280 MB. Before deleting anything I worked out how much was genuinely unique — 276 MB, with the rest being one set of files copied 228 times. A set-difference check run before the delete recovered seven files that existed only in historical snapshots.
Welcome to haotianblog: what this bilingual technical site covers
An introduction to the bilingual site, its technical focus, and the kinds of articles and resources it will publish.
The Score Sets a Price, It Never Renders a Verdict
Replacing manual approval of mailbox requests with proof of work plus local IP scoring. The design does not hinge on the algorithm but on one rule: no reputation score causes a rejection, it only decides how long you hash. Covers why a hand-written SHA-256 must be checked against block-boundary vectors, why difficulty is a UX parameter rather than a security one, and why external reputation APIs and country weighting were deliberately left out.
Two Different GPUs Reporting the Same Name
Building a JAX environment on a dual-GPU Windows box under WSL2 produced traps that all share one shape: what you can observe is not what is there. device_kind reports the same model for two different cards, so routing by name puts a 16 GB batch on the 8 GB one. Also a CPU-only jaxlib that installs happily and does nothing, background processes killed without a journal entry, a best-fit policy that starved the larger card, and stdin pipes that deadlock across the WSL boundary.
Loopback Cannot Drop Packets, But It Retransmitted 62 Times
A router died under load, recovered on reboot, and left no evidence behind. The only way in was an observation that should have been impossible: 62 retransmissions on loopback, all concentrated in LAST_ACK and CLOSE_WAIT. Following it led to a firewall rule protecting the wrong address and dropping the teardown signals between two local processes. Includes the full failure chain, the fork that sends you after the wrong bug, and a twin-rule experiment showing why a ct condition silently never matches in a raw chain.
Eight Failures That Never Errored: The Fitter Quietly Returned My Initial Guess
Eight problems found while writing an equivalent-circuit fitter for impedance spectra, none of which threw an exception. The most expensive was a missing minus sign in the Levenberg-Marquardt step: every trial walked uphill, all were rejected, and the function handed back the initial guess while the interface reported success. Also a parameter running to 1e154 along a flat valley, a guard that misclassified normal convergence, and a weighting choice worth a 250x difference in bias.
At the Same Google Rank, My Tool Pages Get 6.4x the Clicks of My Articles
Three months, 12,491 impressions, 53 clicks. After bucketing Search Console data by position and ruling out truncated titles, missing descriptions and mobile demotion one at a time, one statistically significant split remained: in the 1-10 bucket, tool pages convert at 4.76% against 0.74% for articles, p=0.0012. Includes the failed attempt that mistook "nobody built it" for "somebody needs it".
Matching Emails Are Not Proof: Six Traps in Third-Party Sign-In
Adding third-party sign-in looks like a solved problem: take an OIDC library, exchange the code, verify the signature, find the user by email. Wiring up …
Read-Only Is Structural, Not a Discipline: Ten Traps in Wiring a Self-Hosted Mailbox to AI
Wiring a self-hosted mailbox into an AI assistant: the protocol half is easy, making read-only structural rather than a promise is not. Traps hit along the way -- a rejection letter whose boilerplate says has been accepted, a syntax check that passed while authentication became dead code, a shared failure latch that took every user down at once, and why a synthetic click cannot tell a dead button from a blocked popup.
