<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/env perl

use strict;
use warnings;
use Time::HiRes qw(usleep);
use utf8;
use open qw(:std :utf8);
use Term::ReadKey;

# Define an expanded set of emojis
my @emojis = (
    'ðŸ˜Š', 'ðŸ˜‚', 'ðŸ¤£', 'ðŸ˜', 'ðŸ¥°', 'ðŸ˜˜', 'ðŸ˜œ', 'ðŸ˜Ž', 'ðŸ¤”', 'ðŸ¤¯',
    'ðŸ‘', 'ðŸ‘', 'ðŸ™Œ', 'ðŸŽ‰', 'ðŸŽŠ', 'ðŸŽˆ', 'ðŸŽ', 'ðŸ†', 'ðŸ¥‡', 'ðŸ…',
    'â¤ï¸', 'ðŸ§¡', 'ðŸ’›', 'ðŸ’š', 'ðŸ’™', 'ðŸ’œ', 'ðŸ–¤', 'ðŸ¤', 'ðŸ¤Ž', 'ðŸ’”',
    'ðŸŒŸ', 'â­', 'âœ¨', 'ðŸ’«', 'ðŸŒˆ', 'â˜€ï¸', 'ðŸŒ¤ï¸', 'â›…', 'ðŸŒ¥ï¸', 'â˜ï¸',
    'ðŸŒŠ', 'ðŸŒ´', 'ðŸŒµ', 'ðŸŒ·', 'ðŸŒ¹', 'ðŸŒº', 'ðŸŒ¸', 'ðŸŒ¼', 'ðŸ€', 'ðŸ',
    'ðŸŽ', 'ðŸ', 'ðŸŠ', 'ðŸ‹', 'ðŸŒ', 'ðŸ‰', 'ðŸ‡', 'ðŸ“', 'ðŸ’', 'ðŸ‘',
    'ðŸ•', 'ðŸ”', 'ðŸŸ', 'ðŸŒ­', 'ðŸ¿', 'ðŸ§', 'ðŸ©', 'ðŸ¦', 'ðŸ­', 'ðŸ«',
    'ðŸ¶', 'ðŸ±', 'ðŸ­', 'ðŸ¹', 'ðŸ°', 'ðŸ¦Š', 'ðŸ»', 'ðŸ¼', 'ðŸ¨', 'ðŸ¯',
    'ðŸš€', 'âœˆï¸', 'ðŸš—', 'ðŸš•', 'ðŸš™', 'ðŸšŒ', 'ðŸŽï¸', 'ðŸš“', 'ðŸš’', 'ðŸš‘'
);

# Get terminal size
my ($width, $height) = GetTerminalSize();

# Initialize emoji positions
my @positions;
for (1..25) {  # Number of falling emojis
    push @positions, get_new_position(\@positions, 1);
}

# Hide cursor and enter alternate screen buffer
print "\e[?25l";
print "\e[?1049h";

# Main loop
while (1) {
    # Clear screen and move cursor to top-left
    print "\e[2J\e[H";

    my $output = '';
    for my $pos (@positions) {
        my ($x, $y, $emoji_index) = @$pos;
        $output .= "\e[${y};${x}H" . $emojis[$emoji_index];

        $pos-&gt;[1]++;  # Move emoji down
        if ($pos-&gt;[1] &gt;= $height) {
            @$pos = @{get_new_position(\@positions, 0)};
        }
    }

    print $output;
    usleep(50000);  # Animation speed

    # Check for 'q' key to quit
    if (defined(my $key = ReadKey(-1))) {
        last if $key eq 'q';
    }
}

# Show cursor and exit alternate screen buffer
print "\e[?25h";
print "\e[?1049l";

# Restore normal terminal behavior
ReadMode('normal');

sub get_new_position {
    my ($positions, $initial) = @_;
    my $min_distance = 3;  # Minimum distance between emojis
    my $max_attempts = 100;  # Maximum number of attempts to find a suitable position

    for (1..$max_attempts) {
        my $new_x = int(rand($width));
        my $new_y = $initial ? int(rand($height)) : 0;  # Random y for initial, 0 for resets
        my $new_emoji = int(rand(scalar @emojis));
        my $is_far_enough = 1;

        for my $pos (@$positions) {
            my ($x, $y) = @$pos;
            if (abs($x - $new_x) &lt; $min_distance &amp;&amp; abs($y - $new_y) &lt; $height / 4) {
                $is_far_enough = 0;
                last;
            }
        }

        if ($is_far_enough) {
            return [$new_x, $new_y, $new_emoji];
        }
    }

    # If we couldn't find a suitable position after max attempts, just return a random one
    return [int(rand($width)), $initial ? int(rand($height)) : 0, int(rand(scalar @emojis))];
}</pre></body></html>