Start with https://example.com/p?q=a%20b&utm_source=old&flag&utm_source=older#buy. Enter linkedin, paid_social, launch and hero/card in source, medium, campaign and content.
Expected final URL
The result is https://example.com/p?q=a%20b&flag&utm_source=linkedin&utm_medium=paid_social&utm_campaign=launch&utm_content=hero%2Fcard#buy. The original q value keeps %20 instead of becoming +, the bare flag remains bare, the slash inside content becomes %2F and #buy stays at the end.
Expected evidence
Two unrelated segments are preserved, both lower-case utm_source occurrences are replaced, and four campaign pairs are added. A differently cased UTM_SOURCE would be treated as unrelated and remain visible, because the owned-name match is exact and case-sensitive. Review such a mixed-case name manually rather than assuming it was silently corrected.
Reproduce and inspect the result
Load the reviewed example in UTMLink or type the values exactly as shown. Build the link and compare each preserved segment, campaign pair and fragment with the expected line character by character. The evidence counters explain what happened without sending the address anywhere: preserved counts unrelated raw segments, replaced counts every lower-case owned UTM occurrence removed, and added counts the final non-empty campaign fields. Change one optional value, build again and verify that stale output disappears before the new result is shown. Finally clear the form and confirm that no history returns after a reload, because this first release deliberately stores neither entered nor generated links.