New Terminal Output:

root@f3f8d6319494:/app# cat > /app/termzip_ansi.py << 'EOF'
s
        frames = [f.read(w * h) for _ in range(n_frames)]

    out = []
    cursor_r, cursor_c = 1, 1

    # Frame 0: write non-space characters
    for r in range(h):
        row = frames[0][r*w:(r+1)*w]
        non_space = [c for c in range(w) if row[c] != 32]
        runs = find_runs(non_space)
        for start, end in runs:
            encode_move(out, cursor_r, cursor_c, r+1, start+1)
            out.append(row[start:end+1].decode('latin1'))
            cursor_r, cursor_c = r+1, end+2
    out.append('\x1e')

    # Subsequent frames
    for i in range(1, n_frames):
        # Find changed rows
        changed_rows = [r for r in range(h) if frames[i-1][r*w:(r+1)*w] != frames[i][r*w:(r+1)*w]]

        if not changed_rows:
            out.append('\x1e')
            continue

        for r in changed_rows:
            prev_row = frames[i-1][r*w:(r+1)*w]
            curr_row = frames[i][r*w:(r+1)*w]
            changes = [c for c in range(w) if prev_row[c] != curr_row[c]]
            runs = find_runs(changes)

            # Calculate cost of EL + rewrite
            cost_erase = 1  # CR
            dr = r - (cursor_r - 1)
            if dr > 0:
                cost_erase += dr  # \n * dr
            elif dr < 0:
                cost_erase += 4 + len(str(-dr))  # ESC[nA
            cost_erase += 4 + w  # ESC[2K + row content

            # Calculate cost of partial updates
            cost_partial = 0
            temp_r, temp_c = cursor_r, cursor_c
            for start, end in runs:
                if temp_r == r+1:
                    dc = (start+1) - temp_c
                    if dc > 0:
                        cost_partial += 4 + len(str(dc))
                    elif dc < 0:
                        cost_partial += min(-dc, 4 + len(str(-dc)))
                else:
                    cost_partial += 1  # CR
                    dr = r - (temp_r - 1)
                    if dr > 0:
                        cost_partial += dr  # \n * dr
                    elif dr < 0:
                        cost_> import struct
> import sys
>
r> def find_runs(changes):
i>     """Find contiguous runs of changed columns."""
>     runs = []
n(st>     if not changes:
>         return runs
>     run_start = changes[0]
 c>     run_end = changes[0]
>     for c in changes[1:]:
>         if c == run_end + 1:
>             run_end = c
>         else:
>             runs.append((run_start, run_end))
>             run_start = run_end = c
>     runs.append((run_start, run_end))
>     return runs
>
(> def encode_move(out, from_r, from_c, to_r, to_c):
>     """Encode cursor movement from (from_r, from_c) to (to_r, to_c)."""
>     if from_r == to_r and from_c == to_c:
>         return
>     if from_r == to_r:
>         # Same row: use CUF or CUB (or backspace for small moves)
 >         dc = to_c - from_c
c>         if dc == 1:
>             out.append(' ')  # Space and backspace is 2 bytes, same as ESC[1C
>             out.append('\b')
(>         elif dc > 0:
>             out.append(f'\x1b[{dc}C')
>         elif dc == -1:
>             out.append('\b')
>         elif dc >= -3:
>             out.append('\b' * (-dc))
>         else:
>             out.append(f'\x1b[{-dc}D')
>     else:
>         # Different rows
>         if from_c == 1 and to_c == 1:
>             # At col 1, going to col 1: use newlines
>             dr = to_r - from_r
>             if dr > 0:
>                 out.append('\n' * dr)
>             else:
>                 out.append('\x1b[' + str(-dr) + 'A')
>         else:
>             # CR + vertical + horizontal
>             out.append('\r')
>             dr = to_r - from_r
>             if dr > 0:
>                 out.append('\n' * dr)
>             elif dr < 0:
>                 out.append(f'\x1b[{-dr}A')
>             if to_c > 1:
>                 out.append(f'\x1b[{to_c-1}C')
>
> def main():
>     if len(sys.argv) != 2:
>         sys.exit(1)
>
>     with open(sys.argv[1], 'rb') as f:
>         magic = f.read(4)
>         if magic != b'TZA1':
>             sys.exit(1)
>         w, h = struct.unpack('<HH', f.read(4))
>         n_frames, max_bytes = struct.unpack('<II', f.read(8))
>
>         # Read all frames
>         frames = [f.read(w * h) for _ in range(n_frames)]
>
>     out = []
>     cursor_r, cursor_c = 1, 1
>
>     # Frame 0: write non-space characters
>     for r in range(h):
>         row = frames[0][r*w:(r+1)*w]
>         non_space = [c for c in range(w) if row[c] != 32]
>         runs = find_runs(non_space)
>         for start, end in runs:
>             encode_move(out, cursor_r, cursor_c, r+1, start+1)
>             out.append(row[start:end+1].decode('latin1'))
>             cursor_r, cursor_c = r+1, end+2
>     out.append('\x1e')
>
>     # Subsequent frames
>     for i in range(1, n_frames):
>         # Find changed rows
>         changed_rows = [r for r in range(h) if frames[i-1][r*w:(r+1)*w] != frames[i][r*w:(r+1)*w]]
>
>         if not changed_rows:
>             out.append('\x1e')
>             continue
>
>         for r in changed_rows:
>             prev_row = frames[i-1][r*w:(r+1)*w]
>             curr_row = frames[i][r*w:(r+1)*w]
>             changes = [c for c in range(w) if prev_row[c] != curr_row[c]]
>             runs = find_runs(changes)
>
>             # Calculate cost of EL + rewrite
>             cost_erase = 1  # CR
>             dr = r - (cursor_r - 1)
>             if dr > 0:
>                 cost_erase += dr  # \n * dr
>             elif dr < 0:
>                 cost_erase += 4 + len(str(-dr))  # ESC[nA
>             cost_erase += 4 + w  # ESC[2K + row content
>
>             # Calculate cost of partial updates
>             cost_partial = 0
>             temp_r, temp_c = cursor_r, cursor_c
>             for start, end in runs:
>                 if temp_r == r+1:
>                     dc = (start+1) - temp_c
>                     if dc > 0:
>                         cost_partial += 4 + len(str(dc))
>                     elif dc < 0:
>                         cost_partial += min(-dc, 4 + len(str(-dc)))
>                 else:
>                     cost_partial += 1  # CR
>                     dr = r - (temp_r - 1)
>                     if dr > 0:
>                         cost_partial += dr  # \n * dr
>                     elif dr < 0:
>                         cost_partial += 4 + len(str(-dr))
>                     if start+1 > 1:
>                         cost_partial += 4 + len(str(start))
>                 temp_r, temp_c = r+1, end+2
>             cost_partial += len(changes)
>
>             # Choose cheaper
>             if cost_erase <= cost_partial:
>                 encode_move(out, cursor_r, cursor_c, r+1, 1)
>                 out.append('\x1b[2K')
>                 out.append(curr_row.decode('latin1'))
>                 cursor_r, cursor_c = r+1, w+1
>             else:
>                 for start, end in runs:
>                     encode_move(out, cursor_r, cursor_c, r+1, start+1)
>                     out.append(curr_row[start:end+1].decode('latin1'))
>                     cursor_r, cursor_c = r+1, end+2
>
>         out.append('\x1e')
>
>     sys.stdout.write(''.join(out))
>
> if __name__ == '__main__':
>     main()
> EOF
root@f3f8d6319494:/app#
