mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-02 07:59:52 -04:00
docs(phase-37): S108 record — accelerators P37 S108 (ten), decision log P37 S108, cookbook §459 (the declaration layer's byte facts), SETUP §P37 S108, cookbook index; the redraw + indented-definition class: D49–D52 + HD5–HD6 (7,283 canonical) | 🛑 T4 in progress (S108)
This commit is contained in:
@@ -1969,3 +1969,25 @@ CLAIM, not a fact — two were refuted on bytes on 2026-09-10.**
|
||||
24-class probe closed 4 at the first candidate, all by `reloc`. Known limits: a same-name donor that is a DIFFERENT
|
||||
function scores high (the ranking is by line count only); a pair whose REL addends differ cannot match (MIPS REL: the
|
||||
addend is in the instruction, the object comparison sees the symbol name).
|
||||
|
||||
### §P37 S108 — 2026-09-12: the declaration layer run to its floor (Phase 37 T4)
|
||||
|
||||
- **`tools/restruct.py`** (rung D) — `defs_visible` indexes the shared headers each SIBLING TU includes (a binary's own shared bodies were
|
||||
"external") and, as a third level, a callee's fleet-unique signature when no member/main/resident TU defines it; `unit_call_counts` (the K&R
|
||||
arity read from the TU AND its included bodies; a definition head is `) {` or a K&R head); `--unalias`: a data-typed declaration of the real
|
||||
name (`extern s32 f;` / `extern char f[];`) becomes the prototype, a header-side arity error marks the INCLUDING TUs, escalation counts
|
||||
attempts; `--callee F --body FILE` gained **`--with REL=FILE`** (a caller-body edit inside the same judged unit, repeatable), **`--map-data`**
|
||||
(with `--all-defs`: the body's `D_` symbols renamed to each copy's own by order of first appearance; a count mismatch REFUSES), header-borne
|
||||
definitions excluded from `--all-defs` (a variant is another function); **`--redraw VERDICT[:cause-substring]`** (`DECL-NONE:visible`).
|
||||
`--unalias` runs under `--apply` (the S107 checkpoint's line lacked it). Selftest 54/54.
|
||||
- **`tools/argcheck.py`** — every definition per name kept (`_ALL`), `resolve_definition(name, tu)`: one fleet-wide signature → it; else the
|
||||
declaring TU's own binary's; else main/resident; else `cross_binary=True`; rows carry `kr_marked` (the `// K&R:` marker read from the RAW
|
||||
line); `DEF` allows leading blanks (indented file-scope definitions); the K&R loop feeds `_ALL` regardless of `out`.
|
||||
- **`tools/type_census.py` / `tools/readability_progress.py`** — lying declarations exclude `kr_marked` and `cross_binary` rows, which are
|
||||
published APART (`kr_sites`/`kr_callees`, `cross_binary`/`cross_callees`; two new TSV columns, read by name).
|
||||
- **`tools/delever_oracle.py --snapshot-baseline`** — REFUSES an empty or shrunken `build/` before writing (it had stamped "HEAD, 0 objects").
|
||||
- **`tools/restruct_cycle.sh`** — skips the fleet run when `git status src` is clean after a batch (the previous R22 stands).
|
||||
- One-off drivers under `.run/P37/restruct/` (ignored; every command line is in the phase log): `sig_cycle.sh` (the parked signature bodies:
|
||||
oracle refresh → `--callee … --body` → R22 → log → commit; a `--tu` fallback when copies differ), `strip_banners.py` (the §8b banner comments).
|
||||
- **Gotchas:** after `kill -INT` on a judge WAIT for its exit (`ps`) before `--restore`; `pgrep -f`/`pkill -f` never with a literal your own
|
||||
command line contains (`restruct_cycl[e]`).
|
||||
|
||||
@@ -998,3 +998,33 @@ cross-address copies produce IDENTICAL probe bodies, and a hash-keyed scratch fi
|
||||
`pkill -f` with a literal from your own command line kills your own shell (R79, hit again at 14:20).
|
||||
8. **A fallback ladder that re-judges hundreds of objects per step needs an escalation rule** (a second caller of the same kind → all
|
||||
callers), or a 20-file chain costs 20 × 20 s per unit.
|
||||
|
||||
## P37 S108 (2026-09-12) — the declaration layer's day of instrument findings: five ways a census was blind to its own population
|
||||
|
||||
The session ran rung D over the fleet for ~9 h and landed ≈90,000 declarations canonical — and almost every jump came from finding a
|
||||
class the instruments could not see, not from the engine getting better. Each of these would have paid on day one of T4:
|
||||
|
||||
1. **A definitions index must follow the sibling TUs' includes.** Since Phase 35 every shared body is a header included by ONE member TU;
|
||||
an index that reads the sibling `.c` files but not the headers they include sees a binary's own shared functions as "external".
|
||||
`t4_D21` drew 300 TUs for 0 units on exactly this; the fix was one loop, and the next batch put 10,123 declarations canonical.
|
||||
2. **A function's identity is (binary, definition), never the bare name (R48, again).** `argcheck.definitions()` kept one signature per
|
||||
name with `setdefault`; 6,419 names carry more than one body; 2,832 correct declarations read as lies for two sessions. Resolve per
|
||||
declaring binary: one fleet-wide signature → it; else the TU's own binary's; else main/resident; else "cross-binary", counted apart.
|
||||
3. **A `^`-anchored definition regex misses INDENTED file-scope definitions** — 116 "disagreements" were this, and the fix (leading blanks
|
||||
allowed) surfaced ~2,200 more drawable TUs whose lying declarations had never been rows at all: the census's denominator grew by
|
||||
~10,000 after the instrument was repaired (`t4_D50`–`D52`: 7,208 canonical in three batches).
|
||||
4. **A call-arity counter must read the included bodies too, and "a `{` later on the line" is not a definition head.** 306 K&R markers read
|
||||
`? of N args` for a known count (the short call sat in a shared body the TU includes), two read `[]` for `if (f() != 0) {`.
|
||||
5. **An empty or shrunken `build/` is a refusal, not a snapshot (R68).** The snapshot tool stamped "HEAD, 0 objects" over 7,428 objects of
|
||||
another tree; a stopped R22 (`make clean` done, fleet run not) is the ordinary way to get there.
|
||||
6. **After `kill -INT` on a judge, WAIT for its exit before `--restore`** — it honours the signal only after its in-flight units (~2 min);
|
||||
a restore run 8 s later consumed `inflight.json` and left six files with no tool-side restore. And `pgrep -f`/`pkill -f` with a literal
|
||||
your own command line contains kills your own shell (R79 — hit twice more; the safe spelling brackets a character: `restruct_cycl[e]`).
|
||||
7. **A flat-yield stop is an inference; bucket the remainder by ledger verdict before stopping.** Two low-yield batches read as "the rest is
|
||||
non-actionable" while 3,700 (TU, callee) pairs had never been judged — they were the `md_*` modules, ranked low by the planner.
|
||||
8. **Same code over per-overlay data is one body with a symbol map, not 133 bodies.** `--map-data` (the pack body's `D_` symbols renamed to each
|
||||
copy's own, by order of first appearance; a count mismatch refuses) landed the 132-copy class in one judged unit — 264 pins.
|
||||
9. **"The pin was the missing argument" needs the CALLERS in the same judged unit as the definition** (`--with REL=FILE`): a declaration change
|
||||
alone is `too few arguments` at every zero-argument caller, and the pack's "one caller" was three once the fleet was grepped.
|
||||
10. **A definition in a shared header whose short callers sit in other shared bodies lands as a K&R-style DEFINITION** — no per-TU `()`
|
||||
declaration can hide a prototype that is in scope before the call; the ladder must count ATTEMPTS to escalate there (it counted files).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **Generated by `tools/cookbook_index.py` — do not hand-edit** (R33). Regenerate after adding a cookbook section.
|
||||
>
|
||||
> `docs/matching-cookbook.md` is ~716 KB / 1176 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses.
|
||||
> `docs/matching-cookbook.md` is ~716 KB / 1177 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses.
|
||||
|
||||
**How to use:** name what you SEE in the diff (a stolen delay slot, an extra `la`, a swapped register pair, a `conflicting types` error), find that symptom below, read those sections first. If nothing fits, THEN grind — and add a section when you win.
|
||||
|
||||
@@ -551,7 +551,7 @@
|
||||
- **§497** — ★ — A BODILESS `typedef struct Tag Alias;` DEFINES THE ALIAS, NOT THE TAG: THE CARRIER'S FALSE "CONFLICTING BODIES" REFUSAL (P32 T1b; ov_SC02_017 `func_80186C64` isolation) <sub>L36705</sub>
|
||||
- **§458** — Struct spelling is a per-access dial: the T2 probe's byte evidence (Phase 37 S106) <sub>L37886</sub>
|
||||
|
||||
### types, signedness & load/store width (98)
|
||||
### types, signedness & load/store width (99)
|
||||
|
||||
- **§3-I1** — Unsigned range check: `(x - lo) < (hi-lo)` → `addiu`+`sltiu` <sub>L41</sub>
|
||||
- **§3-I2** — Byte mask forces `andi` even after `lbu` <sub>L47</sub>
|
||||
@@ -651,8 +651,9 @@
|
||||
- **§481** — ★★★ — `conflicting types` IS A SAME-SCOPE ERROR; ACROSS SCOPES IT IS ONLY A WARNING (P31 S77, `main:func_8001FC08`, 400 ins) <sub>L35911</sub>
|
||||
- **§496** — ★★ — A CARRIED-TYPE TEST THAT ASSUMES THE OVERLAY INCLUDE SET SILENTLY DROPS A RESIDENT TYPEDEF (P32 T1a; byte-proven, resident `func_800D128C` isolation) <sub>L36671</sub>
|
||||
- **§497** — ★ — A BODILESS `typedef struct Tag Alias;` DEFINES THE ALIAS, NOT THE TAG: THE CARRIER'S FALSE "CONFLICTING BODIES" REFUSAL (P32 T1b; ov_SC02_017 `func_80186C64` isolation) <sub>L36705</sub>
|
||||
- **§459** — The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can and cannot hide <sub>L37912</sub>
|
||||
|
||||
### declarations, prototypes & K&R (122)
|
||||
### declarations, prototypes & K&R (123)
|
||||
|
||||
- **§3-T4** — Branch polarity: invert the source condition to flip gcc's chosen branch <sub>L90</sub>
|
||||
- **§8c** — Splitting a TU means rebuilding its DECLARATION ENVIRONMENT, not moving text (Phase 26 session 6) <sub>L456</sub>
|
||||
@@ -776,6 +777,7 @@
|
||||
- **§481** — ★★★ — `conflicting types` IS A SAME-SCOPE ERROR; ACROSS SCOPES IT IS ONLY A WARNING (P31 S77, `main:func_8001FC08`, 400 ins) <sub>L35911</sub>
|
||||
- **§487** — ★★★ — THE PSX LOADER'S PER-VERSION SIGNATURE SETS ARE A FREE PROVENANCE ORACLE: main's "WALL" BAND IS LIBPAD 4.2.1 (P31 S78) <sub>L36160</sub>
|
||||
- **§495** — ★★★ — THE VERBATIM END-STATE (P31 S80 #10): TWO DEF-SIDE DECLARATION WALLS, A "BANK" THAT WAS THE ASSEMBLY, AND A GATE THAT DROPPED A BANK ON EXIT 0 <sub>L36630</sub>
|
||||
- **§459** — The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can and cannot hide <sub>L37912</sub>
|
||||
|
||||
### jump tables & switches (72)
|
||||
|
||||
@@ -2988,6 +2990,7 @@
|
||||
- **§456** — The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and launders (Phase 36 T7) <sub>L37765</sub>
|
||||
- **§457** — The lever-removal move catalog, S105: eight TU batches, 42 of 42 at 0 (Phase 36 T7) <sub>L37814</sub>
|
||||
- **§458** — Struct spelling is a per-access dial: the T2 probe's byte evidence (Phase 37 S106) <sub>L37886</sub>
|
||||
- **§459** — The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can and cannot hide <sub>L37912</sub>
|
||||
|
||||
|
||||
---
|
||||
@@ -4176,3 +4179,4 @@ Notes routinely quote that as a section id. This table resolves it. Grep bait: `
|
||||
| L37765 | §456 | The lever-removal move catalog: what the S104 agents found under ~205 pins, barriers and l |
|
||||
| L37814 | §457 | The lever-removal move catalog, S105: eight TU batches, 42 of 42 at 0 (Phase 36 T7) |
|
||||
| L37886 | §458 | Struct spelling is a per-access dial: the T2 probe's byte evidence (Phase 37 S106) |
|
||||
| L37912 | §459 | The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can |
|
||||
|
||||
@@ -3901,3 +3901,27 @@ For those, no single-TU spelling exists; the file-layout phase's split is the fi
|
||||
**What it cost.** ~4 h of the session in five unalias passes and two planner corrections; 120 of 149 landed; 29 named. **Sooner:** read
|
||||
the census's "lying declaration" rows against the DEFINITIONS' names before pricing — a definition under another name is a hole in the
|
||||
denominator, and the planner should have counted only rows the engine can act on from the first batch (`DECL-NONE` now settles them).
|
||||
|
||||
## P37 S108 (2026-09-12) — T4 run to its measured floor: the declaration layer's instruments were the campaign
|
||||
|
||||
**Context and belief.** The checkpoint priced T4's remainder as six mechanical steps (the D cycle again, 29 alias functions, the headers,
|
||||
13 parked signature bodies, the banners, the census). The D cycle had put ≈17,300 declarations canonical in S107 and its first batch of
|
||||
S108 was "the test of the DECL-NONE settling".
|
||||
**What happened.** That batch drew 300 TUs for 0 units — and the reason was the engine's definitions index, not the population: it never
|
||||
looked inside the shared headers a SIBLING TU includes, so every binary's own shared functions were "external". One loop fixed it and the
|
||||
next fifteen batches put 76,075 declarations canonical. The same day, four more blind spots each moved the number by thousands: argcheck
|
||||
keyed definitions by bare name (2,832 false lies — a same-address function with three bodies), its `DEF` regex missed indented definitions
|
||||
(a whole class of callers never became rows; 7,208 canonical in three batches after the fix), the arity counter never read included bodies,
|
||||
and the "flat yield" stop I made at D36 left 3,700 never-judged pairs in the `md_*` modules. **The census went 98,648 → 13,832 → 8,830 →
|
||||
2,367 lying declarations, each step an instrument repair, not a new rung.**
|
||||
**The pivots.** (1) The planner's rows must be rows the engine can act on, and the stop rule is the remainder bucketed by ledger verdict
|
||||
(R117) — never a yield curve. (2) Lying declarations are counted per binary (a function is identified by its definition — the plan's own
|
||||
rule, now the instrument's), with two populations counted APART: byte-proven K&R sites (5,082, each marked with its cause) and cross-binary
|
||||
declarations (511: the fleet's definitions disagree and the binary has none). (3) The parked signature bodies are not "apply the patch":
|
||||
`func_80157D20`'s 132 copies needed a per-copy data-symbol map (`--map-data`), `func_80029D3C` needed its three zero-argument callers in the
|
||||
same judged unit (`--with`), `func_80188A30` needed only its return type (`void` → `s32`, reorg's delay-slot fill), and the `md_SC07_004`
|
||||
pair needs a caller one level up re-signed too — the definition-side change is a UNIT of definition + callers + declarations, judged once.
|
||||
**What it cost.** ~9 h of one session, 60 commits, ~35 fleet gates (every one 218/218); one self-inflicted race (a restore run against a
|
||||
judge still unwinding) and two shell kills by `pgrep -f`. **Sooner:** the five instrument checks above are each a one-line control against
|
||||
a known case (a shared-header callee; a three-body name; an indented definition; a short call in an included body; an empty `build/`) —
|
||||
they belong in `type_census --selftest` and `restruct --selftest` from the day the census exists, not in the campaign's log.
|
||||
|
||||
@@ -37908,3 +37908,35 @@ member, the site's own cast kept: `*(u16 *)((((struct { s32 p; } *)&D_801C7E30)-
|
||||
the body closes with members everywhere but that one site, and that site with both sides `/s`. The same recipe on the ORIGINAL text (every
|
||||
site a cast) is also IDENTICAL: the pointer read's `/s` is what the scheduler's escape needed, whichever side the store took. R1 is the first
|
||||
entry of the engine's recipe registry (R2 = a18's `extern T X[]`, R3 = f3's walked pointer); T6 runs the registry on every kept cast.
|
||||
|
||||
## §459 — The declaration layer's byte facts (Phase 37 T4, S107–S108): what a prototype spelling can and cannot hide
|
||||
|
||||
Rung D put ≈90,000 call declarations canonical (the definition's ANSI signature) byte-identically, judged per object; the residue and the
|
||||
signature-side landings are the byte facts worth keeping (every one gated `check-all: 218 passed, 0 failed of 218`).
|
||||
|
||||
1. **A byte-proven K&R site is a per-TU fact, but a definition in a shared header makes it a per-DEFINITION fact.** A TU whose calls pass
|
||||
fewer arguments than the definition takes keeps `extern ret f(); // K&R: n of m args (…)` — 5,082 such sites over 155 callees, counted
|
||||
apart from the lies. When the DEFINITION sits in a shared header (`func_80162CCC.h`) and the short call sits in another shared body
|
||||
(`func_80164DB0.h:5`), no per-TU `()` can hide the prototype already in scope: the definition itself is spelled K&R-style (`void
|
||||
func_80162CCC(a0) u8 *a0; {`) — **IDENTICAL on 288 objects, 145 files** (`t4_ua13`; same shape `func_8016F0E4` 296 objects, `func_80131CA8`
|
||||
202 in S107). gcc 2.7.2's K&R head changes nothing in the callee's bytes when the parameter types are the byte-true ones.
|
||||
2. **"The pin was the missing argument" is a UNIT of definition + callers.** `func_80029D3C`'s pins (P36) faked `$4`; the truth is `s32
|
||||
func_80029D3C(s32 n)` — and every zero-argument caller then passes the value its pin had loaded: `s0 = func_80029D3C(D_8011DB1A);`
|
||||
(ov_SC07_002), and in two shared bodies a local compared then passed — `s16 cmp79; if (... (cmp79 = *(s16 *)(p + 0x79)) != 1000) angle =
|
||||
func_80029D3C(cmp79);` — **IDENTICAL on every recipe (2,177 files)**: local-alloc homes a local that dies at the call in `$a0`, exactly where
|
||||
the pin had put it. A declaration change alone is `too few arguments` at each such caller; grep the fleet for `f()` before trusting a
|
||||
pack's "one caller" (it was three).
|
||||
3. **A return type is observable in a delay slot (§162f1 operated).** `func_80188A30`: `void` → `s32` with the body unchanged (no `return`; the
|
||||
function falls off the end) — reorg's `fill_slots_from_thread` refuses to steal `li v0,24` into the `beqz` slot once `$v0` is live at the
|
||||
epilogue (`reorg.c:4274`); the `"memory"` barrier that had faked the `nop` comes off. IDENTICAL, 1 file.
|
||||
4. **Same code over per-overlay data is one body plus a symbol map.** `func_80157D20` in 132 overlays: the pack body names `D_80192768`
|
||||
(ov_SC04_011's table); each copy's own definition names its own (`D_801806BC` in ov_MAIN_012, …) at the same site. Renaming the pack's `D_`
|
||||
symbols to each copy's by ORDER OF FIRST APPEARANCE (`--map-data`; a count mismatch refuses) landed all 132 as `void func_80157D20(void
|
||||
*param_1, s32 param_2)` — **IDENTICAL, 2,105 files, 264 `$4/$5` pins gone**. The 133rd "definition" was a variant header (`__99380536.h`,
|
||||
different bytes for 3 overlays): a variant is another function, left with its includers' declarations.
|
||||
5. **What a prototype cannot hide (the residue's causes, each a ledger row):** a caller in one jr-merged TU whose bytes disagree with the
|
||||
definition's head (the original was separate translation units — the file-layout phase's; 10 functions); a `void` definition whose
|
||||
callers USE `$v0` (`void value not ignored` — the definition's return type is the lie: a definition-side change, 5 functions); a prototype
|
||||
naming a type the TU cannot see (`Pos800D20C0`; 1,120 rows — T5's canonical types); `conflicting types` from a second declaration
|
||||
elsewhere in the TU (417); a zero-argument caller that passes its OWN incoming `$a0` through (`func_801A6A18(void) { func_801A1E94(); }`) —
|
||||
the fix re-signs the caller too, one level up.
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -716,6 +716,17 @@ bucketed by what each bucket needs before any plan is proposed. **Candidates for
|
||||
|
||||
- **2026-09-12 — T4 batch `t4_HD6`** (`.run/P37/restruct/run_t4_HD6.log`, `batch_t4_HD6.json`): `restruct: batch t4_HD6 rung D — 271 files (headers; 271 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0 in 16 s wall · final 271/271 identical · written 0 files` → R22 (`.run/P37/baseline/r22_t4_HD6.log`) **`(no src change — the previous R22 stands)`** (``) → census `(census skipped)`.
|
||||
|
||||
- **S108 — the targeted redraw + the indented-definition class (`cycle_t4i.log`, `REDRAW=DECL-NONE:visible`):** `t4_D49` 203 TUs · 90 units: 55
|
||||
canonical / 35 kept (`f76538941`); then the argcheck cache rebuilt on the fixed `DEF` and **2,247 TUs became drawable** — callers of INDENTED
|
||||
file-scope definitions had never been rows: `t4_D50` 2,802 units: 2,791 canonical (`a0c26f587`) · `t4_D51` 2,802: 2,778 (`6d822ff2c`) ·
|
||||
`t4_D52` 1,659: 1,639 (`f74d1e077`); headers `t4_HD5` 281: 24 units, 20 canonical / 4 K&R (`3d9c8aed1`) · `t4_HD6` 0 units (`8a84409a1`, no
|
||||
src change — the cycle's new skip); every gated batch `check-all: 218 passed, 0 failed of 218`. Chained: `cycle_t4j.log` batches 53–62 for the
|
||||
~1,500 drawable TUs left. **The record banked (R30):** accelerators **P37 S108** (ten entries: the five blind spots, the kill/restore race,
|
||||
the flat-yield stop, `--map-data`, `--with`, the K&R-style definition), decision log **P37 S108** (the census's four steps were instrument
|
||||
repairs; the stop rule is the bucketed remainder; a signature change is a unit of definition + callers + declarations), cookbook **§459**
|
||||
(the declaration layer's byte facts: the K&R-style definition on 288 objects, the local homed in `$a0`, the return type in a delay slot, the
|
||||
per-overlay data map, what a prototype cannot hide), SETUP **§P37 S108** (every option and gotcha), the cookbook index (1,177 sections).
|
||||
|
||||
## 🛑 SESSION CHECKPOINT — S107 (2026-09-12, FINAL — written for a FRESH session at 84 % context; the session's last commit follows this): gate 1 APPROVED, **T0 ☑ T1 ☑ T2 ☑ T3 ☑ — T4 IN PROGRESS (☐)** — 🛑 **T4 NEXT: resume the declaration layer where the cycle stopped (below, §1 "T4 — where it stands and the exact next commands"); xHigh** | R22 `check-all: 218 passed, 0 failed of 218` at `f2b58011e` (every one of the 21 T4 commits carries its own) | HEAD after this commit is the checkpoint's commit; tree clean; nothing pushed after `79b2f6f15` (Drew pushes, R6) | last batch `t4_HD6` on 3d9c8aed1: 271 files (headers; 271 drawable) · 0 declaration units: 0 canonical / 0 promoted / 0 K&R marked / 0 aliases typed / 0 __builtin_abs → abs / 0 kept · compiles 0
|
||||
|
||||
**Replay this block into the chat at the next session start (R64); it is the ONLY in-phase context the next session inherits. Everything below
|
||||
|
||||
Reference in New Issue
Block a user