Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Why does default array sorting put cleaned 10 before 2?

Our cleaned list sorts as 10, 2, 3 with default sort, and 2, 3, 10 with a numeric comparator. Removing a marker does not select numeric ordering. Validate every numeric input before using subtraction as a comparator.

Tested October 15, 2026 · v24.19.0 · 4 measured runs

Open the Claude text cleaner · Full measured data

Code-point comparison for Marked two

Measured inputs and outputs

These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.

Before and after observations; full code points and strings are in the JSON download.
Fixture and modeInput string and code pointsOutput and cleaner statusObserved before / after
Marked two
direct string / keep / invisible true
"​2"
U+200B U+0032
"2"
Removed 1 invisible character
{"values":["​2","10","3"],"defaultSorted":["10","3","​2"],"numericSorted":["​2","3","10"],"numericLabels":["NaN","10","3"]}
{"values":["2","10","3"],"defaultSorted":["10","2","3"],"numericSorted":["2","3","10"],"numericLabels":["2","10","3"]}
Plain two
direct string / keep / invisible true
"2"
U+0032
"2"
No selected invisible characters found
{"values":["2","10","3"],"defaultSorted":["10","2","3"],"numericSorted":["2","3","10"],"numericLabels":["2","10","3"]}
{"values":["2","10","3"],"defaultSorted":["10","2","3"],"numericSorted":["2","3","10"],"numericLabels":["2","10","3"]}
Ten control
direct string / keep / invisible true
"10"
U+0031 U+0030
"10"
No selected invisible characters found
{"values":["10","10","3"],"defaultSorted":["10","10","3"],"numericSorted":["3","10","10"],"numericLabels":["10","10","3"]}
{"values":["10","10","3"],"defaultSorted":["10","10","3"],"numericSorted":["3","10","10"],"numericLabels":["10","10","3"]}
Negative control
direct string / keep / invisible true
"-2"
U+002D U+0032
"-2"
No selected invisible characters found
{"values":["-2","10","3"],"defaultSorted":["-2","10","3"],"numericSorted":["-2","3","10"],"numericLabels":["-2","10","3"]}
{"values":["-2","10","3"],"defaultSorted":["-2","10","3"],"numericSorted":["-2","3","10"],"numericLabels":["-2","10","3"]}

The same cleaned elements admit two different orders

Each observer constructs a fresh list from the supplied string followed by 10 and 3. After the marked two is cleaned, the default result is 10, 2, 3. Subtraction comparison yields 2, 3, 10. The plain two control produces the same pair without an edit. The ten control retains two identical 10 entries and places 3 first only under the numeric comparator. The negative control puts minus two first under both choices but still disagrees on 10 versus 3. Numeric labels accompany every element so conversion failures remain visible. In particular, the pre-cleanup marked value converts to NaN; its recorded comparator output is not evidence of a meaningful numeric order.

Arithmetic ordering does not validate the list

The earlier numeric-collation page compares Intl.Collator options for item labels containing digits. This observer calls Array.sort directly with no locale machinery, and its intended numeric controls contain complete ordinary number strings. We copy the list before each sort, keeping the unsorted values available in the record. The subtraction comparator deliberately illustrates a common local choice rather than implementing a validated sorting service. NaN comparisons do not provide a total numeric order. We do not infer anything useful from the position of the invalid marked element before cleanup. No test here measures mixed objects, sparse arrays, huge datasets, sort performance or an application’s treatment of missing values.

Choose the ordering rule after establishing the value domain

Decide whether elements are numbers or labels, then validate the domain required by the chosen comparator. Do not apply subtraction blindly to values that remain invalid after cleanup. A comparison function can return without throwing and still fail to express the intended relationship. Our plain controls show that default ordering remains different even when every conversion is finite. Preserve the original strings if lexical identity matters, and distinguish numeric conversion from the displayed element values, which remain strings in this matrix. The downloadable runs specify exact lists, duplicate controls and both orders. They do not prescribe one comparator for every dataset or claim that character cleanup itself sorts any homepage input.

Reproduce this test

Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.

node reproduce.cjs

Reference and next check

ECMAScript Array.prototype.sort provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.