Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

"Rubics Cube" game

by tos (Deacon)
on Mar 04, 2008 at 14:54 UTC ( [id://671890]=sourcecode: print w/replies, xml ) Need Help??
Category: GUI Programming
Author/Contact Info tos
Description: Dear Monks,

my way to gui-programming was heavily influenced by perl/Tk. It ever impressed me and I like the examples that come with „widget“. So i always wanted to create my own (bigger) Tk-application.

Someway the idea occured to me to tinker the „Rubics Cube“ with the instruments that perl/Tk offers. After first experiences with a graphical rather rudimentary approach the second attempt was an actual 3d-application.

This for me ambitious project led me to a broad variety of problems. Solving these improved (as i think) my way of programming and my comprehension. Additionally i had to recall some mathematical basics from linear algebra. Briefly said, my tinkering didn't make me more stupid :-).

Meanwhile qb3 („kjuBeeThree“), as the application is called, has grown up to 5000 lines of code and the result relatively satisfies me. Unfortunaly i didn't reach one of my aims. Qb3 isn't able to solve given twisted cubes on its own.

My ambition concerning qb3 has faded in the last time. There are a lot of other perlish things which now stronger attract my attention than this.

Nevertheless i would like to see qb3 getting better and more capable. Therefore i'll give my „Unfinished“ to the PM-community, hoping that perhaps one or two are in the mood to work along on qb3. It also might be that there are quite interesting techniques to be seen in the code. Especially the own „3d-engine“ could be of interest.

Qb3 has a lot of bugs and surely there are many things that could be done better. But if seen pragmatically and not with an academic claim i would like to say that the result so far is quite cute. I mostly like to see it shuffle while it's rotated.

Qb3 runs „out of the box“ on unix and windows if Tk.pm is installed. Regard the shape of the mousepointer. If it changes its appereance it's worth to click (and move). Try all mousebuttons.

For editing the source use vim with tabstop=3 and :set fdm=marker.

$Id: qb3,v 0.68 2008/03/04 14:30:10 tos Exp tos $

# md5sum qb3 81b7f0a98394acd86d51132094c20835 *qb3

You have to concatenate the four sourceparts in order. Then you'll have gotten the whole.

Download the parts as qb3-1,2,3,4. Then make a

cat qb3-? >qb3

the result should have the above shown md5sum

Happy playing and regards, tos

p.s.: as you surely already noticed this isn't my native language. So, please bear with me. Of course laughing is allowed. I can't hear it anyway. :-)

p.p.s.: there is a picture of qb3 on my homenode

#!/usr/bin/perl

#
#                                       _    _____ 
#            / / / /              __ _| |__|___ /             / / / / 
+   
#            [][][]/             / _` | '_ \ |_ \             [][][]/
#            [][][]/            | (_| | |_) |__) |            [][][]/
#            [][][]/             \__, |_.__/____/             [][][]/
#                                    |_|           
#
#            $Id: qb3,v 0.68 2008/03/04 14:30:10 tos Exp tos $
#
#
#             nomenclature
#
#             qb        : the whole rubics-cube-object
#             cube    : one cubic element of qb
#             slice    : cubes with a common x, y or z-axis-value

# uses {{{1
use warnings;
use strict;
use Data::Dumper;
use Tk;
use Tk::DialogBox;
use Tk qw/:eventtypes/;
use Getopt::Std;
use File::Basename;
use constant PI => (atan2(1,1) * 4);
#}}}1

# global vars {{{1
$|++;

our ($VERSION, $opt_h, $opt_v, $opt_V) 
                = ((qw($Revision: 0.68 $))[1], 0, 0, 0, 0);

getopts('hl:vV') && &opts;

our (
        $canvas, $mm, $qb, $qbCubes, $actCube, $zug, $saveIt, $tl, 
        $tlcs
);

$qbCubes = 3;    # 2 - 5 valid

our ($screenWidth, $screenHeight, $distance) = (250, 250, 50);
our $Z = 0;
our $highId = 0;
our $iColrFlag = 1;
our $rotSiSteps = 8;

our %rgb = (
                    "ora",    "#ff9933",
                    "pin",    "#ff66cc",
                    "red",    "#dd0000",
                    "gre",    "#00d000",
                    "blu",    "#3399ff",
                    "yel",    "#ffff33",
                    
                    # "oral",    "#ffce9e",
                    # "pinl",    "#ffbce8",
                    # "redl",    "#ec8282",
                    # "grel",    "#92cd92",
                    # "blul",    "#bcd9f8",
                    # "yell",    "#fffea1",

                    "oral",    "#ffefe0",
                    "pinl",    "#ffe8f7",
                    "redl",    "#f9d9d9",
                    "grel",    "#d9f7d9",
                    "blul",    "#e0efff",
                    "yell",    "#ffffe0",

                    "orad",    "#bf7326",
                    "pind",    "#bf4d99",
                    "redd",    "#a80000",
                    "gred",    "#008c00",
                    "blud",    "#2671bd",
                    "yeld",    "#bfbf26",

                    "orag",    "#70dc1e",
                    "ping",    "#70cf45",
                    "redg",    "#68b611",
                    "greg",    "#30ea11",
                    "blug",    "#3ddc51",
                    "yelg",    "#70f61e",

                    "oray",    "#fce00f",
                    "piny",    "#fcd13c",
                    "redy",    "#f2b300",
                    "grey",    "#b0f000",
                    "bluy",    "#c0e04c",
                    "yely",    "#fcff0f",

                    "orar",    "#59dbb7",
                    "pinr",    "#59c9ed",
                    "redr",    "#4da6a6",
                    "grer",    "#00eea6",
                    "blur",    "#11dbff",
                    "yelr",    "#59c9ed",

                    "DarkRed", "#8b0000",
                    "DarkGreen", "#006400",
                    "DarkBlue", "#00008b",
);

my $cRef = [
                    [$rgb{yel}, $rgb{yell}, $rgb{yeld},
                    $rgb{yelg}, $rgb{yely}, $rgb{yelr}], 

                    [$rgb{red}, $rgb{redl}, $rgb{redd},
                    $rgb{redg}, $rgb{redy}, $rgb{redr}], 

                    [$rgb{ora}, $rgb{oral}, $rgb{orad},
                    $rgb{orag}, $rgb{oray}, $rgb{orar}], 

                    [$rgb{gre}, $rgb{grel}, $rgb{gred},
                    $rgb{greg}, $rgb{grey}, $rgb{grer}], 

                    [$rgb{blu}, $rgb{blul}, $rgb{blud},
                    $rgb{blug}, $rgb{bluy}, $rgb{blur}], 

                    [$rgb{pin}, $rgb{pinl}, $rgb{pind},
                    $rgb{ping}, $rgb{piny}, $rgb{pinr}],
];

our %cD = our %cL = (
                        r1 => $cRef->[0], 
                        r2 => $cRef->[1], 
                        r3 => $cRef->[2], 
                        r4 => $cRef->[3], 
                        r5 => $cRef->[4], 
                        r6 => $cRef->[5],
); #}}}1

#---------------------------------------------------------------------
package matob;    # {{{1
#---------------------------------------------------------------------

    # 3D- and matrix-computing # - - - - - - - - - - - - - - - - - - -
+ 

    use constant EPSILON => 1e-09;
    
    sub new { # {{{2
    
        my ($pkg, $t) = @_;
    
        # $t = 0, nullmatrix
        # $t = 1, identity-matrix

        bless        [
                        [$t, 0, 0, 0],
                        [0, $t, 0, 0],
                        [0, 0, $t, 0],
                        [0, 0, 0, $t]
                    ], $pkg;
    
    }; # constructor }}}2


    sub freeRot { # {{{2
    
        # rotation around arbitrary axis which intersects the origin.
        # must have a norm of 1 to avoid changes of ojectsize

        shift;
        
        my ($ra, $phi) = @_;
        die if ref($ra) ne "vec3d";
    
        my $x = $ra->{p2}{lx};
        my $y = $ra->{p2}{ly};
        my $z = $ra->{p2}{lz};
        
        my $sphi = sin($phi);
        my $cphi = cos($phi);
        my $emcphi = 1 - cos($phi);
    
        my ($xmat, $mat1) = (new matob, new matob);
    
        $xmat->[0][0] = $x * $x * $emcphi + $cphi; 
        $xmat->[0][1] = $x * $y * $emcphi - $z * $sphi; 
        $xmat->[0][2] = $x * $z * $emcphi + $y * $sphi; 
        $xmat->[0][3] = 0;
    
        $xmat->[1][0] = $x * $y * $emcphi + $z * $sphi; 
        $xmat->[1][1] = $y * $y * $emcphi + $cphi; 
        $xmat->[1][2] = $y * $z * $emcphi - $x * $sphi; 
        $xmat->[1][3] = 0;
    
        $xmat->[2][0] = $x * $z * $emcphi - $y * $sphi; 
        $xmat->[2][1] = $y * $z * $emcphi + $x * $sphi; 
        $xmat->[2][2] = $z * $z * $emcphi + $cphi; 
        $xmat->[2][3] = 0;
    
        $xmat->[3][0] = 0; $xmat->[3][1] = 0;
        $xmat->[3][2] = 0; $xmat->[3][3] = 1;
    
        matMult($mat1,$xmat,$mm);
        matCopy($mm,$mat1);

    } # freeRot    }}}2
    
    sub invMat { # {{{2
    
        my $m = shift;
        
        # Inverses of 3x3-Matrices can be determined with 
        # determinants (hihi) and because the neutral element 
        # (line 3, row 3) at this point has no influence on the 
        # resulting determinant, we can simply reduce our matrix 
        # to 3x3 and then solve it by the rule of Sarrus
    
        my $det     = $m->[0][0] * $m->[1][1] * $m->[2][2]
                    + $m->[0][1] * $m->[1][2] * $m->[2][0]
                    + $m->[0][2] * $m->[1][0] * $m->[2][1]
                    - $m->[2][0] * $m->[1][1] * $m->[0][2]
                    - $m->[2][1] * $m->[1][2] * $m->[0][0]
                    - $m->[2][2] * $m->[1][0] * $m->[0][1];
    
        my $x =
        [
            [
                $m->[1][1] * $m->[2][2] - $m->[1][2] * $m->[2][1], 
                $m->[0][2] * $m->[2][1] - $m->[0][1] * $m->[2][2], 
                $m->[0][1] * $m->[1][2] - $m->[0][2] * $m->[1][1], 
            ],
            [
                $m->[1][2] * $m->[2][0] - $m->[1][0] * $m->[2][2], 
                $m->[0][0] * $m->[2][2] - $m->[0][2] * $m->[2][0], 
                $m->[0][2] * $m->[1][0] - $m->[0][0] * $m->[1][2], 
            ],
            [
                $m->[1][0] * $m->[2][1] - $m->[1][1] * $m->[2][0], 
                $m->[0][1] * $m->[2][0] - $m->[0][0] * $m->[2][1], 
                $m->[0][0] * $m->[1][1] - $m->[0][1] * $m->[1][0], 
            ],
        ];
        
        my $inv = new(1);
    
        for (my $z = 0; $z < 3; $z++) {
           for (my $s = 0; $s < 3; $s++) {
              $inv->[$z][$s] = $det * $x->[$z][$s];
            }
        }
    
        $inv;
    
    } # matInv }}}2

    sub matCopy { # {{{2

        # copy matrices
    
        my ($dest, $source) = @_;
    
        for (my $i=0; $i<4; $i++) {
           for (my $j=0; $j<4; $j++) {
                 $dest->[$i][$j] = $source->[$i][$j];
            }
        }
    } # matCopy }}}2
    
    sub matMult { # {{{2
    
        # multiply matrices

        my ($result, $mat1, $mat2) = @_;
    
        for (my $i=0; $i<4; $i++) {
           for (my $j=0; $j<4; $j++) {
              for (my $k=0; $k<4; $k++) {
                 $result->[$i][$j] += $mat1->[$i][$k] * $mat2->[$k][$j
+];
                }
            }
        }
        $result; # sollte auch fuer $mat1 verwendet werden ...
    
    } # matMult }}}2
    
    sub rotate { # {{{2
    
        # rotation around local x, y, and z-axis

        shift;
        my ($ax, $ay, $az) = @_;

        # x-rotationmatrix
        unless ($ax == 0) {
           
           my ($xmat, $mat1) = (new matob, new matob);
    
           $xmat->[0][0] = 1; $xmat->[0][1] = 0; 
            $xmat->[0][2] = 0; $xmat->[0][3] = 0;
    
           $xmat->[1][0] = 0; $xmat->[1][1] = cos($ax);
           $xmat->[1][2] = sin($ax); $xmat->[1][3] = 0;
            
           $xmat->[2][0] = 0; $xmat->[2][1] = -1 * sin($ax);
           $xmat->[2][2] = cos($ax); $xmat->[2][3] = 0;
    
           $xmat->[3][0] = 0; $xmat->[3][1] = 0;
           $xmat->[3][2] = 0; $xmat->[3][3] = 1;
    
           matMult($mat1,$xmat,$mm);
           matCopy($mm,$mat1);
        }
        # y-rotationmatrix
        unless ($ay == 0) {
           
           my ($ymat, $mat1) = (new matob, new matob);
    
           $ymat->[0][0] = cos($ay); $ymat->[0][1] = 0; 
            $ymat->[0][2] = -1 * sin($ay); $ymat->[0][3] = 0;
    
           $ymat->[1][0] = 0; $ymat->[1][1] = 1;
           $ymat->[1][2] = 0; $ymat->[1][3] = 0;
            
           $ymat->[2][0] = sin($ay); $ymat->[2][1] = 0;
           $ymat->[2][2] = cos($ay); $ymat->[2][3] = 0;
    
           $ymat->[3][0] = 0; $ymat->[3][1] = 0;
           $ymat->[3][2] = 0; $ymat->[3][3] = 1;
    
           matMult($mat1,$ymat,$mm);
           matCopy($mm,$mat1);
        }
        # z-rotationmatrix
        unless ($az == 0) {
           
           my ($zmat, $mat1) = (new matob, new matob);
    
           $zmat->[0][0] = cos($az); $zmat->[0][1] = sin($az); 
            $zmat->[0][2] = 0; $zmat->[0][3] = 0;
    
           $zmat->[1][0] = -1 * sin($az); $zmat->[1][1] = cos($az);
           $zmat->[1][2] = 0; $zmat->[1][3] = 0;
            
           $zmat->[2][0] = 0; $zmat->[2][1] = 0;
           $zmat->[2][2] = 1; $zmat->[2][3] = 0;
    
           $zmat->[3][0] = 0; $zmat->[3][1] = 0;
           $zmat->[3][2] = 0; $zmat->[3][3] = 1;
    
           matMult($mat1,$zmat,$mm);
           matCopy($mm,$mat1);
        }
    }; # rotate }}}2
    
    sub vecsPhi { # {{{2
    
        # expects R3-unit vectors as references on 3-element-lists
        my ($v, $w) = @_;

        #dotProd($v, $w) / (vNorm(@$v) * vNorm(@$w));
        dotProd($v, $w);
    
    } # vecsPhi }}}2

    sub vNorm { # {{{2
    
        my ($x, $y, $z) = @_;
    
        # square root of scalar product
        sqrt ($x * $x + $y * $y + $z * $z);
    
    } # vNorm }}}2

    sub dotProd { # {{{2
        
        # expects R3-unit vectors as references on 3-element-lists
        my ($v, $w) = @_;

        $v->[0] * $w->[0] + $v->[1] * $w->[1] + $v->[2] * $w->[2];
        
    }; #dotProd }}}2
    
    sub notNull { #{{{2
    
        # retuns 0 if value "near" enough to 0
        my $n = shift;
    
        abs($n) > EPSILON ? $n : 0;
    
    }; #notNull }}}2

# package matob; }}}1

#---------------------------------------------------------------------
package point3d; # {{{1
#---------------------------------------------------------------------

    use Data::Dumper;

   # lx, ly, lz :    # local coordinates
   # wx, wy, wz :    # worldcoordinatesystem is 'leftsystem'
   # sx, sy :         # screenkoordinates

    sub new { # {{{2
    
        my ($pkg, $X, $Y, $Z) = @_;
    
        bless {
                    lx    => $X,
                    ly    => $Y,
                    lz    => $Z,
        }, $pkg;
    
    }; # constructor }}}2


    sub creaHVWC { # {{{2
    
        # find out the worldcoordinates for horizontal and vertical
        # axis to get "artificial horizon"
        
        my ($p, $eAxis) = @_;
        return 0 if ref($p) ne "point3d";

        # multiplication with inverse matrix to reverse rotation for 
        # horizontal and vertical vector

        my $i = $mm->invMat;
        my ($lx, $ly, $lz) = @$eAxis;
        
        $p->{lx} =         $lx * $i->[0][0]
                       +    $ly * $i->[1][0]
                       +    $lz * $i->[2][0]
                       +            $i->[3][0];
        
        $p->{ly} =         $lx * $i->[0][1]
                       +    $ly * $i->[1][1]
                       +    $lz * $i->[2][1]
                       +            $i->[3][1];
        
        $p->{lz} =         $lx * $i->[0][2]
                        +    $ly * $i->[1][2]
                        +    $lz * $i->[2][2]
                        +            $i->[3][2];
    
        # $corr is necessary to keep the "Einheits"-lenght
        # on the rotation-axis-vector. Without this correction
        # the norm of the rotation-axis-vector will shrink or grow
        # due to inexact(floatingpoint) computings. In this case
        # the cube will suddenly shrink or grow after a couple
        # of rotations are made. Though the shrinking is funny
        # to look at, it's not desired.
        
        my $corr = sqrt(1 /     
                                      (
                                             $p->{lx} * $p->{lx}
                                         +    $p->{ly} * $p->{ly}
                                         +    $p->{lz} * $p->{lz}
                                    )
                            );
    
        # uncomment the following three lines if you want to see
        # the shrink-/grow-effekt. Therefore you have to do several
        # Button3-Motions of the whole cube.

        $p->{lx} *= $corr;
        $p->{ly} *= $corr;
        $p->{lz} *= $corr;
                    
    }; # creaHVWC }}}2

    sub creaWC { # {{{2
    
        my $p = shift;
    
        return 0 if ref($p) ne "point3d";
    
        $p->{wx} =         $p->{lx} * $mm->[0][0]
                        +    $p->{ly} * $mm->[1][0]
                        +    $p->{lz} * $mm->[2][0]
                        +                  $mm->[3][0];
    
        $p->{wy} =         $p->{lx} * $mm->[0][1]
                        +    $p->{ly} * $mm->[1][1]
                        +    $p->{lz} * $mm->[2][1]
                        +                  $mm->[3][1];
    
        $p->{wz} =         $p->{lx} * $mm->[0][2]
                        +    $p->{ly} * $mm->[1][2]
                        +    $p->{lz} * $mm->[2][2]
                        +                  $mm->[3][2];
    
    }; # creaWC }}}2

    sub project3dTo2d { # {{{2
    
        my $p = shift;
        return 0 if ref($p) ne "point3d";
    
        my $xoffset = $screenWidth/2;
        my $yoffset = $screenHeight/2;
    
        $p->{sx} = 200 * $p->{wx} / ($p->{wz} + $distance) + $xoffset;
        $p->{sy} = -200 * $p->{wy} / ($p->{wz} + $distance) + $yoffset
+;
    
    }; # project3dTo2d }}}2

    sub rotate { # {{{2

        my ($p, $ax, $ay, $az) = @_;
        my ($lx, $ly, $lz);

        unless ($ax == 0) { # x-axis-rotation
           
            ($ly, $lz) = ($p->{ly}, $p->{lz});

            $p->{ly} = $ly * cos($ax) - $lz * sin($ax);
            $p->{lz} = $ly * sin($ax) + $lz * cos($ax);

        }
        unless ($ay == 0) { # y-axis-rotation
           
            ($lx, $lz) = ($p->{lx}, $p->{lz});

            $p->{lz} = $lz * cos($ay) - $lx * sin($ay);
            $p->{lx} = $lz * sin($ay) + $lx * cos($ay);

        }
        unless ($az == 0) { # z-axis-rotation
           
            ($lx, $ly) = ($p->{lx}, $p->{ly});

            $p->{lx} = $lx * cos($az) - $ly * sin($az);
            $p->{ly} = $lx * sin($az) + $ly * cos($az);

        }

    } # rotate }}}2

    sub showAttr { # {{{2
        
        print Dumper(shift);

    }; #showAttr }}}2

# package point3d; }}}1

#---------------------------------------------------------------------
package line3d; # {{{1
#---------------------------------------------------------------------

    use Data::Dumper;

    sub new { # {{{2

        my ($pkg, $P1, $P2, $visible, $color, $name) = @_;
        
        return 0 if (
                                ref($P1) ne "point3d" 
                            or ref($P2) ne "point3d"
                        ); 

        bless {
                    p1            => $P1,
                    p2            => $P2,
                   visible     => $visible,
                   color        => $color,   
                   name        => $name,           
        }, $pkg;
    
    }; # constructor }}}2


    sub clear {  # {{{2
    
        my $l = shift;
        #return 0 if ref($l) ne "line3d";

        $canvas->delete($l->{name});
        
    } # clear }}}2

    sub creaWC { # {{{2

        my $l = shift;
        #return 0 if ref($l) ne "line3d";
    
        $l->{$_}->creaWC for qw(p1 p2);
    
    }; # creaWC }}}2

    sub eVec { # {{{2

        my $l = shift;
        return undef unless isLine3d($l);

        my ($norm, $eVec) = (norm($l), []);

        @$eVec = map {
                            matob::notNull( 
                                                    ($l->{p2}{$_} - $l
+->{p1}{$_}) 
                                                    / $norm
                            )
                    } qw(lx ly lz);

        $eVec;

    }; # eVec }}}2

    sub isLine3d { # {{{2
        
        my $l = shift;
        ref($l) ne "line3d" && do {
                                            print "$l not type \"line3
+d\"\n";
                                            return 0;
                                        };
        1;

    }; #isLine3d }}}2

    sub norm { # {{{2
    
        my $l = shift;
        return undef unless isLine3d($l);
    
        matob::vNorm(
                            $l->{p2}{lx} - $l->{p1}{lx}, 
                            $l->{p2}{ly} - $l->{p1}{ly},
                            $l->{p2}{lz} - $l->{p1}{lz}
                        );

    } # norm }}}2

    sub plot { # {{{2
    
        my $l = shift;
        #return 0 if ref($l) ne "line3d";

        my $tag = $l->{name};
    
        return unless $l->{visible};
    
        $canvas->delete($tag);
        
        $l->creaWC;
        $l->project3dTo2d;
    
        if ($l->{visible}) {
            $canvas->createLine (
                $l->{p1}{sx}, $l->{p1}{sy},
                $l->{p2}{sx}, $l->{p2}{sy},
                -fill => $l->{color},
                -tags => [$tag, "line3d"],
                -arrow => "last",
                -activefill => "yellow",
            );
        }
    } # plot }}}2

    sub project3dTo2d { # {{{2
    
        my $l = shift;
        #return 0 if ref($l) ne "line3d";
    
        $l->{$_}->project3dTo2d for qw(p1 p2);
    
    }; # project3dTo2d }}}2

    sub showAttr { # {{{2
        
        print Dumper(shift);

    }; #showAttr }}}2

# package line3d; }}}1

#---------------------------------------------------------------------
package vec3d; # {{{1
#---------------------------------------------------------------------

    # dient v.a. der Selbstverdeutlichung der perl'schen Veerbungs-
    # lehre. 'vec3ds' sind 'line3ds' deren p1 der Ursprung ist.

    # i.Ü. muß eine Erbenklasse noch nicht einmal einen eigenen Kon-
    # struktor haben.

    # die Typprüfung in line3d müßte eigentlich um 'vec3d' erweitert
    # werden. ABER, ist das dann noch oo-sauber ?

    use Data::Dumper;

    our @ISA = qw(line3d);

    sub new { # {{{2

        my ($pkg, $p, $visible, $color, $name) = @_;
        
        $pkg->SUPER::new    (
                                    new point3d(0, 0, 0), 
                                    $p, $visible, $color, $name
                                );

    }; # constructor }}}2


    sub eVec { # {{{2

        my $v = shift;
        return undef unless isVec3d($v);

        my ($norm, $eVec) = (norm($v), []);
        @$eVec = map {
                            matob::notNull($v->{p2}{$_} / $norm)
                    } qw(lx ly lz);

        $eVec;

    }; # eVec }}}2

    sub isVec3d { # {{{2
        
        my $v = shift;
        ref($v) ne "vec3d" && do {
                                            print "$v not type \"vec3d
+\"\n";
                                            return 0;
                                        };
        1;

    }; #isVec3d }}}2

    sub norm { # {{{2
    
        my $v = shift;
        return undef unless isVec3d($v);
    
        matob::vNorm($v->{p2}{lx}, $v->{p2}{ly}, $v->{p2}{lz});

    } # norm }}}2

    sub plot { # {{{2
    
        my $l = shift;
        #return 0 if ref($l) ne "vec3d";

        my $tag = $l->{name};
    
        return unless $l->{visible};
    
        $canvas->delete($tag);
        
        $l->creaWC;
        $l->project3dTo2d;
    
        if ($l->{visible}) {
            $canvas->createLine (
                $l->{p1}{sx}, $l->{p1}{sy},
                $l->{p2}{sx}, $l->{p2}{sy},
                -fill => $l->{color},
                -tags => [$tag, "vec3d"],
                -arrow => "last",
                -activefill => "yellow",
            );
        }
    } # plot }}}2

    sub rotate { # {{{2

        my ($v, $ax, $ay, $az) = @_;

        $v->{p2}->rotate($ax, $ay, $az);

    }; # rotate }}}2

    sub showAttr { # {{{2
        
        print Dumper(shift);

    }; #showAttr }}}2

# package vec3d; }}}1

#---------------------------------------------------------------------
package rect3d; # {{{1
#---------------------------------------------------------------------

    use Data::Dumper;

    sub new { # {{{2

        my ($pkg, $P1, $P2, $P3, $P4, $visible, $color, $name) = @_;
        
        return 0 if (
                                ref($P1) ne "point3d" 
                            or ref($P2) ne "point3d"
                            or ref($P3) ne "point3d"
                            or ref($P4) ne "point3d"
                        ); 

        bless {
                    p1        => $P1,
                    p2        => $P2,
                    p3        => $P3,
                    p4        => $P4,
                   visible => $visible,     # for BackfaceCulling
                   color    => $color,           # side-color, @-refer
+enz
                                                    # palette-based

                   iColr    => "gray",            # individual Color !
                   name    => $name,           
        }, $pkg;
    
    }; # constructor

    sub creaWC {

        #  /**
        #   * Diese Methode multipliziert die 3DVektoren der LOKALEN-
        #   * Koordinaten des Objektes mit der Transformationsmatrix,
        #   * die die Daten für Rotation,Verschiebung,Skalierung
        #   * enthält, und speichert die Berechnungen als die WELT-
        #   * Koordinaten des Objektes ab.
        #   *
        #   * @param r Für dieses Rechteck wird die Transformation
        #   *          durchgeführt
        #   */
    
        my $r = shift;
        return 0 if ref($r) ne "rect3d";
    
        foreach my $p qw(p1 p2 p3 p4) {
            $r->{$p}->creaWC;
        }
    
    }; # creaWC }}}2


    sub backfaceCulling { # {{{2

        #  /**
        #   * Berechnet, in welche Richtung das Polygon zeigt.
        #   * Die Formel ist die letzte Zeile des Vektorproduktes
        #   * und gibt die z-Koordinate des Normalenvektors aus
        #   * den ersten drei Punkten des Polygons an (BILDSCHIRM-
        #   * Koordinaten). Ist z positiv, so zeigt die Fläche
        #   * mindestens 90 Grad vom Betrachter weg.
        #   */

        my $r = shift;
        return 0 if ref($r) ne "rect3d";
    
        my $z =         ($r->{p2}{sx} - $r->{p1}{sx}) 
                    *     ($r->{p3}{sy} - $r->{p1}{sy})
                    -     ($r->{p2}{sy} - $r->{p1}{sy})
                    *     ($r->{p3}{sx} - $r->{p1}{sx});
    
            $r->{visible} = ($z <= 0) ? 0 : 1;
    
    }; # backfaceCulling }}}2

    sub plot { # {{{2
            
        my $r = shift;
        return 0 if ref($r) ne "rect3d";

        my ($cTag, $palType, $side) = @_;
    
        $r->project3dTo2d;
        $r->backfaceCulling;
    
        my $color;
        if ($r->{visible}) {
            
            $color = $iColrFlag 
                        ? $cL{$side}[$palType] 
                        : $r->{iColr};

            unless ($r->{id}) {
                # object doesn't yet exist
                $r->{id} = $canvas->createPolygon
                (
                    $r->{p1}{sx}, $r->{p1}{sy},
                    $r->{p2}{sx}, $r->{p2}{sy},
                    $r->{p3}{sx}, $r->{p3}{sy},
                    $r->{p4}{sx}, $r->{p4}{sy},
                    -fill => $color,
                    -tags => [$cTag, $_, "cube"],
                    -outline => "black",
                    -activewidth => 5,
                    -activeoutline => "#c2ff51",
                    #-stipple => $main::stipple,
                );
                $highId = $r->{id};
                
            } else {

                my $x = $r->{id};
                $canvas->raise($x);
                $canvas->coords(
                    $r->{id},
                    $r->{p1}{sx}, $r->{p1}{sy},
                    $r->{p2}{sx}, $r->{p2}{sy},
                    $r->{p3}{sx}, $r->{p3}{sy},
                    $r->{p4}{sx}, $r->{p4}{sy},
                );
                $canvas->itemconfigure ($r->{id},
                    -fill => $color,
                );
            }
            
        } else {

                # keep object with size 0 at position 0
                $canvas->coords($r->{id}, 0, 0, 0, 0, 0, 0, 0, 0);
        }
    }; # plot }}}2

    sub project3dTo2d { # {{{2
    
        #  /**
        #   * Projiziert die 3DVektoren der WELT-Koordinaten des
        #   * Objektes auf 2DVektoren, die die BILDSCHIRM-Koordinaten
        #   * des Objektes angeben.
        #   *
        #   * @param r Für dieses Rechteck wird die Projektion
        #   *          durchgeführt
        #   */

        my $r = shift;
        return 0 if ref($r) ne "rect3d";
    
        $r->{$_}->project3dTo2d for qw(p1 p2 p3 p4);
    
    }; # project3dTo2d }}}2

    sub rotate { # {{{2

        my ($r, $ax, $ay, $az) = @_;
        return 0 if ref($r) ne "rect3d";

        $r->{$_}->rotate($ax, $ay, $az) for qw(p1 p2 p3 p4);

    } # rotate }}}2

    sub showAttr { # {{{2
        
        print Dumper(shift);

    }; # showAttr }}}2

# package rect3d; }}}1

#---------------------------------------------------------------------
package cube3d; # {{{1
#---------------------------------------------------------------------

    use Data::Dumper;

    our $hsl;
    
    sub new { # {{{2

        my $pkg = shift;
        my (    $origX, $origY, $origZ, 
                $sideLen, $name, $visible, $pal) = @_;

        $hsl = $sideLen / 2;
    
        my ($p1, $p2, $p3, $p4, $p5, $p6, $p7, $p8, $centr) =
            (
                new point3d($origX - $hsl, $origY - $hsl, $origZ + $hs
+l), 
                new point3d($origX + $hsl, $origY - $hsl, $origZ + $hs
+l), 
                new point3d($origX + $hsl, $origY + $hsl, $origZ + $hs
+l), 
                new point3d($origX - $hsl, $origY + $hsl, $origZ + $hs
+l), 
                new point3d($origX - $hsl, $origY + $hsl, $origZ - $hs
+l), 
                new point3d($origX + $hsl, $origY + $hsl, $origZ - $hs
+l), 
                new point3d($origX + $hsl, $origY - $hsl, $origZ - $hs
+l), 
                new point3d($origX - $hsl, $origY - $hsl, $origZ - $hs
+l), 
                new point3d($origX       , $origY       , $origZ      
+ ), 
            );
        
        # back
        my $r1 = new rect3d(    $p1, $p2, $p3, $p4, 1, 
                                    $cL{r1}, "yel");
        # front 
        my $r2 = new rect3d(    $p5, $p6, $p7, $p8, 1, 
                                    $cL{r2}, "red");
        # top  
        my $r3 = new rect3d( $p4, $p3, $p6, $p5, 1, 
                                    $cL{r3}, "ora");
        # bottom 
        my $r4 = new rect3d( $p1, $p8, $p7, $p2, 1, 
                                    $cL{r4}, "gre");
        # right 
        my $r5 = new rect3d( $p2, $p7, $p6, $p3, 1, 
                                    $cL{r5}, "blu");
        # left 
        my $r6 = new rect3d( $p8, $p1, $p4, $p5, 1, 
                                    $cL{r6}, "pin");
    
        my $obj = bless {
            r1            => $r1,
            r2            => $r2,
            r3            => $r3,
            r4            => $r4,
            r5            => $r5,
            r6            => $r6,
            name        => $name,
            centr        => $centr,
            visible    => $visible,
            palette    => $pal,
        }, $pkg;

        $obj->{centr}->creaWC; # Cube-Center
    
        $obj;
        
    }; # constructor }}}2


    sub check { # {{{2
        
        my $c = shift;
        my $stat = 0;

        unless ($c->{centr}{lx} == int($c->{centr}{lx})) {
            print $c->{name}, " lx: ", 
                    $c->{centr}{lx},"  ";
                    $stat++;
        };
        unless ($c->{centr}{ly} == int($c->{centr}{ly})) {
            print $c->{name}, " ly: ", 
                    $c->{centr}{ly},"  ";
                    $stat++;
        };
        unless ($c->{centr}{lz} == int($c->{centr}{lz})) {
            print $c->{name}, " lz: ", 
                    $c->{centr}{lz},"  ";
                    $stat++;
        };
        $stat;

    }; #showAttr }}}2

    sub creaWC { # {{{2
    
        my $c = shift;
        return 0 if ref($c) ne "cube3d";
    
        $c->{centr}->creaWC;
        $c->{$_}->creaWC for (qw|r1 r2 r3 r4 r5 r6|);
        
    }; # creaWC }}}2

    sub plot { # {{{2
    
        my $c = shift;
        return 0 if ref($c) ne "cube3d";

        my $palType = $c->{palette};

        my $cTag = "c" . $c->{name};
        return unless $c->{visible};
    
        foreach (qw|r1 r2 r3 r4 r5 r6|) {
    
            $c->{$_}->plot($cTag, $palType, $_);    
        
        }
    } # plot }}}2

    sub rotate { # {{{2

        my ($c, $ax, $ay, $az) = @_;
        return 0 if ref($c) ne "cube3d";

        $c->{$_}->rotate($ax, $ay, $az) for qw(r1 r2 r3 r4 r5 r6);

        # 040516.1030 :
        # durch Visualisierung ausgewählter Punktvektoren, finde ich 
        # heraus, daß der centr-Punkt erst nach drei Umläufen eines 
        # Einzelcubes (z.b. c20) wieder den korrekten Wert annimmt.
        # warum nun der Faktor 3, für ein sauberes 'Mitlaufen' des 
        # centr-Punkts eines Cubes sorgt, bleibt mir bislang schleier-
        # haft.

        $c->{centr}->rotate($ax * 3, $ay * 3, $az * 3);

    } # rotate }}}2

    sub showAttr { # {{{2
        
        my $c = shift;

        print Dumper($c);

    }; #showAttr }}}2

    sub visible { # {{{2
        
        my ($c, $visible) = @_;
        return 0 if ref($c) ne "cube3d";
        
        foreach my $r qw(r1 r2 r3 r4 r5 r6) {
            $c->{$r}{visible} = $visible;
        }
        1;

    }; # visible }}}2


# package cube3d; }}}1

#---------------------------------------------------------------------
package slice; # {{{1
#---------------------------------------------------------------------

    # 

    use Data::Dumper;
    use constant EPSILON => 1e-09;

    my $lastActAxis;

    sub new { # {{{2

        my ($pkg, $name) = @_;
        
        $name =~ /([xyz])(\d+)/;
        
        bless {
                   name        => $name,           
                    axis        => $1,
                    val        => undef,
                    propos    => 0,
                    #gripped    => 0,
                    members    => {},
        }, $pkg;
    
    }; # constructor }}}2


    sub examine { # {{{2

        my ($val, $axis) = @_;
        my %sm;

        #print "\$val: $val\n";
        #print "\$axis: $axis\n";
    
        foreach (@{$qb->{cube}}) {
    
                            ($axis eq "x") && 
                            do {
                                    abs($_->{centr}{lx} - $val) < EPSI
+LON 
                                    && do {$sm{$_->{name}} = 1};
                                    next;
                            };
                            ($axis eq "y") && 
                            do {
                                    abs($_->{centr}{ly} - $val) < EPSI
+LON
                                    && do {$sm{$_->{name}} = 1};
                                    next;
                            };
                            ($axis eq "z") && 
                            do {
                                    abs($_->{centr}{lz} - $val) < EPSI
+LON
                                    && do {$sm{$_->{name}} = 1};
                                    next;
                            };
                            print "*** HIER DARF ICH NICHT HIN ***\n";
        }

        keys %sm != $qbCubes * $qbCubes 
                && do {
                            print Dumper \%sm;
                            main::show_msg("error", 
                                                "slice-integrity corru
+pted");
                        }; 

        \%sm;

    }; # examine }}}2
                    
    sub changeColor { # {{{2
        
        my ($s, $num) = @_;

        foreach (keys %{$s->{members}}) {
                  
            $qb->{cube}[$_]->{palette} = $num;
            
        }

    } # changeColor }}}2

    sub members { # {{{2

        my $s = shift;
        
        $s->{members} = examine($s->{val}, $s->{axis});

    }; # members }}}2

    sub propose { # {{{2

    }; # propose }}}2

    sub showAttr { # {{{2
        
        print Dumper(shift);

    }; #showAttr }}}2

# package slice; }}}1

#---------------------------------------------------------------------
package qb; # {{{1
#---------------------------------------------------------------------

    use Data::Dumper;
    use Tk;
    use Tk qw/:eventtypes/;
    use constant PI => (atan2(1,1) * 4);
    use constant EPSILON => 1e-09;
    
    sub new { # qb-object {{{2
    
        my ($pkg, $k, $gap) = @_;
        my @c;
    
# bislang wurde die jeweilige Achsenpostion eines Slices (aus Bequem-
# lichkeitsgründen) direkt im Slicenamen wiedergespiegelt, z.b.
# 'sly-10'. Da nun verschieden große qbs möglich sind, muß die Slice-
# benamsung generalisiert werden. Slicenamen werden künfig, beginnend
# beim "negativsten" aufsteigend durchnumeriert. Bsp.: 3er_qb
# 'sly-10' wird 'sly1', 'sly  0' wird 'sly2' usw.

        # 3er-Cube

# perl -we '$sl=10;foreach $z (-$sl, 0, $sl) {foreach $y (-$sl, 0, $sl
+) {foreach $x (-$sl, 0, $sl) {printf "%3d %3d %3d %3d \n", $i++, $x, 
+$y, $z};print "\n"};print "\n"}'

        my (@seq, $sl, $spalt, $slap2n, $n2slap);

        CASE: { # welches Schweinderl hätten's denn gern ? {{{3
        
                    ($k == 2) && do {
                        ($sl, $spalt) = (12, $gap && 1.2);
                        my $slh = $sl/2;
                        @seq = ([$slh, -$slh], [-$slh, $slh]);

                        # SliceAxisPosition to ordNum
                        $slap2n = {-$slh,1,$slh,2};
                        # ordNum to slap. First Value is dummy.
                        $n2slap = [2, -$slh, $slh];
                    };

                    ($k == 3) && do {
                        ($sl, $spalt) = (10, $gap && 1);
                        @seq = ([$sl, 0, -$sl], [-$sl, 0, $sl]);

                        # SliceAxisPosition to ordNum
                        $slap2n = {-$sl,1,0,2,$sl,3};
                        # ordNum to slap. First Value is dummy.
                        $n2slap = [3, -$sl, 0, $sl];
                    };

                    ($k == 4) && do {
                        ($sl, $spalt) = (8, $gap && .8);
                        my $slh = $sl/2;
                        @seq = (    [$slh * 3, $slh, -$slh, -$slh * 3]
+,
                                    [-$slh * 3, -$slh, $slh, $slh * 3]
+);

                        # SliceAxisPosition to ordNum
                        $slap2n = {-$slh * 3, 1, -$slh, 
                                        2, $slh, 3, $slh * 3, 4};
                        # ordNum to slap. First Value is dummy.
                        $n2slap = [4, -$slh * 3, -$slh, $slh, $slh * 3
+];
                    };

                    ($k == 5) && do {
                        ($sl, $spalt) = (6, $gap && .6);
                        @seq = (    [$sl * 2, $sl, 0, -$sl, -$sl * 2],
+ 
                                    [-$sl * 2, -$sl, 0, $sl, $sl * 2])
+;

                        # SliceAxisPosition to ordNum
                        $slap2n = {-$sl * 2, 1, -$sl ,2, 0, 3,
                                        $sl, 4, $sl * 2, 5};
                        # ordNum to slap. First Value is dummy.
                        $n2slap = [5, -$sl * 2, -$sl, 0, $sl, $sl * 2]
+;
                    };

        } # }}}3

        my ($i, $sp) = (0, $sl - $spalt);

        foreach my $z (@{$seq[0]}) {
            
            foreach my $y (@{$seq[0]}) {

                foreach my $x (@{$seq[1]}) {

                    $c[$i] = new cube3d(    $x, $y, $z, $sp, 
                                                sprintf ("%02d", $i), 
+1, 0);
                    $i++;

                };
            };
        };
        
        my %s;
        foreach my $j (qw(x y z)) {
                  
            for (my $i = 1; $i <= $k; $i++) {

                $s{"$j$i"} = new slice("$j$i");

            };
        };

        my $steps = $rotSiSteps * 6;
        
        bless {
                            cube        => \@c,        # single-cubes
                            slice        => \%s,        # slices
                            sideLen    => $sl,
                            s2n        => $slap2n,    # slicenames
                            n2s        => $n2slap,
                            sMovFlag    => 0,
                            actAxis    => '',
                            rS            => PI / $steps,
        }, $pkg;

    }; # constructor }}}2


    sub autoRot { # {{{2
              
        my ($qb, $dSteps) = @_;
        my $steps = abs($dSteps);
        my $dir = $dSteps / $steps;
    
        while ($steps-- > 0) {

            my $tick = 0;
            while ($tick++ < $rotSiSteps) {
                      
                $qb->oneSliceRotStep(1, $dir); 
                #DoOneEvent(DONT_WAIT);
                DoOneEvent();
            }
        }
        $qb->updSlices();
        $qb->{slice}{marked}->changeColor(0);
        $qb->corr;
        $qb->plotAllCubes;

    }; # autoRot }}}2
    
    sub check { # {{{2
        
        my $c = shift;
        my $stat = 0;

        foreach (@{$qb->{cube}}) {
            $stat += $_->check;
        }
        $stat;

    }; #check }}}2

    sub corr { # {{{2

        # if the mousepointer leaves the gripped Slice while rotation
        # and enters another slice, this one will be the 'selCubes'-
        # slice. The next statement makes sure that the actually rotat
+ed
        # slice will be corrected.
        # Surely there is a cheaper solution concerning the performanc
+e-
        # aspect but for now this one will be good enough.

        #$qb->detSlViaNam($canvas, $qb->{slice}{gripped}) if $qb->{sli
+ce}{gripped};

        # correct inaccurancies in local-x/y/z-values

        my ($qb, $slice) = @_;

        $slice ||= $qb->{slice}{marked};
        print "correcting inaccuracies in slice ",
                $slice->{name}, "\n";
        my $x;

        foreach (keys %{$slice->{members}}) {

            print "$_ vor ";
            print "(lx, ly, lz): (",
                        $qb->{cube}[$_]{centr}{lx},", ",
                        $qb->{cube}[$_]{centr}{ly},", ",
                        $qb->{cube}[$_]{centr}{lz},")\n";

            $x = sprintf "%.0f",$qb->{cube}[$_]{centr}{lx};
            $qb->{cube}[$_]{centr}{lx} = ($x =~ /^-0$/) ? "0" : $x;

            $x = sprintf "%.0f",$qb->{cube}[$_]{centr}{ly};
            $qb->{cube}[$_]{centr}{ly} = ($x =~ /^-0$/) ? "0" : $x;
                                                
            $x = sprintf "%.0f",$qb->{cube}[$_]{centr}{lz};
            $qb->{cube}[$_]{centr}{lz} = ($x =~ /^-0$/) ? "0" : $x;
                                                
            print "$_ nach ";
            print "(lx, ly, lz): (",
                        $qb->{cube}[$_]{centr}{lx},", ",
                        $qb->{cube}[$_]{centr}{ly},", ",
                        $qb->{cube}[$_]{centr}{lz},")\n\n";
        }
    }; # corr }}}2
                    
    sub selSlice { # {{{2
        
        my ($qb, $slice) = @_;

        $qb->{slice}{marked} = $slice 
                                    ? (ref($slice) eq "slice")
                                        ? $slice
                                        : $qb->{slice}{$slice}
                                    : $qb->sliceOfCube($actCube);
        
        print "selektierte slice ", $qb->{slice}{marked}{name}, "\n";
        $qb->{slice}{marked}->changeColor(5);

    } # selSlice }}}2

    sub move { # {{{2

        my ($qb, $zug) = @_;

        $zug =~ /(([xyz])\d)(-?\d)/;
        $qb->{actAxis} = $2;
        my ($slice, $x) = ($1, $3);
        $qb->selSlice($slice);
        $qb->autoRot($x);
        
    }; # move }}}2

    sub oneSliceRotStep { # {{{2
    
        my ($qb, $steps, $dir) = @_;
        my $slice = $qb->{slice}{marked};
        
        while ($steps-- > 0) {
            # Achtung, identischer Baustein in 
            # $canvas->bind('cube', '<B1-Motion>' =>  #
            foreach (keys %{$slice->{members}}) {
    
                $qb->{cube}[$_]->rotate($qb->{rS} * $dir, 0.0, 0.0) 
                                                if ($qb->{actAxis} eq 
+"x");

                $qb->{cube}[$_]->rotate(0.0, $qb->{rS} * $dir, 0.0) 
                                                if ($qb->{actAxis} eq 
+"y");

                $qb->{cube}[$_]->rotate(0.0, 0.0, $qb->{rS} * $dir) 
                                                if ($qb->{actAxis} eq 
+"z");
    
            }
        
            main::plotAll();
    
        }
    } # oneSliceRotStep }}}2

    sub plotAllCubes { # {{{2
    
        # The drawing of the individual cubes is done from far to near
+ 
        # (relative to observers position) to avoid sumptuous object-
        # clipping-computings.
    
        # (gilt das noch ???)
        # bei einem 5er-cube werden eigentlich verdeckte Polygone ange
+-
        # zeigt. Eine Lösung könnte in der Distanzmessung zur Sicht-
        # ebene und nicht zum Beobachterpunkt liegen ...
        
        my $qb = shift;
        my ($i, @a, @b) = (0);
    
        foreach (@{$qb->{cube}}) {    # remember the particular 
                                # cubeCenter-observer-distance
    
            $_->creaWC;
    
            $a[$i] = matob::vNorm($_->{centr}{wx}, $_->{centr}{wy}, 
                                $_->{centr}{wz} + $distance) . "_$i";
    
            $b[$i++] = $_;
    
        }
    
        no warnings;                             # perl grumbles, 
        foreach (sort {$b <=> $a} @a) {    # but does the demanded
                                                    # numerical sort
            /._(\d+)$/;
    
            $b[$1]->plot;
        }
        use warnings;
    
    
    } # plotAllCubes }}}2

    sub randMove { # {{{2

        my $qb = shift;
        my ($x, $slice);

        $qb->{actAxis} = [qw/x y z/]->[int(rand(3))];
        my $n = int(rand($qbCubes))+1;
        $slice = sprintf("%1s%1d", $qb->{actAxis}, $n);
        #$qb->{slice}{gripped} = $slice;
        $qb->selSlice($slice);

        do {$x = int(rand(7)) - 3} until $x;
        $zug = $slice . sprintf("%2d *", $x);
        $zug =~ s/\s//;

        [$zug, $x];

    }; # randMove }}}2

    sub shuffle { # {{{2

        my ($qb, $shuffleSteps, $movLBox) = @_;

        my ($zn, $i, $zug, $x) = (1, 0);
        
        while ($i++ < $shuffleSteps) {
            
            my $rA = $qb->randMove;
            ($zug, $x) = @$rA;

            $qb->autoRot($x);

            my $zn = $movLBox->index('end') + 1;
            $zug = sprintf("%4d: %5s", $zn, $zug);
            $movLBox->insert('end', $zug);
            $movLBox->see('end');

            $qb->{shuffleBreak} && do {
                                                    $qb->{shuffleBreak
+} = 0;
                                                    last;
                                                };
            
            #sleep 1;
        };

    }; # shuffle }}}2

    sub showAttr { # {{{2
        
        my $qb = shift;

        print Dumper($qb);

    }; #showAttr }}}2

    sub save { # {{{2
        
        my ($qb, $fname, $movLBox) = @_;

        $canvas->configure(-cursor => 'watch');
        $fname =~ s/\.q(?:sn|po|mv)$//;
        $fname ||= "noname";
        #$fname = "noname";
        print "saving $fname ... ";

        # qsn    : SNap
        open (O, ">$fname.qsn");
        $Data::Dumper::Purity = 1;
        print O Data::Dumper->Dump([$qb], ['qb']);
        close O;

        # qmv : MoVes
        my @moves = $movLBox->get(0, 'end');
        open (O, ">$fname.qmv");
        print O "$_\n" for @moves;
        close O;

        # qpo : POsition
        open (O, ">$fname.qpo");
        $Data::Dumper::Purity = 1;
        print O Data::Dumper->Dump([$mm], ['mm']);
        close O;
        print "done\n";

        $saveIt = 0;

    }; #save }}}2
  
    sub updSlices { # {{{2

        return if keys %{$qb->{constraint}};
        print "updSlices start\n";
        foreach my $j (qw(x y z)) {
                  
            $j eq $qb->{actAxis} && next;
            for (my $i = 1; $i <= $qbCubes; $i++) {

                $qb->{slice}{$j . $i}{val} ||= $qb->{n2s}[$i];
                $qb->{slice}{$j . $i}->members();

            };
        };

        print "updSlices end\n";
        
    }; #updSlices }}}2

    sub sliceOfCube { # {{{2
        
        my ($qb, $cube) = @_;
        $cube ||= $actCube;
        
        #print "\$cube: $cube\n";
        my $val = $qb->{cube}[$cube]{centr}{"l" . $qb->{actAxis}};
        #print "\$val: $val\n";
        my $slice = $qb->{actAxis} . $qb->{s2n}{$val};

        #$qb->{slice}{$slice}->showAttr;

        $qb->{slice}{$slice};
        
    }; #sliceOfCube }}}2

    sub undoMove { # {{{2

        my ($qb, $rZug) = @_;

        $rZug =~ s/,-/, / || $rZug =~ s/, /,-/;
        $qb->move($rZug);

    }; # undoMove }}}2

# package qb; }}}1
Replies are listed 'Best First'.
"Rubics Cube" game - part 2
by tos (Deacon) on Mar 04, 2008 at 18:04 UTC
    #--------------------------------------------------------------------- package main; #--------------------------------------------------------------------- sub init { # {{{1 $zug = ""; undef $mm; $mm = new matob(1); undef $qb; $qb = new qb($qbCubes, 1); $qb->updSlices(); $qb->{actAxis} = 'y'; print $qb->{cube},"\n"; my $font = '-misc-fixed-medium-r-normal-*-*-150-*-*-c-*-iso8859-9 +'; $font = '-misc-fixed-medium-r-*-*-13-*-*-*-m-*-*-*'; my $font2 = '-*-console-medium-*-*-*-16-*-*-*-*-*-*-*' +; $font2 = '-*-courier-medium-r-*-*-14-*-*-*-*-*-*-*'; my $al = 26; my $xAxis = new line3d( new point3d(-$al, 0, 0), new point3d($al, 0, 0) +, 1, "gray20", "xAxis"); my $yAxis = new line3d( new point3d(0, -$al, 0), new point3d(0, $al, 0) +, 1, $rgb{DarkRed}, "yAx +is"); my $zAxis = new line3d( new point3d(0, 0, -$al), new point3d(0, 0, $al) +, 1, "blue", "zAxis"); my $horiz = new vec3d( new point3d(1, 0, 0), 1, "green", "vektor"); my $vertik = new vec3d(new point3d(0, 1, 0), 1, "orange", "vektor") +; my $cvac = new vec3d($qb->{cube}[$actCube]{centr}, 1, "white", "cvac"); # all vars should be kept in a common ds { cvac => $cvac, freezeCvac => 0, font => [$font, $font2] +, horiz => $horiz, old_fill => '', PFLAG => 1, plotCS => 0, plotTri => 0, triX => 0, triY => 0, triZ => 0, showCvac => 1, shuffleSteps => 1, vertik => $vertik, xAxis => $xAxis, xb1down => 0, xb3down => 0, yAxis => $yAxis, yb1down => 0, yb3down => 0, zAxis => $zAxis, } } # init }}}1 my $V = init(); sub plotAllVectors { #{{{1 $V->{showCvac} && $V->{cvac}->plot; $V->{horiz}->plot; $V->{vertik}->plot; #$c20_centr->plot; }; #}}}1 sub plotAll { #{{{1 #print "plotte mal wieder all\n";; $qb->plotAllCubes; plotCS() if $V->{plotCS}; plotTri() if $V->{plotTri}; # plotAllVectors; } # plotAll #}}}1 sub plotCS { #{{{1 $V->{xAxis}->plot; $V->{yAxis}->plot; $V->{zAxis}->plot; } # plotCS #}}}1 sub remCS { #{{{1 $V->{xAxis}->clear; $V->{yAxis}->clear; $V->{zAxis}->clear; } # remCS #}}}1 sub plotTri { #{{{1 $V->{triX}->plot; $V->{triY}->plot; $V->{triZ}->plot; } # plotCS #}}}1 sub remTri { #{{{1 $V->{triX}->clear; $V->{triY}->clear; $V->{triZ}->clear; } # remCS #}}}1 sub fileDialog { #{{{1 my $w = shift; my $operation = shift; my $file; # Type names Extension(s) Mac File Type(s) # #--------------------------------------------------------- my @types = ( ["qb3-Snapshot files", '.qsn'], ["qb3-Moves files", '.qmv'], ["qb3 files (deprecated)", '.qb3'], #["All files", '*'] ); if ($operation eq 'open') { $file = $w->getOpenFile(-filetypes => \@types); } else { $file = $w->getSaveFile(-filetypes => \@types, -initialfile => 'noname', #-defaultextension => '.qb3'); ); } $file; #if (defined $file and $file ne '') { # $ent->delete(0, 'end'); # $ent->insert(0, $file); # $ent->xview('end'); #} } # fileDialog }}}1 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Widgets and bindings # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Menus {{{1 my $top = MainWindow->new(); $top->resizable(1, 1); # Menu Bar # {{{2 my $menu_bar = $top ->Frame( -relief => 'raise', -borderwidth => 2) ->pack(-side => 'top', -fill => 'x'); #}}}2 # Game Menu # {{{2 my $menuB1 = $menu_bar ->Menubutton(-text => 'Game') ->pack(-side => 'left', -padx => 2); $menuB1->command( -label => 'New', -accelerator => 'Ctrl-n', -underline => 0, -command => \&newGame, ); $top->bind('<Control-n>' => \&newGame); $menuB1->separator(); $menuB1->command( -label => 'Load', -accelerator => 'Ctrl-l', -underline => 0, -command => \&load, ); $menuB1->command( -label => 'Save as', -accelerator => 'Ctrl+s', -underline => 0, -command => \&save, ); $menuB1->separator(); $menuB1->command( -label => 'Quit', -accelerator => 'q', -underline => 0, -command => \&lebWohl, ); #}}}2 # Dialogs Menu # {{{2 use subs qw/colMenu moveInp/; # 040930: Menubutton's menuitems expects a list-of-list- # reference. It doesn't matter whether this reference # is delivered by list-reference or via sub. my $diaMenu = [ ['cascade', "Colors", -menuitems => colMenu], ['command', 'MoveInput', -command => \&moveInp], ['command', 'checkSlices', -command => \&checkSlices], ]; #sub diaMenu { # [ # ['cascade', "Colors", -menuitems => colMenu], # ], #} my $menuB4 = $menu_bar ->Menubutton( -text => 'Dialogs', -menuitems => $diaMenu) ->pack(-side => 'left', -padx => 2); #my $menuB4 = $menu_bar # ->Menubutton( -text => 'Colors', # -menuitems => colMenu) # ->pack(-side => 'left', -padx => 2); # # the Slick, Sophisticated, New-Fashioned Way, # -> 12.2.2. masteringPerlTk\ch12_02.h +tm # # auf die folgende Art läßt sich sehr elegant das kaskadierende # Farbmenu erzeugen. sub colMenu { #{{{3 [ ['command', 'default', -command => sub { foreach (keys %cD) { $menuB4->entryconfigure ($_, -background => $cD{$_}[0]); %cL = %cD; plotAll(); } } ], map ['cascade', $_, -background => $cL{$_}[0], -menuitems => [ map ['command', $_, -background => $rgb{$_}, -command => [ sub { print "\$_: $_\n"; print "\$menuB4: $menuB4\n"; # nachdem das colMenu ein Stufe tiefer + ge- # rutscht ist, kann ich den index des +ersten # col-Menus nicht mehr ermitteln. ?! # bekomme nur 'none'. Lösung vermutlic +h dann, # wenn ich die folgende Zeile tatsächl +ich ver- # standen und anschließend modifiziert + habe. # don't give up ... # bis v0.52 funktioniert colMenu; alle +rdings # auf höherer Menustufe my $i1 = $menuB4->menu()->index("activ +e"); my $i2 = shift @_; print "$i1/$i2\n"; my $i3 = index ("yelredoragreblupin", +$i2)/3; print "\$i3: $i3\n"; my $i4 = $i1 - 1; $cL{"r$i4"} = $cRef->[$i3]; $menuB4->entryconfigure($i1, -background => $rgb{$i +2}); plotAll(); }, $_ ], ], qw/yel red ora gre blu pin/, ], ], qw/r1 r2 r3 r4 r5 r6/, ], } # end colMenu }}}3 sub moveInp { #{{{3 if (! Exists($tl)) { $tl = $top->Toplevel( ); $tl->title("MoveInput"); my $text = $tl->Scrolled('Text', -width => 25, -height => 10, -scrollbars => 'w')->pack(qw/ -fill y -e +xpand 1/); $tl->Button(-text => "Clear", -command => sub { $text->delete("1.0", "end"); } )->pack(-side => 'left'); $tl->Button(-text => "Commit", -command => sub { my @z = split /\n/, $text->get("1.0", "end"); foreach (@z) { /([xyz]\d)([+-]?\d)/ ? do { my $z = "$1$2"; print "tue $z\n"; $qb->move($z); } : print "invalid Move\n"; }; } )->pack(-side => 'left'); $tl->Button(-text => "HighLightCubes", -command => sub { my @z = split /\n/, $text->get("1.0", "end"); foreach (@z) { /(\d\d)/ && print $1,"\n"; $qb->{cube}[$1]->{palette} = 4; }; plotAll(); } )->pack(-side => 'left'); $tl->Button(-text => "Close", -command => sub { $tl->withdraw } )->pack(-side => 'left'); } else { $tl->deiconify( ); $tl->raise( ); } } # end moveInp #}}}3 sub checkSlices { #{{{3 if (! Exists($tlcs)) { $tlcs = $top->Toplevel( ); $tlcs->title("checkSlices"); # setup the default value we would like my $rb_value = "gray"; $tlcs->configure(-background => $rb_value); # create the Radiobuttons that will let us change it foreach (qw(x y z)) { my $fr = $tlcs->Frame( -borderwidth => 2, #-relief => 'ridge', )->pack(qw/-side left/); for (my $i = 1; $i <= $qbCubes; $i++) { $fr->Radiobutton( -text => $_ . $i, -value => $_ . $i, -variable => \$rb_value, -command => \&set_bg)->pack(-side => 'top'); } } sub set_bg { foreach (0 .. $qbCubes ** 3 - 1) { $qb->{cube}[$_]->{palette} = 0; }; plotAll(); #print "\$rb_value: $rb_value\n"; foreach (keys %{$qb->{slice}{$rb_value}{members}}) { $qb->{cube}[$_]->{palette} = 1; }; plotAll(); } $tlcs->Button(-text => "Clear", -command => sub { foreach (0 .. $qbCubes ** 3 - 1) { $qb->{cube}[$_]->{palette} = 0; }; plotAll(); } )->pack(-fill => 'y', -expand => 1, -side => 'top'); $tlcs->Button(-text => "Close", -command => sub { $tlcs->withdraw } )->pack(-side => 'bottom'); } else { $tlcs->deiconify( ); $tlcs->raise( ); } } # end moveInp #}}}3 # }}}2 # Options Menu # {{{2 my $mOptions = $menu_bar ->Menubutton(-text => 'Options') ->pack(-side => 'left', -padx => 2); $mOptions->separator; my $cubeMenu = $mOptions->cget(-menu)->Menu(); $mOptions->cascade(-label => "cubes", -underline => 0, -menu => $cubeMenu); foreach (qw/2 3 4 5/) { $cubeMenu->radiobutton( -label => $_, -variable => \$qbCubes, ); } $mOptions->checkbutton( -label => 'show cvac', -variable => \$V->{showCvac}); $mOptions->checkbutton( -label => 'freeze cvac', -variable => \$V->{freezeCvac}); $mOptions->separator; my $shufMenu = $mOptions->cget(-menu)->Menu(); $mOptions->cascade(-label => "shuffleSteps", -underline => 0, -menu => $shufMenu); $shufMenu->radiobutton(-label => '3', -variable => \$V->{shuffleSteps}); $shufMenu->radiobutton(-label => '5', -variable => \$V->{shuffleSteps}); $shufMenu->radiobutton(-label => '9', -variable => \$V->{shuffleSteps}); $shufMenu->radiobutton(-label => '20', -variable => \$V->{shuffleSteps}); $shufMenu->radiobutton(-label => '50', -variable => \$V->{shuffleSteps}); # }}}2 # "Questionmark"-menu {{{2 my $qmMenu = $menu_bar ->Menubutton(-text => '?') ->pack(-side => 'left', -padx => 2); $qmMenu->command( -label => 'Help', -accelerator => 'Meta+H', -underline => 0, -command => sub {print "hilf dir selbst da +nn \ hilft +dir gott...\n"} ); sub mbox { my $mbox = $top->DialogBox( -title => "About qb3", -buttons => ["ok"], ); my $fr = $mbox->add('Frame', -borderwidth => 2, -relief => 'ridge') ->pack(qw/-side left/); $fr->Label(-image => $mbox->Pixmap( -data => &greyCubeLogo)) ->pack(qw/-side top/); $mbox->add('Label', -text => " Version: $VERSION\n\n" . "Perl: $]\n" . "Tk : $Tk::VERSION", -relief => "groove", )->pack(-side => 'left'); $mbox->add('Label', -image => $top->Pixmap(-data => &ptk)) ->pack(qw/-side top/); $mbox->add('Label', -image => $top->Pixmap(-data => &cwVim)) ->pack(qw/-side top/); $mbox->add('Label', -image => $top->Pixmap(-data => &wilbur)) ->pack(qw/-side top/); $mbox->add('Label', -image => $top->Pixmap(-data => &tos), -relief => "groove", )->pack(qw/-side top/); $mbox->add('Label', -text => " made by tos", -relief => "groove", )->pack(-side => 'top'); $mbox->Show(); }; #}}}2 sub show_msg { #{{{1 my($iconvar, $message, $movLBox) = @_; my $button = $top->messageBox( -icon => $iconvar, -type => "OK", -title => 'Message', -message => $message ); #$saveIt && $qb->save("errDump", $movLBox); exit; } # show_msg }}}1 $qmMenu->command( -label => 'About', -accelerator => 'Meta+A', -underline => 0, -command => \&mbox, ); # }}}2 # menus }}}1 # dashboard {{{1 my $mainFrame = $top ->Frame(-bd => "2") ->pack(-side => 'top', -fill => 'x'); my $rf = $mainFrame ->Frame( -bd => "2", #-cursor => 'rtl_logo', #-cursor => 'question_arrow', #-cursor => 'draped_box', -cursor => 'plus', ) ->pack(-side => 'right', -fill => 'y'); my $tf = $mainFrame ->Frame() ->pack(-side => 'top', -fill => 'both'); my $cubAnz1 = $tf ->Label( -text => "", #-relief => "groove", -width => 30, -foreground => $rgb{Dark +Green}, -height => 4, -font => $V->{font}[0]) ->pack(-fill => 'x', -expand => 1, -side => 'left' +); my $bf = $mainFrame ->Frame() ->pack(-side => 'bottom', -fill => 'x'); my $cubAnz2 = $bf ->Label( -text => "", #-relief => "groove", -foreground => $rgb{DarkGreen}, -height => 4, -font => $V->{font}[0]) ->pack(-fill => 'x', -expand => 1, -side => 'left' +); my $lf = $mainFrame ->Frame( #-relief => "groove", -cursor => 'plus', -bd => "2") ->pack(-side => 'left', -fill => 'y'); my $tlf = $lf ->Frame( #-relief => "groove", -bd => "2") ->pack(-side => 'top', -fill => 'x'); my $blf = $lf ->Frame( #-relief => "groove", -bd => "2") ->pack(-side => 'bottom', -fill => 'x'); $top->Icon(-image => $top->Pixmap(-data => &icon)); my $hMovLBox = $tlf ->Label( -text => "Moves", -relief => "flat", -foreground => "gray20", -cursor => 'pirate', #-width => 10, -font => $V->{font}[0]) ->pack(-side => 'top', -fill => 'x'); my $movLBox = $tlf ->Scrolled(qw/Listbox -width 16 -height 7 -setgrid 1 -scrollbars w -bd 2/, -font => $V->{font}[1]) ->pack(); #-bg LemonChiffon2 /, my $canvFram = $mainFrame ->Frame( #-relief => "groove", -width => 600, -height => 270, -bd => "2") ->pack(-side => 'left'); $canvas = $canvFram ->Canvas(-width => $screenWidth, -height => $screenHeight, #-relief => "ridge", -cursor => 'crosshair') ->pack(-side => 'left', -fill => 'both'); my $detInf = $rf ->Frame( ) ->pack(-side => 'right', -fill => 'both'); my $statLine = $top ->Frame( -relief => "raise", -bd => "2", -heigh +t => 8) ->pack(-side => 'top', -fill => 'both'); my $statAnz = $top ->Frame( -relief => "sunken", -bd => "2", -foreground => $rgb{DarkGreen}) ->pack(-side => 'top', -fill => 'x'); my $lvFrame = $detInf ->Frame( -relief => "flat", -bd => "2") ->pack(-side => 'top', -fill => 'x'); my $wvFrame = $detInf ->Frame( -relief => "flat", -bd => "2") ->pack(-side => 'top', -fill => 'x'); my $dFrame = $detInf ->Frame( -relief => "flat", -bd => "2") ->pack(-side => 'top', -fill => 'x'); my $oFrame = $detInf ->Frame( -relief => "flat", -bd => "2") ->pack(-side => 'top', -fill => 'x'); my $sVFrame = $detInf ->Frame( -relief => "flat", -bd => "2") ->pack(-side => 'top', -fill => 'x'); my $rfDeckl = $detInf ->Label( -relief => "flat", -width => "50", -height => "40", -text => "") ->place(-x => 0, -y => 0); my $tlfDeckl = $tlf ->Label( -relief => "flat", -width => "50", -height => "20", -text => "") ->place(-x => 0, -y => 0); my $blfDeckl = $blf ->Label( -relief => "flat", -width => "50", -height => "20", -text => "") ->place(-x => 0, -y => 0); my $lvLab = $lvFrame ->Label( -text => "localCoords", -relief => "flat", -cursor => 'pirate', -foreground => "gray20", -width => 20, -font => $V->{font}[0]) ->pack(-side => 'top'); my $lxAnz = $lvFrame ->Label( -text => "", -relief => "sunken", -foreground => "gray20", -width => 10, -font => $V->{font}[0]) ->pack(-side => 'top'); my $lyAnz = $lvFrame ->Label( -text => "", -relief => "sunken", -foreground => $rgb{DarkRed}, -width => 10, -font => $V->{font}[0]) ->pack(-side => 'top'); my $lzAnz = $lvFrame ->Label( -text => "", -relief => "sunken", -foreground => $rgb{DarkBlue}, -width => 10, -font => $V->{font}[0]) ->pack(-side => 'top'); my $cubAnz = $statLine ->Label( -text => "", -relief => "sunken", -width => 3, -foreground => $rgb{DarkG +reen}, -font => $V->{font}[0]) ->pack(-side => 'left'); my $rectAnz = $statLine ->Label( -text => "", -relief => "sunken", -width => 2, -foreground => "blue", -font => $V->{font}[0]) ->pack(-side => 'left'); my $sliceAnz = $statLine ->Label( -text => "", -relief => "sunken", -width => 5, -foreground => "darkorchi +d", -foreground => "purple", -font => $V->{font}[0]) ->pack(-side => 'left'); my $vecAnz = $statLine ->Label( -text => "", -relief => "sunken", -width => 4, -foreground => "darkorchid", -font => $V->{font}[0]) ->pack(-side => 'left'); my $statFram = $statLine ->Frame( -relief => "groove", -bd => "1", #-height => 3) ) ->pack(-side => 'left', -fill => "x"); $statFram->bind('<1>' => sub { print "bye, bye Sir!\n"; exit; }); my $shuffle = $statFram ->Button(-text => "shuffle", -height => 0.3, -command => sub { keys %{$qb->{constraint}} && r +eturn; $qb->shuffle( $V->{shuff +leSteps}, $movLBox ); }, -font => $V->{font}[0]) ->pack(-side => 'left'); my $leave = $statFram ->Label( -text => "", -width => 40, -cursor => 'pirate', -font => $V->{font}[0]) ->pack(-side => 'left', -fill => 'x'); my $yKoor = $statLine ->Label( -text => "", -relief => "sunken", -width => 3, -font => $V->{font}[0]) ->pack(-side => 'right'); my $xKoor = $statLine ->Label( -text => "", -relief => "sunken", -width => 3, -font => $V->{font}[0]) ->pack(-side => 'right'); my $lwLab = $wvFrame ->Label( -text => "worldCoords", -relief => "flat", -foreground => "gray20", -width => 12, -font => $V->{font}[0]) ->pack(-side => 'top'); my $xKoor3d = $wvFrame ->Label( -text => "", -relief => "sunken", -width => 10, -foreground => "gray20", + -font => $V->{font}[0]) ->pack(-side => 'top'); my $yKoor3d = $wvFrame ->Label( -text => "", -relief => "sunken", -width => 10, -foreground => $rgb{Dark +Red}, -font => $V->{font}[0]) ->pack(-side => 'top'); my $zKoor3d = $wvFrame ->Label( -text => "", -relief => "sunken", -width => 10, -foreground => $rgb{Dark +Blue}, -font => $V->{font}[0]) ->pack(-side => 'top'); my $dLab = $dFrame ->Label( -text => "distance", -relief => "flat", -foreground => "gray20", -width => 12, -font => $V->{font}[0]) ->pack(-side => 'top'); my $distLab = $dFrame ->Label( -text => "", -foreground => "red", -relief => "sunken", -width => 10, -font => $V->{font}[0]) ->pack(-side => 'top'); my $oLab = $oFrame ->Label( -text => "query", -relief => "flat", -foreground => "gray20", -width => 12, -font => $V->{font}[0]) ->pack(-side => 'top'); my $rSentry = $oFrame ->Entry(-relief => "sunken", -width => 10, -textvariable => \$qb->{query}, -validate => 'key', -font => $V->{font}[0]) ->pack(-side => 'top'); my $sVLab = $sVFrame ->Label( -text => "selVect", -relief => "flat", -foreground => "gray20", -width => 12, -font => $V->{font}[0]) ->pack(-side => 'top'); my $sVxAnz = $sVFrame ->Label( -text => "", -relief => "sunken", -foreground => "gray20", -width => 10, -font => $V->{font}[0]) ->pack(-side => 'top'); my $sVyAnz = $sVFrame ->Label( -text => "", -relief => "sunken", -foreground => $rgb{DarkRed}, -width => 10, -font => $V->{font}[0]) ->pack(-side => 'top'); my $sVzAnz = $sVFrame ->Label( -text => "", -relief => "sunken", -foreground => $rgb{DarkBlue}, -width => 10, -font => $V->{font}[0]) ->pack(-side => 'top'); my $sVnAnz = $sVFrame ->Label( -text => "", -relief => "sunken", -foreground => "black", -width => 10, -font => $V->{font}[0]) ->pack(-side => 'top'); sub lebWohl { $top->iconify(); #$saveIt && $qb->save("noname", $movLBox); print "bye, bye Sir!\n"; exit; }; # lebWohl my $hiddenMB = $top->Menubutton( -text => 'File', -relief => 'raised', ); #$file->pack(qw/-side left/); my $hiddenM = $hiddenMB->Menu(-tearoff => 0, -menuitems => [ [qw/command ~color/], '', [qw/command ~position/], '', [qw/command ~properties/], '', [qw/command ~hide/], '', [qw/command ~Quit/, -command => \&exit], ]); $hiddenMB->configure(-menu => $hiddenM); #print "\$hiddenM: $hiddenM\n"; sub load { # {{{3 $canvas->configure(-cursor => 'watch'); my $file = shift || fileDialog($top, "open"); $file || return; #print "\$file: $file\n"; my ($name,$path,$ext) = fileparse($file, '\..*'); #print "\$name: $name\n"; #print "\$path: $path\n"; #print "\$ext: $ext\n"; print "loading ... "; $canvas->delete('all'); #local $/ = ""; CASE: { ($ext eq ".qsn") && do { my $ds; open I, $file; while (<I>) { m/\'id\'\s+\=\>\s+\d+/ && next; $ds .= $_; }; close I; eval $ds; }; ($ext eq ".qmv") && do { open I, $file; while (<I>) { #print; chomp; $movLBox->inser +t('end', $_); /([xyz]\d-?\d)/; my $haltMal = $1; #print "will $halt +Mal\n"; $qb->move($haltMal +); } close I; }; }; open (I, $path . $name . ".qpo"); my $ds = (<I>); print $ds; close I; eval $ds; print "done\n"; plotAll(); print "\$qb: $qb\n"; $canvas->configure(-cursor => 'crosshair'); }; # load }}}3 sub save { # {{{3 my $f = fileDialog($top, "save"); $qb->save($f, $movLBox) if defined $f; }; # save }}}3 sub newGame { # {{{3 $canvas->delete('all'); $movLBox->delete(0,'end'); $V = init(); $mm->rotate(PI/-6, PI/6, 0.0); plotAll(); }; #}}}3 # dashboard }}}1 # bindings # {{{1 my $labDefColor = $statLine->cget('-background'); my $highLightBgColor = "wheat2"; #$lyAnz->configure(-background => $highLightBgColor); sub updDashBoard { # {{{2 { ($qb->{actAxis} eq "x") && do { $lyAnz->configure(-background => $labDefColor); $lzAnz->configure(-background => $labDefColor); $lxAnz->configure(-background => $highLightBgColor); }; ($qb->{actAxis} eq "y") && do { $lxAnz->configure(-background => $labDefColor); $lzAnz->configure(-background => $labDefColor); $lyAnz->configure(-background => $highLightBgColor); }; ($qb->{actAxis} eq "z") && do { $lxAnz->configure(-background => $labDefColor); $lyAnz->configure(-background => $labDefColor); $lzAnz->configure(-background => $highLightBgColor); }; } } # updDashBoard # }}}2 #$top->bind('<A>' => # {{{2 # # uneingerastete Slice-Stellung, deren Möglichkeit ich au +s # # effekthascherischen Erwägungen beibehalten will, bringt + # # leider Mehraufwand mit sich. (eigentlich logisch) # # Nun der Versuch das in, auch noch nach Monaten verständ +- # liche Worte zu fassen. Also: # # # Definition: "gerastet" meint, daß die Kanten aller Cube +s # # eine Slices parallel zu den jeweils + korres- # # pondierenden Koordinatenachsen stehe +n. # # Zu Spielbegin sind alle Slices geras +tet. # # # # # Definition: "engaged" [(ein)gerastet] means that all cu +be- # # edges of a slice are parallel with the + parti- # # cular coordinate-axises. At the begin +ning of # # a game all slices are engaged. # # # # # - Doppelklick auf gerasteten Slice führt zu Achsen- # # wechsel. So solls auch sein. Ist der Slice nicht ge- # # rastet, so findet kein Achsenwechsel statt. Es können # # jetzt nur Slices gedreht werden, die senkrecht auf # # der gleichen Achse stehen. (Schaschlikspieß). # # # - Doubleclick on engaged slice leads to change of rota- # # tionaxis. That's the way it has to be. If the slice i +s # # not engaged there will be no change of axis. Only sli +ces # # then can be rotated which are vertical to the same ax +is. # # Think of a skewer. # # # - erst wenn alle Slices in der Flucht liegen UND gerast +et # # sind, kann wieder Achsenwechsel stattfinden. # # # - not until all slices lay in straight line AND are eng +a- # # ged change of axis can be done. # # # - sind alle Slices gefluchtet aber nicht gerastet, steh +en # # sie gemeinsam schief im KS. Um wieder in alle Richtun +gen # # beweglich zu sein, muß jetzt erst wieder Orthogonalit +ät # # zwischen Slices und KS hergestellt werden. # # # - if all slices are in straight line but not engaged th +ey # # have a common crooked position. To make them mavable +to # # all directions there has to be at first an orthogonal # # (relative) position between slices and coordinatesyst +em. # # # die folgende Subroutine soll ausgehend von einem repräs +en- # # tativen Slice alle drei gemeinsam zurück in einen geras +te- # # ten Zustand drehen. # # # the following subroutine ... # # sub { # print "<A>\n"; # # adjust (make orthogonal) slices # # relativ to coorSystem # # my $slice = $qb->{slice}{gripped}; # print "\$slice: $slice\n"; # $slice =~ /^(sl[xyz])/; # my $slPrfx = $1; # # my $steps = $qb->{rot}{$slice}; # my $dir = $steps / abs($steps); # $steps = abs($steps) % $rotSiSteps; # my $diff = $rotSiSteps - $steps; # if ($diff < $steps) { # $steps = $diff; # $dir = -$dir; # }; # # print "\$steps: $steps\n"; # print "\$dir: $dir\n"; # # $qb->{slice}{gripped} = ''; # # for (my $i = 1; $i <= $qbCubes; $i++) { # #for ("-10", " 0", " 10") { # my $slice = $slPrfx . $i; # print "\$slice: $slice\n"; # $qb->detSlViaNam($canvas, $slice); # $qb->oneSliceRotStep($steps, -$dir); # $qb->corr; # $qb->{rot}{$slice} = 0; # } # # }); # }}}2 $top->bind('<b>' => # {{{2 sub { print "<b>\n"; $qb->{shuffleBreak}++; }); # }}}2 $top->bind('<Control-c>' => \&lebWohl); $top->bind('<c>' => # {{{2 sub { print "Cubes ", $qb->check ? "bad" : "OK", "\n"; #print "\$qb->{constraint}\n"; #print Dumper $qb->{constraint}; foreach (qw(X Y Z)) { my $tr = "tri$_"; my $ax = lc($_) . "Axis"; print "\n$tr-eVec: \t("; print "$_\t" for @{$V->{$tr}->eVec}; print ")\t"; print "\n$ax-eVec: \t("; print "$_\t" for @{$V->{$ax}->eVec}; print ")\n"; print matob::vecsPhi( $V->{$tr}->eVec, $V->{$ax}->eVec ), "\n"; } }); # }}}2 $top->bind('<C>' => # {{{2 sub { my $initialColor = "gray"; $top->chooseColor(-title => "Choose a color", -ini +tialcolor => $initialColor); }); # }}}2 # <d> # {{{2 {my $x = 50; $top->bind('<d>' => sub { $x = ($x == 50) ? 0 : 50; $rfDeckl->configure(-width => $x); $tlfDeckl->configure(-width => $x); $blfDeckl->configure(-width => $x); }); }; # }}}2 $top->bind('<D>' => # {{{2 #$top->bind('<D>' => [\&autoRot, 2]); sub { print "_"x25, "slice-Dump-Anf", "_"x25,"\n"; print "slices: ", Dumper ($qb->{slice}), "\n"; print "="x25, "slice-Dump-End", "="x25,"\n"; }); # }}}2 $top->bind('<g>' => # {{{2 sub { print "\$qb->grippedS: ", $qb->{slice}{gripped}{name}, "\n"; }); # }}}2 $top->bind('<h>' => # {{{2 sub { print "\$highId: $highId\n"; }); # }}}2 $top->bind('<i>' => # {{{2 sub { $iColrFlag = $iColrFlag ? 0 : 1; plotAll(); }); # }}}2 $top->bind('<k>' => # {{{2 sub { $V->{plotCS} = $V->{plotCS} ? do {remCS; 0} : plotCS; }); # }}}2 $top->bind('<l>' => # {{{2 sub { print "\$mm: $mm\n"; $mm->rotate( $qb->{rS}, 0.0, 0.0) if ($qb->{actAxis} eq "x"); $mm->rotate( 0.0, $qb->{rS}, 0.0) if ($qb->{actAxis} eq "y"); $mm->rotate( 0.0, 0.0, $qb->{rS}) if ($qb->{actAxis} eq "z"); plotAll; }); # }}}2 $top->bind('<Control-l>' => # {{{2 sub { load(); }); # }}}2 $top->bind('<m>' => # {{{2 sub { #print Data::Dumper->Dump([$mm],['$mm']); print "\$mm:\n"; for (my $z=0; $z<4; $z++) { for (my $s=0; $s<4; $s++) { printf "%+0.2f ", $mm->[$z][$s]; } print "\n"; } my $im = invMat($mm); print "\$inv:\n"; for (my $z=0; $z<4; $z++) { for (my $s=0; $s<4; $s++) { printf "%+0.2f ", $im->[$z][$s]; } print "\n"; } my ($probe, $dummy) = ([]); $probe = matMult($dummy,$mm,$im); print "\$probe\n"; for (my $z=0; $z<4; $z++) { for (my $s=0; $s<4; $s++) { printf "%+0.2f ", $probe->[$z][$s]; } print "\n"; } }); # }}}2 $top->bind('<M>' => # {{{2 sub { { $mm->freeRot($V->{horiz}, -$qb->{rS}); } plotAll; }); # }}}2 $top->bind('<p>' => # {{{2 sub { #print "<p> tut nix\n"; print "\$actCube: $actCube\n"; }); # }}}2 $top->bind('<P>' => # {{{2 sub { { $mm->freeRot($V->{horiz}, $qb->{rS}); } plotAll; }); # }}}2 $top->bind('<Control-p>' => # {{{2 sub { print "CTRL-p\n"; foreach ($V->{xAxis}, $V->{yAxis}, $V->{zAxis}) { } }); # }}}2 $top->bind('<q>' => \&lebWohl); $top->bind('<r>' => # {{{2 sub { $mm->rotate(-$qb->{rS}, 0.0, 0.0) if ($qb->{actAxis} eq "x"); $mm->rotate( 0.0,-$qb->{rS}, 0.0) if ($qb->{actAxis} eq "y"); $mm->rotate( 0.0, 0.0,-$qb->{rS}) if ($qb->{actAxis} eq "z"); plotAll; }); # }}}2 $top->bind('<S>' => # {{{2 sub { keys %{$qb->{constraint}} && return; $qb->shuffle($V->{shuffleSteps}, $movLBox); }); # }}}2 $top->bind('<s>' => # {{{2 sub { $qb->{cube}[$actCube]->showAttr; }); # }}}2 $top->bind('<Control-s>' => # {{{2 sub { save(); }); # }}}2 $top->bind('<t>' => # {{{2 sub { print "matob::dotProd(\$xAxis, \$yAxis): ", matob::dotProd($V->{xAxis}, $V->{yAxis}), "\n" +; #$V->{horiz}->showAttr; }); # }}}2 $top->bind('<T>' => # {{{2 sub { print "$actCube\n"; #rp4rp3 $V->{triX} = new line3d($qb->{cube}[$actCube]{r2}{p4}, $qb->{cube}[$actCube]{ +r2}{p3}, 1, "white", "triX"); #rp4rp1 $V->{triY} = new line3d($qb->{cube}[$actCube]{r2}{p4}, $qb->{cube}[$actCube]{ +r2}{p1}, 1, "#42ff00", "triY"); #rp4gp4 $V->{triZ} = new line3d($qb->{cube}[$actCube]{r2}{p4}, $qb->{cube}[$actCube]{ +r4}{p1}, 1, "cyan", "triZ"); $V->{plotTri} = $V->{plotTri} ? do {remTri; 0} : plotT +ri; }); # }}}2 $top->bind('<u>' => # {{{2 sub { return unless my $rZug = $movLBox->get('end'); $qb->undoMove($rZug); $movLBox->delete('end'); $movLBox->see('end'); }); # }}}2 $top->bind('<v>' => # {{{2 sub { }); # }}}2 $top->bind('<V>' => # {{{2 sub { print Data::Dumper->Dump([%$V]); }); # }}}2 $top->bind('<X>' => # {{{2 sub { print Data::Dumper->Dump([%cL]); }); # }}}2 $top->bind('<w>' => # {{{2 sub { $qb->showAttr; }); # }}}2 $top->bind('<x>' => # {{{2 sub { $qb->{actAxis} = "x"; updDashBoard; }); # }}}2 $top->bind('<y>' => # {{{2 sub { $qb->{actAxis} = "y"; updDashBoard; }); # }}}2 $top->bind('<z>' => # {{{2 sub { $qb->{actAxis} = "z"; updDashBoard; }); # }}}2 $top->bind('<Button-2>' => # {{{2 sub { $V->{plotCS} = $V->{plotCS} ? do {remCS; 0} : plotCS; $V->{plotTri} = $V->{plotTri} ? do {remTri; 0} : plotT +ri; }); # }}}2 $top->bind('<MouseWheel>' => sub {print "MouseWheel\n"}); $rSentry->bind('<Enter>' => # {{{2 sub { $rSentry->focusNext; }); # }}}2 $leave->bind('<Button-1>' => \&lebWohl); $rfDeckl->bind('<Button-1>' => # {{{2 sub { #print "<Button-1 / \$rfDeckl>\n"; $rfDeckl->configure(-width => 0); }); # }}}2 $lvLab->bind('<Button-1>' => # {{{2 sub { #print "<Button-1 / \$lvLab>\n"; $rfDeckl->configure(-width => 50); }); # }}}2 $tlfDeckl->bind('<Button-1>' => # {{{2 sub { #print "<Button-1 / \$tlfDeckl>\n"; $tlfDeckl->configure(-width => 0); }); # }}}2 $blfDeckl->bind('<Button-1>' => # {{{2 sub { #print "<Button-1 / \$blfDeckl>\n"; $blfDeckl->configure(-width => 0); }); # }}}2 $hMovLBox->bind('<Button-1>' => # {{{2 sub { #print "<Button-1 / \$hMovLBox>\n"; $tlfDeckl->configure(-width => 50); }); # }}}2 $canvas->bind('line3d', '<Button-1>' => # {{{2 sub { print "'line3d', <Button-1>\n"; my $v = shift; my $id = $v->find(qw/withtag current/); my $name = ($v->gettags('current'))[0]; print "line3d $name\n"; $V->{$name}->showAttr; print "\neVec: ("; print "$_\t" for @{$V->{$name}->eVec}; print ")\n"; }); # }}}2 $canvas->bind('vec3d', '<Any-Enter>' => # {{{2 sub { print "'vec3d', <Any-Enter>\n"; my $v = shift; my $id = $v->find(qw/withtag current/); my $name = ($v->gettags('current'))[0]; my $ref; eval "\$ref = \$$name"; my ($x, $y, $z) = ($ref->{p2}{lx}, $ref->{p2}{ly}, $ref->{p2}{lz}) +; $vecAnz->configure( -background => $highLightBgColor, -text => $ref->{name} ); $sVxAnz->configure( -background => $highLightBgColor, -text => sprintf "%-0f", $x ); $sVyAnz->configure( -background => $highLightBgColor, -text => sprintf "%-0f", $y ); $sVzAnz->configure( -background => $highLightBgColor, -text => sprintf "%-0f", $z ); my $nrm = matob::vNorm($x, $y, $z); $sVnAnz->configure( -background => $highLightBgColor, -text => sprintf "%-0f", $nrm ); }); # }}}2 $canvas->bind('vec3d', '<Any-Leave>' => # {{{2 sub { $vecAnz->configure( -background => $labDefColor, ); $sVxAnz->configure( -background => $labDefColor, ); $sVyAnz->configure( -background => $labDefColor, ); $sVzAnz->configure( -background => $labDefColor, ); $sVnAnz->configure( -background => $labDefColor, ); }); # }}}2 $canvas->bind('cube', '<Button-1>' => # {{{2 sub { print "cube-<Button-1>\n"; my $e = $Tk::event; ($V->{xb1down}, $V->{yb1down}) = ($e->x, $e->y); $canvas->configure(-cursor => 'exchange'); $qb->{slice}{gripped} = $qb->{slice}{$sliceAnz->cget('-text')}; }); # }}}2 $canvas->bind('cube', '<Alt-Button-1>' => [ # {{{2 sub { my ($canv, $old_fill) = @_; #print "<Alt-Button-1>\n"; my $id = $canv->find(qw/withtag current/); #print "\$id: $id\n"; $canv->itemconfigure($id, -outline => "#ffff64", -width => 5 ); my $actRect = ($canv->gettags('current'))[1]; #print "\$actRect: $actRect\n"; print "\$old_fill: $$old_fill\n"; #my $initialColor = $$old_fill; my $newColor = $top->chooseColor( -title => "Choose a color" +, -initialcolor => $$old_fil +l); $newColor ||= $$old_fill; print "\$newColor: $newColor\n"; $qb->{cube}[$actCube]{$actRect}{iColr} = $newColor +; $canv->itemconfigure($id, -outline => "black", -width => 1 ); plotAll; }, \$V->{old_fill}]); # }}}2 $canvas->bind('cube', '<Double-Button-1>' => # {{{2 sub { print "<Double-Button-1>\n"; $qb->{slice}{marked}->changeColor(0); $canvas->configure(-cursor => 'exchange'); #$canvas->configure(-cursor => 'target'); my $canv = shift; { keys %{$qb->{constraint}} && last; $qb->{actAxis} eq "x" && do { $qb->{actAxi +s} = "y"; last; }; $qb->{actAxis} eq "y" && do { $qb->{actAxi +s} = "z"; last; }; $qb->{actAxis} eq "z" && do { $qb->{actA +xis} = "x"; last; }; } $qb->selSlice; plotAll; $sliceAnz->configure( -text => $qb->{slice}{marked}{name +}); $qb->{slice}{gripped} = $qb->{slice}{$sliceAnz->cget('-text' +)}; }); # }}}2 $canvas->bind('cube', '<Shift-Button-1>' => [ # {{{2 sub { my ($canv, $old_fill) = @_; print "<Shift-Button-1>\n"; my $id = $canv->find(qw/withtag current/); $canv->itemconfigure($id, -fill => undef); }, \$V->{old_fill}]); # }}}2 #$canvas->bind('cube', '<Any-Enter>' => [\&cscroll_enter, \$old_fill]) +; $canvas->bind('cube', '<Any-Enter>' => [ # {{{2 sub { #$qb->{slice}{gripped} && return; print "'cube', <Any-Enter>\n"; $V->{freezeCvac} || do { $V->{cvac}->{p2} = $qb->{cube}[$act +Cube]{centr}; plotAllVectors; }; $V->{PFLAG} == 0 && return; # OTHERWISE ENDLESS-LOO +P !!! my ($canv, $old_fill) = @_; my $id = $canv->find(qw/withtag current/); $id-- if ($canv->gettags('current'))[0] eq 'text'; $$old_fill = ($canv->itemconfigure($id, -fill))[4]; ($actCube = ($canv->gettags('current'))[0]) =~ s/c(\d+)/$1/; my $actRect = ($canv->gettags('current'))[1]; updDashBoard; $qb->selSlice; $sliceAnz->configure(-text => $qb->{slice}{marked}{nam +e}); $V->{PFLAG} = 0; # avoid renewed sub-run-through w +hich # will be caused (suspected) b +y poly- # gon-redrawings plotAll; # cube/rect-names in statusline # selected cubes-names should be red (deprecated due t +o # slice-highlighting ?) my $fg = $qb->{slice}{marked}{members}{$actCube} ? "red +" : $rgb +{DarkGreen}; $cubAnz->configure( -text => "c" . $actCube, -foreground => $fg); $rectAnz->configure( -text => $actRect); # update coordinate- and distance-display in dashboard my $dist = $mm->vNorm($qb->{cube}[$1]{centr}{wx}, $qb->{cube}[$1]{centr}{wy}, $qb->{cube}[$1]{centr}{wz} + $ +distance); $xKoor3d->configure(-text => sprintf "%0f", $qb->{cube}[$1 +]{centr}{wx}); $yKoor3d->configure(-text => sprintf "%0f", $qb->{cube}[$1 +]{centr}{wy}); $zKoor3d->configure(-text => sprintf "%0f", $qb->{cube}[$1 +]{centr}{wz}); $distLab->configure(-text => sprintf "%0f", $dist); $lxAnz->configure(-text => sprintf "%0f", $qb->{cube}[$1]{ce +ntr}{lx}); $lyAnz->configure(-text => sprintf "%0f", $qb->{cube}[$1]{ce +ntr}{ly}); $lzAnz->configure(-text => sprintf "%0f", $qb->{cube}[$1]{ce +ntr}{lz}); } , \$V->{old_fill}]); # }}}2 $canvas->bind('cube', '<Any-Leave>' => [ # {{{2 sub { my($canv, $old_fill) = @_; my $id = $canv->find(qw/withtag current/); $id-- if ($canv->gettags('current'))[0] eq 'text'; $canv->itemconfigure($id, -fill => $$old_fill); $qb->{slice}{marked}->changeColor(0); $V->{PFLAG} = 1; plotAll; } , \$V->{old_fill}]); # }}}2 $canvas->bind('cube', '<B1-Motion>' => # {{{2 sub { ($Z++ <= 1) ? return : do {$Z = 0}; foreach (keys %{$qb->{slice}{marked}{members}}) { $qb->{cube}[$_]{palette} = 0; } my $e = $Tk::event; my ($xnow, $ynow) = ($e->x, $e->y); my $dir = ($V->{xb1down} > $xnow) ? 1 : -1; $qb->{slice}{gripped}{rot} += $dir; $qb->{sMovFlag} = 1; foreach (keys %{$qb->{slice}{marked}{members}}) { $qb->{cube}[$_]->rotate($qb->{rS} * $dir, 0.0, + 0.0) if ($qb->{actAxis} eq +"x"); $qb->{cube}[$_]->rotate(0.0, $qb->{rS} * $dir, + 0.0) if ($qb->{actAxis} eq +"y"); $qb->{cube}[$_]->rotate(0.0, 0.0, $qb->{rS} * +$dir) if ($qb->{actAxis} eq +"z"); } plotAll; ($V->{xb1down}, $V->{yb1down}) = ($xnow, $ynow); }); # }}}2 $canvas->CanvasBind('<Motion>' => # {{{2 sub { $xKoor->configure(-text => $Tk::event->x); $yKoor->configure(-text => $Tk::event->y); }); # }}}2 $canvas->CanvasBind('<Control-Button-1>' => # {{{2 sub { print "<Control-Button-1>\n"; print "\$actCube: $actCube\n"; # hol mir das sliceObjekt zu diesem cube my $slice = $qb->sliceOfCube($actCube); $slice->changeColor; }); # }}}2 $canvas->CanvasBind('<Double-Button-3>' => # {{{2 sub { $V->{plotCS} = $V->{plotCS} ? do {remCS; 0} : plotCS; }); # }}}2 $canvas->CanvasBind('<Button-1>' => # {{{2 #$canvas->CanvasBind('<Button-3>' => sub { $qb->{slice}{gripped}{name} && return; $canvas->configure(-cursor => 'fleur'); plotAllVectors; my $e = $Tk::event; ($V->{xb3down}, $V->{yb3down}) = ($e->x, $e->y); }); # }}}2 $canvas->bind('cube', '<Button-3>' => [ # {{{2 sub { #$canvas->CanvasBind('<Button-3>' => [sub { my($w, $x, $y) = @_; print "\$hiddenM: $hiddenM\n"; $hiddenM->post($x, $y); }, Ev('X'), Ev('Y')]); #}}}2 $canvas->CanvasBind('<B1-Motion>' => # {{{2 #$canvas->CanvasBind('<B3-Motion>' => sub { $qb->{slice}{gripped}{name} && return; my $e = $Tk::event; my ($xnow, $ynow) = ($e->x, $e->y); my $xdir = ($V->{xb3down} - $xnow) / 10; my $ydir = ($V->{yb3down} - $ynow) / 10; $V->{horiz}->{p2}->creaHVWC([1, 0, 0]); $V->{vertik}->{p2}->creaHVWC([0, 1, 0]); $mm->freeRot($V->{horiz}, $qb->{rS} * -$ydir); $mm->freeRot($V->{vertik}, $qb->{rS} * -$xdir); plotAll; ($V->{xb3down}, $V->{yb3down}) = ($xnow, $ynow); }); # }}}2 $canvas->CanvasBind('<ButtonRelease-3>' => # {{{2 sub { $canvas->configure(-cursor => 'crosshair'); }); # }}}2 $canvas->CanvasBind('<ButtonRelease-1>' => sub # {{{2 { print "ButtonRelease-1\n"; print "\$qb->{slice}{gripped}{name} ", $qb->{slice}{gripped}{name},"\n"; $canvas->configure(-cursor => 'crosshair'); $V->{PFLAG} = 1; plotAll; my $slice = $qb->{slice}{gripped} || return; $qb->{slice}{gripped} = {}; $qb->{sMovFlag} && do { print "moved slice was : ", $slice->{name}, "\n"; my $rest = $slice->{rot} % $rotSiSteps; my $movs = int($slice->{rot} / $rotSiSteps); $rest ? do { #print "\$rest: $rest\n"; #print "incomplete move\n"; $qb->{constraint}{$slice->{name}} = $slice; } : do { #print "\$movs: $movs\n"; $qb->corr($slice); $movs && do { $zug = sprintf("%4d: %2s%-2d", $movLBox->index('end') + + 1, $slice->{name}, $movs); print "valid move: $zug\n"; $movLBox->insert('end', $zug); $movLBox->see('end'); $saveIt = 1; $slice->{rot} = 0; }; #print "delete ", $slice->{name}, "aus constra +intHash\n"; delete ${$qb->{constraint}}{$slice->{name}}; $qb->updSlices; }; }; $qb->{sMovFlag} = 0; print "Cubes ", $qb->check ? "bad" : "OK", "\n"; #print "members: ", Dumper $slice->{members}, "\n"; }); # }}}2 # END bindings }}}1 $mm->rotate(PI/-6, PI/6, 0.0); plotAll(); #$qb->detSlViaNam($canvas, "slx10"); #print ALL_EVENTS;
      MainLoop; sub opts { # {{{1 # tos-Standards:# # $opt_h : help # $opt_l : logfile # $opt_v : schwatzhaft # $opt_V : zeige Version OPT: { $opt_h && do { print <<"EOHELP"; einsatz wasses tut ... Usage: $0 [OPTION]... [FILE]... Options: -h this helptext -v be verbose -V show version Examples: tosSkel ... EOHELP exit; }; $opt_V && do { print "$0, $VERSION\n" && exit; }; # $opt_l && do { # print "log-file is: $opt_l\n"; # $tos::logFile = "$opt_l"; # }; $opt_v && do { print "mode: verbose\n"; }; } } # end opts }}}1 # logos {{{1 sub ptk { #{{{2 my $xpm = <<'end-of-xpm'; /* XPM */ static char *ptk[] = { /* columns rows colors chars-per-pixel */ "88 31 39 1", " c black", ". c #111111", "X c #333300", "o c #222222", "O c gray20", "+ c #663300", "@ c #663333", "# c #666633", "$ c #444444", "% c #555555", "& c gray40", "* c #777777", "= c #006699", "- c #336699", "; c #339999", ": c #669999", "> c #990000", ", c #996633", "< c #996666", "1 c #CC3333", "2 c #CC6666", "3 c #FF6666", "4 c #999966", "5 c #CC9966", "6 c #CCCC66", "7 c #888888", "8 c gray60", "9 c #AAAAAA", "0 c #BBBBBB", "q c #9999CC", "w c #FF9999", "e c #CCCC99", "r c #FFCC99", "t c #FFFF99", "y c gray80", "u c #FFCCCC", "i c #FFFFCC", "p c #EEEEEE", "a c gray100", /* pixels */ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaa ", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaa ", "aa0y00y00y00y00y00y00y00y00y00y00y00y00y00y00y00y00y00y00y00y00y00y00 +y00y00y00y00y00y0 ", "aa000y00000y00000y00000y00000y00000y00000y00000y00000y00000y00000y000 +00y00000y00000y00 ", "aay0 000077y00y97y098y98089977809780097780977y +00009780079y8800y >", "aa00 iiiiiiiiiiiiiiiiiiiiii y0y% O 90$.oo97 0Oo0 7% O%yO.oo0% O%yO.o +7y0yO..Oy%O0 *y00>>", "aa0y iiiiiiiiiiiiiiiii4,5ti 00y%OyO%8 0yO%0 8 9 y%Oy00O%0 8%Oy00O%y% +.000O%7 00 &Oy001>>", "aa00 iiiiiiiiaiiiiiiii#,@+5 00y%.% 7%O00%O0o&OO%Oy% O0O $y% O0O%y7 + 0y0O $0y% 70011>>", "aay0 iiiiiiie4,4eiiiii,##5r y00%.&9y7 00O%y%O%$.%0%Oy00O%7 0%Oy00O%y% +oy00O%0 807 y0111>>", "aa00 iiiiiie@,5<#4tiie,#tii 00y%Oy00y$.oo00* 7& 7y% OOyO%0 7% OOyO.o. +800yO.ooy07 01111>>", "aa0y iiiii5#<45<4,,rr<,4iii y0098000008800y070070y9777089y8997770879y +0y0087800y0711111>>", "aa00 iiii,,4555555<,,,,eiii 00y0y0y0y0y0y000y000y00y0y00y00yyy0y0y0y0 +00000y0y000111111>>", "aay0 iiie,55555555554,4iiii 0y000000000000y000y00y00y00y00009;q00000y +0y0y09000y1111111>>", "aa00 iti,5<45555554#@<iiiii 00:====-==-9000y000y00y000000y9===90y0y00 +:;====;y011111111>>", "aa0y iii#5,X,4<<54X,eiiiiii y000==-0y:==:y000y00y0000y0y000:==q000000 +======:0111111111>>", "aa00 iie#,,@,##++,+tiiiiiii 0000==;y00;==000y00000y0y0000y09==900y0y9 +=999qy01211u11111>>", "aay0 iie#@,riir# #<<riiiiii y0y0==;000:==90y0:::90000q;0::0q==90y000; +;q000012p33aw1111>>", "aa00 itiXX,iiii,+it4@iiiiii 000y==;00y;==q0:=;9:=-0y:=====-9==9000y0= +====;11wpuwauw111>>", "aa0y ii,,#4iiir+6iir#iiiiii 0y00==;00:==;0:=;000==::===:==:9==90y00y= +====1111wapaaau31> ", "aa00 ii#i,eiia5#iiii,iiiiii y000===--==;0q===;;;;-:0:==00y09==9000000 +yq:11pu11waawuu11 ", "aay0 it@i+riia<5iiii,riiiii 00y0==;099000:==90000000:==0y009==9y0y0y0 +0011paa111wau311y ", "aa00 ir,i,eiia,tiiii,5iiiii 000y==;00y0y0:==90y00y00:==00009==900000y +011aaau3111wu11y0 ", "aa0y i54ie,iii,iiiii4@tiiii 0y00==-y00000:==;00y000y:==y00y9==9y00y00 +111uuuau311111000 ", "aa00 i,<ii#rii@eiiiiiiiiiii y000==;000y0y0===9000090:==00009==900y001 +111112uauw1110y0y ", "aay0 ir5ii4,iietiiiiiiiiiii 00yq===0y00000:===:9:=:0:==0y0y:==:0y0011 +1111112uaw110y000 ", "aa00 iiiiiiiiaaiiiiiiiiiiii 00:;;;;-:0y0y009;===;9y;;;;;:0:;;-;:00111 +11111112u210000y0 ", "aa0y 0y000000y0000y000000y00000000000000001111 +11111111110y0y000 ", "aa00y00y00y00y00y00y00y00y00y000y0y0000y0000y00y0000y00y00y0y0y011111 +1111111110y00000y ", "aay000y00y00y00y00y00y00y00y00y00000y0y00y0y00y00y0y00y00y00000111111 +111111110000y0y00 ", "a >>>>>>> +>>>>>>> ", " >>>>>>>> +>>>>>> " }; end-of-xpm return $xpm; } # end ptk #}}}2 sub cwVim { #{{{2 my $xpm = <<'end-of-xpm'; /* XPM */ static char *cwVim[] = { /* columns rows colors chars-per-pixel */ "88 34 257 2", " c #000400", ". c #08040A", "X c #070411", "o c #0E0503", "O c #020333", "+ c #0C0047", "@ c #00064E", "# c #0F053C", "$ c #0C1105", "% c #040369", "& c #0B120F", "* c #00095F", "= c #100078", "- c #062103", "; c #111C18", ": c #191914", "> c #1C1818", ", c #191D09", "< c #13200D", "1 c #121D20", "2 c #17163C", "3 c #211913", "4 c #0C1954", "5 c #001B70", "6 c #032C0F", "7 c #1D1B26", "8 c #231B20", "9 c #1B1B36", "0 c #2C1725", "q c #1A2A19", "w c #22271D", "e c #033E00", "r c #222826", "t c #2D242E", "y c #2B2726", "u c #153902", "i c #0B3D12", "p c #2A292E", "a c #332629", "s c #302922", "d c #30293A", "f c #004F02", "g c #25372C", "h c #154801", "j c #153E3C", "k c #263A28", "l c #31362A", "z c #313633", "x c #31353C", "c c #1C461C", "v c #30344B", "b c #3D3336", "n c #3B3635", "m c #3C3542", "M c #035E05", "N c #1A5119", "B c #016300", "V c #453935", "C c #36442F", "Z c #005E37", "A c #44402F", "S c #2B4E32", "D c #3E4436", "F c #036B08", "G c #424144", "H c #37483E", "J c #5A3649", "K c #007200", "L c #40463F", "P c #4E3D4D", "I c #4B453A", "U c #424650", "Y c #484643", "T c #4B4651", "R c #4A494D", "E c #018000", "W c #5A474B", "Q c #48573F", "! c #107D13", "~ c #515057", "^ c #594B60", "/ c #574F56", "( c #585246", ") c #53534F", "_ c #4B5948", "` c #4E5557", "' c #4F564F", "] c #495951", "[ c #535648", "{ c #4F5663", "} c #5E5252", "| c #00900F", " . c #4E5673", ".. c #009400", "X. c #645461", "o. c #55605D", "O. c #5B5E5D", "+. c #5F5B67", "@. c #009D0C", "#. c #00A000", "$. c #4C6C54", "%. c #586659", "&. c #5F6358", "*. c #655F5E", "=. c #5E6752", "-. c #5D636D", ";. c #646165", ":. c #676357", ">. c #00AA00", ",. c #5C6967", "<. c #71615D", "1. c #706067", "2. c #6E6075", "3. c #656867", "4. c #626E52", "5. c #7D5D6F", "6. c #6C6E54", "7. c #766471", "8. c #00B600", "9. c #756D56", "0. c #726F63", "q. c #67765F", "w. c #68736E", "e. c #6F6E79", "r. c #697376", "t. c #6F7366", "y. c #697668", "u. c #727074", "i. c #777070", "p. c #737472", "a. c #757C80", "s. c #8C7282", "d. c #7A7E75", "f. c #787F7A", "g. c #7D7C82", "h. c #738972", "j. c #867F8B", "k. c #8D7B8E", "l. c #8C7F85", "z. c #7B878B", "x. c #917B96", "c. c #8B837D", "v. c #828783", "b. c #85877E", "n. c #86858B", "m. c #8B8879", "M. c #8B8685", "N. c #848F89", "B. c #8F8D91", "V. c #889193", "C. c #938E8C", "Z. c #948C98", "A. c #8F918C", "S. c #968AA0", "D. c #A28697", "F. c #8E909B", "G. c #8C9883", "H. c #9F8F92", "J. c #8E9990", "K. c #89A980", "L. c #BF8DB1", "P. c #9CA5A8", "I. c #AC9BB2", "U. c #A4A2A6", "Y. c #A9A0A6", "T. c #A1A3AE", "R. c #AC9FAC", "E. c #9EAAA2", "W. c #A6A7A2", "Q. c #A9A3B1", "!. c #ABA5A3", "~. c #BE9BAE", "^. c #B7A2A9", "/. c #AAB0B3", "(. c #B0ADB7", "). c #B2ADB2", "_. c #AFB1AE", "`. c #B5B3A1", "'. c #ADB6AE", "]. c #B4B4AB", "[. c #B2B1C2", "{. c #B9B3B1", "}. c #BDAEC5", "|. c #AFB8BA", " X c #C3AFB5", ".X c #B5B7B4", "XX c #9AC2C3", "oX c #C0B0BE", "OX c #B8B4BF", "+X c #B9B5BA", "@X c #D2A7CA", "#X c #B5BFBA", "$X c #BFBCC1", "%X c #BAC1B6", "&X c #CCB8BA", "*X c #C0BFB6", "=X c #BBC1C3", "-X c #C4BEBC", ";X c #C6BCC3", ":X c #BEBFC9", ">X c #BFC1BD", ",X c #C6BBCF", "<X c #CABFB3", "1X c #C4BECA", "2X c #CEB9CB", "3X c #C3C1C5", "4X c #CBBCCA", "5X c #C2C6B3", "6X c #B7CABD", "7X c #B6CAC2", "8X c #D0BFC7", "9X c #C8C5CA", "0X c #C0C8D0", "qX c #C1CAC5", "wX c #C3C8CB", "eX c #C6C8C5", "rX c #C4CAC0", "tX c #D9BCD2", "yX c #D5C1C3", "uX c #CCC6C4", "iX c #CEC4CA", "pX c #C8C6D1", "aX c #CAC9C0", "sX c #CCCACE", "dX c #C5D5C8", "fX c #CAD1D4", "gX c #D5CDCC", "hX c #C2DAC1", "jX c #C9D4CF", "kX c #D4CFD4", "lX c #D2D0DB", "zX c #D2D5D1", "xX c #D4D7C7", "cX c #DECFDD", "vX c #E2CFE5", "bX c #D9D8CF", "nX c #D3DBDD", "mX c #DBD8DC", "MX c #E0D8D6", "NX c #E0DEE2", "BX c #DFE2DF", "VX c #E3DEED", "CX c #D5EDDC", "ZX c #EAEAE1", "AX c #E6EBE8", "SX c #EEE8E5", "DX c #EFEBF0", "FX c #FCE6F6", "GX c #F0F3EF", "HX c #EFF3F7", "JX c #FEEDFF", "KX c #F8F3F1", "LX c #F6F9ED", "PX c #FEFBFF", "IX c #FCFFFC", "UX c gray100", "YX c None", /* pixels */ "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY +XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXLX! +K YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY +XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXCXYXM #. +8.f DXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY +XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX*.f.1.f.l.y.d.t.s.h.E #. +E 8.B o k d.d.w.l.i.d.a.w.d.x YXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY +XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX5.GXMXlXhXnXvXnXkXCXvXP h +>.| 8.N AXFXcXnX0XCXvXiXmXZXY.. YXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY +XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXfX] nX+XlX2X2XyX-X4X=XtXT B +>.@.@.c @XhX3XuXiX1XaXkX|.9XF. YXYXYX", "IXIXLXGXLXGXPXGXHXHXHXHXHXHXHXHXKXGXKXKXKXKXKXKXAXGXAXGXAXGXGXGXGXGXK +XDXDXDXDXDXLXGXGXGXGXGXSXDXBXSXAXAXAXAXBXMXv.J 0.xX;X>X6X,X6XS.;.M | +..@.| ! N ^ ,X6X@XqX>X<XpX=Xe.I 3.f.wX", "KXAXAXBXBXBXNXZXZXZXZXZXZXZXZXZXAXAXAXAXAXAXAXAXAXSXAXDXAXNXAXNXBXBXZ +XbXZXbXBXBXnXNXNXmXmXnXzXBXnXMXMXnXmXMXfXeX0Xo.A.gXeXuX8XyXyXk.z ..>. +#.E >.| f k.NXhXyXdXgXgX(.) r =.,.3.g.", "IXZXzXlXgXsXwXzX:X$X;X;X;X:X:XpX1X:X:X:X:X:X:X3X$X:X$X-X$X3X1X3X1X1X1 +X:X$X1X;X$X$X=X-X;X1X3XeXqX>X>X.X+X{.+X{./..Xi.k.lX4X:X0X=XqXJ.0 ..| +..>.#.f Z.AXfX2X7X}.wX1XO.l L L ~ *.} ", "IXBXiX1X3XwX0XeXkXwXeXsXyXuXeXuXeXeXeX>X>XeX=X=X3X3X:X3X$X$X1X;X.X+X{ +.>X.X.X.X#X+X.X_._.).{.{.Y._..X.X/._..X_./.U.e.i.CX8XeXyX2X1Xc.0 >.>. +E @.N K.IXmX$X;X2XhX).;.> l ' ' ] _ 3.", "IXMXlXlXjXzXsXkXfXeXsXeX0X9X$XqX;X;X$X3X3X$X-X-X-X$X-X$X$X-X+X$X-X>X$ +X>X>X).;X+X;X$X/.).>X#X{.Z.P.).{..X/.).).U.!.q.j.mX=XuX,XqXpXV.p ..@. +8.f W.JXkX'.kX6X2X).u.; H g U %.t.' -.", "IXbXqXaXgXjXn./ ;.M.>XiXdXsX-X=X=XpXwX-X.XqX$XqX-X{.eX{.:X{.wX=X;.;X/ +.=X4X_.6X)._.oX|. X`.oXJ.: X #X).<X/.[.`.T.}.Q k.NX%X1XwXaXzXx.g ..| +F M.PX,XeX;XsXxXR.e.- 3 v L =.2.1.t.} ", "LXVXfX;XdX2.& :.~ > ,.lX|.3XNXgXeXpX*XlXlXqXlX{.:XqXfX:XxXeXOX*Xw n.m +X{.7X:X8X7X4XqXoXXX}.6X;XB.: R.|.|.^.{.U._.d.N l.lX-X3XwX;X8Xn.V #.B +m.IX2XxXoX0XfX~.e.h #.M r ` %.y.a./ r.", "PXAXpXfXI. OXAXmXR V.H.; x n o z 2X`.m g Z.BX{.x $ i.=X.X7 X + x .X).{ 1 :.xX1Xf.y , x & %X^.]._.oX1Xk.! F J.lX8X1XeX;X$XM.d f G. +JX<X:XuXwXeXQ.-.u @.>.#.B U ^ 2.d.w.X.", "IXZXrX4XP.r %X1XeX>XzX3Xw. p V.) [.3 ;.0X:.x {.pXt.H.F.o wX[.`.X y.W +.D.$XH n .Xn.p g.P.X -.Z.t OX%X[.[.].V.F >.K n.BX=X4X3XqX;XA.7 W.DX +kXpX>X,XdX Xe.e @.@.| #.8.B v 6.u.-.*.", "IXBXzXkXE.t =XfXsXMXkXmXv.: kXkXnXC. > X o V.].x 1 o X H.eX;Xw Q.( +.xXwX. . & : b 4.I fX+XA.& `.{.E.{.m.F 8.>.F x.kX6X4X;X9XuXu.'.FXfX +5X1X3XsX!.r.u | #...@.....8.! { 4.X.,.", "IXGXpXjXQ.& Y.qXmXz.U.zXB.z OXfXuXb.. f.A.B.b.lXR s W.n.l =X[._.q D.: +X7XH.8 ] l.z.j.E.7.r OXnXr.X OX_.2XOXS j j @.F c.kXwXpXwXwX=XD.NXjXyX +|.uXnX~.e.u @.>.| @.#.>.| | Z z +.4.X.", "KXDXdX,XjXl. 8 > H.v.. o a r +XMXU . y ; _.R . ) & r nX+Xa $ r + . e.N.. p p ` %XX $ > o _ /.).#X{.^ = Z F G.kX3X;X=X9XeXF.cXwXsX +tX7X'.u.u | #.....@...#...4 @ H ` { &.", "PXNXlX6XzXmXOXV.a.jX:X/.n.w.n.d.>X1XaX+Xu.J.wXeX3X3.R g.M.a.3X*X/.N.i +.).rXpX[.0.p./.gX0X{.n.i./.J. X(.'./.T.E.H % 1 S.NXuX;X3XiX9XuXqXtX%X +!.X.t e #.#...#.#.@.@...% @ g Y o.] +.", "PXBXkX9XeXsXlXMXsXuXuX9XsXpXfXfXeX3X-X9XpXpX:XOXqXeXzX1XaXxX0X*X1X:X3 +X;X{.$X:XeX/.qXoX|.%XoX$X>X_.:X<XW.=X].).U.) O j.BX$XeXeX3X<X7X4XzXE. +) Q.-.B #.@.#.| @...@.5 = q / :.] +.t.", "PXBXwXsXwX3XiXsXwXwXeXeXsXwX9X3X9XwXwX3XuX-XuX>XuX[.).<X[.+X$XoX%X%X: +X|.%X*X).=X4X].!.{.-XrXE.=X/./.>X).).!.T.V.m.v c.bX1XpXiXyXlX}.hXtXI. +4.wXD.B ..>.| ..8.! 4 # 7 C C G w.%.2.", "PXAXwXwXwXeX9XeXsXpX:X=XuX=X3X3X;X;X3X=X$X=X3XuX-X#XqXwXqX'.=XaX:X!.y +X$X[.}.^.%XOX|.wX).Q.*XyXY.=X!.).{._.!.{.P.W.` C.nX$X3X:X:XhX@X=XrX}. +r 8 f K B F 8.! M 9 @ ; < z ` e.X.$.O.", "PXBXkXsXqX=X3XuXwXeX9X9X=XeXeX=X=X=X3X;X3X;X$X:X1XuX+X[.gX{.[.>X&.G ( +.1X'.5X|.P.*XI.>X) . |.T.|.=X_.(.=X/.(.`./.H.o.l.lXeXuXOXwX,XeXlXE.g +7 5.6 ;.s.` - ^ t.-.X O.-.r D %.s.` i.", "PXBXsXpXsX9X:X>XwXeX9X9X3XwXwXwXwX>X=X=XwX9X$X+XwX0XeX%XpX=XxX=XT.y.r +X<X(.[.-.I dXVXE.%X .X&X-X;X{.T.{.).T.].U.Q.t.m.mXeXiX:XqXjX>XR.m < +[.MX- i 0XVX%XlXcXpX%XvXLXS.6 u.,.<.+.", "IXBXsXiX9XsXiXwXuX3XwX9X9XeX>X=XuX3X=X3X-X>X>X|.G G )./.U m ).e.V x 0 +X}.eXJ.X X b p J.kX. %.L 3.C.=X/.+X/././.!.[.y.B.kXeX1X$XeX.XL.$.f S +eXu.f k wX<.R r.fX<.{ r.<XT b { d.O.O.", "IXBXfXwXwXfXsXqXwX3X=X9X:XpX9X=X1X;X3X=X3X$X-X{.1 < n.V.< & /.A.m ; % +X{.>XP.r l +.o.P.pX. > ) 8 3.9X'..X/.'.).W.U.p.j.lXaXyX9X4XT.S M F 5. +oXS f G.}.2 O G.T., !.S.k / $.t.+.*.", "PXBXiX1XwX3XsXwXfXqXwXwX9X9XuX-XeXeXeX9X=XeX3XfXp.b t s G -.bX0XP.: + +X1XOX-XO.U wX].oXzX Q.0X3.z +X{.).{.{.OX/.).3.Z.bX=X1X>X{.I B >.N 5X +x.f S OXj.+ v tX0.& b nX=.9 ] :.r.i.,.", "LXnXzXrXaX:X:XwX1XwXeX-X>XqXeX-X3X$X>X3X$X=X$XiX'.. r . $ l.fXpXT.. j +X*XaXqX*.Y lXrXwXbXo P.pX<.U qX)._./.].|.!./.w.H.VXeX0XH.O.# 5 B e.Q. +h f e.). v.T.$ & B.).w n O.:.a.*.q.", "PXNXpXsXsXiXuXaX3X3X:X:X3X:XpX3XyXeX3X-XuX3XwX3X0X R / . W.zXY ` ~ + ,./.&X3.. o.n t V.$ ,.Y.z $ J.+X>X+X!.). XY.C.,.a.H.Z.U q 7 + O }.eX +[ & iXfXd : :X*Xx y (.^.H ] -.-.a.2.2.", "IXbXeXsXpXpXlX3XaXeXrXeXeXeX9XwX3X=XwX=X=X=X=X=X+X*.l.W./ .XOXY n z b + ` /.sX|.3.t &.n.v.8 L F.I x H.Q.(.).|././.E. Xg.x s w j *._ S + 2 - +c * , w r p w p n m r d r ' r.a.N.9.&.", "IXBXeXwXeXeXeX:XsXwXsX9X3X3X3X;X=X3X-X$X3X-X>X-XuX=XfXqX9X9X$X:XfXgX= +X{.3X>X-X>XpX#XjX=X4XwXfXP.5X*X#X]._.#X<X_.Q.!._.A.l.j.a.[ } r.A @ 5 +5 # p H H ` _ o.' ` o.=.q.t.e.Z.n.a.` ", "HXNXeXeXgXuXuXpXsX9XsX9X9X3X3X1XsXwXeX>XwX3XwX>X=XOX$X+XbX(.>XeX=X).: +XyX).|.{.-X=X!. X|.(.].!.pXOXQ.|.(.Y.[.(./.'.U.(.Y.N.b.A.e.M.h.f.' O +@ C ' ) o.=.O.t.r.d.-.e.j.p.p.B.B.a.*.", "IXBXuXsX=X:X0X:X3X=X>XeX>X-X>X>X>X$X$X$X{.-X{.>X.X:X].+X#XOX.X{.+X|.* +X=X/.{.=XT.).sX X].(..X-XP.R.Y..X_.]._.].E.!.W.W.N.T.l.l.V.z.9.x.h.d. +9.O.w.;.w.%.a.p.f.t.l.b.B.V.A.E.A.f.} ", "PXOXZ.B.A.n.b.m.B.Z.n.F.F.B.B.F.N.A.A.B.B.A.B.B.c.V.A.N.M.Z.g.N.b.v.A +.v.a.M.J.B.l.z.w.G.j.a.v.N.A.V.d.a.n.e.g.e.y.u.7.3.a.t.3.2.0. .6.;.+. +{ %.W ` O.~ :.+.0.-.O.w.;.3.1.e.e.o.R ", "rXf.n I L G ~ ~ &.) *.O.o.O.o.%.o.O.;.o.` ;.) o.;.R 1.] } ' ;.=.` ) o +.` O.o.} ' %.U 1.&.R O./ / Y R } T &.T &.} *.R &.o.P R %.~ ~ ' ^ D ` +I H U ) G R T O.T ~ ] ~ / o.) ~ ) C t " }; end-of-xpm return $xpm; } # end cwVim #}}}2 sub icon { #{{{2 my $xpm = <<'end-of-xpm'; /* XPM */ static char *kpackage[] = { /* columns rows colors chars-per-pixel */ "32 32 257 2", " c transparent", ". c #69090B", "X c #640F09", "o c #750D0D", "O c #7B1517", "+ c #721A19", "@ c #9C0A08", "# c #89190D", "$ c #892321", "% c #693046", "& c #982122", "* c #A91E19", "= c #D50C09", "- c #D81215", "; c #C21D1C", ": c #963030", "> c #D01918", ", c #D21C09", "< c #C91F1D", "1 c #B52729", "2 c #A62F2C", "3 c #E41518", "4 c #D31F22", "5 c #B13132", "6 c #C82A1E", "7 c #88405C", "8 c #A73835", "9 c #D22A1C", "0 c #2E63AB", "q c #C53024", "w c #CB2D26", "e c #D22A26", "r c #72507A", "t c #DB292D", "y c #E52825", "u c #5A5A98", "i c #655887", "p c #CF3235", "a c #BC3B3A", "s c #D3352C", "d c #BC3E4B", "f c #AE4358", "g c #EA2E2F", "h c #C53F3F", "j c #E33339", "k c #B84747", "l c #886919", "z c #3A70CD", "x c #3075D0", "c c #E83736", "v c #CA4443", "b c #E13B3A", "n c #3C76C5", "m c #DE4246", "M c #4C79BA", "N c #C6504E", "B c #E84245", "V c #427FCE", "C c #467FC8", "Z c #D14F4F", "A c #F14143", "S c #E3474A", "D c #D74D51", "F c #B76A12", "G c #A27917", "H c #EF494A", "J c #5782C1", "K c #EA4D4F", "L c #A77D08", "P c #DF5351", "I c #E55150", "U c #468AD2", "Y c #787AA4", "T c #5087D1", "R c #C45E73", "E c #DB5858", "W c #4B8CCB", "Q c #5C8AA9", "! c #BA7711", "~ c #75848A", "^ c #DC595E", "/ c #F6504F", "( c #548DD1", ") c #F45656", "_ c #7E8B7F", "` c #E95C59", "' c #5092DB", "] c #D86467", "[ c #D07812", "{ c #F05B5C", "} c #B5880D", "| c #CD7B13", " . c #FC565A", ".. c #8C8D66", "X. c #CB7A26", "o. c #5C91DC", "O. c #BD8900", "+. c #6693BC", "@. c #968E54", "#. c #5B94D5", "$. c #6D93AA", "%. c #E86361", "&. c #5A98CE", "*. c #B58D12", "=. c #BB8D03", "-. c #C7821F", ";. c #CA7F28", ":. c #5497EA", ">. c #E86468", ",. c #FA5D61", "<. c #B98C1F", "1. c #529CEB", "2. c #C77580", "3. c #FE605E", "4. c #BD8F18", "5. c #5E9BDF", "6. c #C0910D", "7. c #679AD3", "8. c #4DA1F6", "9. c #A39653", "0. c #679CDB", "q. c #58A0F0", "w. c #F36D6A", "e. c #FE6867", "r. c #E77274", "t. c #F36E70", "y. c #C29815", "u. c #C19821", "i. c #FB6D6D", "p. c #BF992B", "a. c #FF6C70", "s. c #CF980D", "d. c #CF818A", "f. c #C99920", "g. c #C39E1B", "h. c #FF7171", "j. c #62A8F9", "k. c #C89E1D", "l. c #FD7572", "z. c #C08D9F", "x. c #63ADF6", "c. c #6DADDD", "v. c #C5A22A", "b. c #6CACF1", "n. c #FF787A", "m. c #D3A119", "M. c #6EACF7", "N. c #75AAF0", "B. c #74B0E8", "V. c #C9A927", "C. c #DDA311", "Z. c #D5A327", "A. c #FF7F7D", "S. c #6FB3F0", "D. c #6CB4FE", "F. c #75B6EE", "G. c #75B4F9", "H. c #7BB5E7", "J. c #CEAC39", "K. c #F6898B", "L. c #DDA924", "P. c #CEAF2D", "I. c #7EB7E3", "U. c #CBB338", "Y. c #D4AF38", "T. c #DCAF33", "R. c #EFAF00", "E. c #CAB642", "W. c #EBAF15", "Q. c #7CBFFD", "!. c #DCB52D", "~. c #75C3FF", "^. c #83C0EC", "/. c #E8B225", "(. c #E0B33F", "). c #85C2E7", "_. c #7BC5F5", "`. c #DEB638", "'. c #7EC4FB", "]. c #EBB73D", "[. c #8AC5FE", "{. c #8FC4F7", "}. c #91C2FD", "|. c #83C9FF", " X c #EABB36", ".X c #F8BA18", "XX c #EFBC2F", "oX c #F5BD27", "OX c #F9BB28", "+X c #DCC350", "@X c #EAC03A", "#X c #87D0FF", "$X c #96CAFE", "%X c #E4C453", "&X c #F3C235", "*X c #90CFFF", "=X c #95D1F6", "-X c #FFC12F", ";X c #EBC848", ":X c #F7C250", ">X c #93D5FF", ",X c #F3C943", "<X c #9BD3FF", "1X c #97D7F5", "2X c #FFC733", "3X c #F7C854", "4X c #94DBFF", "5X c #EECD5C", "6X c #FECC36", "7X c #FACA4E", "8X c #F7C95C", "9X c #E9D34F", "0X c #F1D148", "qX c #E8D357", "wX c #FFCD41", "eX c #9EDBFF", "rX c #F7CE58", "tX c #9FDFFD", "yX c #FED244", "uX c #FFD24D", "iX c #FCD35C", "pX c #FBDB49", "aX c #FFD949", "sX c #B1DFFF", "dX c #A2E7FE", "fX c #FED951", "gX c #AAE5FE", "hX c #F0E05A", "jX c #F5DE5A", "kX c #FFD767", "lX c #FADE63", "zX c #EEE565", "xX c #FFE056", "cX c #FFDD6B", "vX c #F8E265", "bX c #FFE05E", "nX c #FFE75B", "mX c #FFE470", "MX c #FFE863", "NX c #FAEB64", "BX c #FFE96C", "VX c #F7EE6D", "CX c #BFF1FE", "ZX c #F6EF74", "AX c #FFEB75", "SX c #FFF069", "DX c #F5F478", "FX c #FFF171", "GX c #FFF178", "HX c #D0F1FF", "JX c #FFF56C", "KX c #FEF573", "LX c #FEF67C", "PX c #FDFB77", "IX c #FEFD80", "UX c gray100", "YX c None", /* pixels */ "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYX{.:.YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXsXHXS.j.:.YXYXYXYXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXz M.gXCXeX#X|.Q.D.1.YXYXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXj.5.M V B.>X4X4X4X>X#XQ.1.x YXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYX8.j.'.#X#X#X^.&.' B.4XdXtX^.T n W S.x.q.YXYXYXYXYXYXYXYX", "YXYX..Q #.j.G.Q.|.*X>X4X=Xc.( B.T V W ).1XeX#X_.Q.D.q.1.YXYXYXYX", "YXYXR.W.m.@.$.7.M.Q.[.F.0.T C J #.I.gXgXtXtXsXeX=X#X[.Q.5.J % YX", "YXYX/.OX.XOXW.v._ V x n &._.1X1X1XI.U F.tXgXeX<X$X}.N.( Y 2.o YX", "YXYXL.-X&XwX6XwX/.p.9.$.S.~.#X>XeXsX=XH.T ' b.G.0.J Y z.K.N . YX", "YXYX4.OXwXwXuXfX@Xf.XX].9.$.D.'.*X*X*X}.S.T 0 u R d.K.A.%.h YX", "YXYXYXOXuXfXnXjX9Xy.5XfXwXXX@.+.j.N.( M r f ^ e ,.l.h.a.>.a YXYX", "YXYXYXXXyXfXbXMXhXu.%XFXbXiXOXp.~ i 7 d K e.t.t K a.h.e.E h YXYX", "YXYXYXf.&XxXNXSXVXg.5XFXFXFXcXuX| 9 / ,.3.3.a.b b e.n.l.%.5 YXYX", "YXYXYXL 4.m.0XSXKXV.%XZXLXGXBXiXX.s B / .3.h.b b l.n.n.>.2 YXYX", "YXYXYXYX,XY.u.k.9XV.(.GXIXLXAXkX;.s K / ,.e.n.) c l.l.{ c ; YXYX", "YXYXYXYXaXNXvXU.4.} T.ZXLXLXAXkX;.s H 3.e.h.n.I g / y 3 > * YXYX", "YXYXYXYX,XNXFXPXIXE.f.`.vXLXGXkX;.s H / 3./ c - 4 4 q P Z O YXYX", "YXYXYXYX XMXSXKXIXzX4.J.u.L.cXkX;.s K / 3 = 9 < c t.A.n.D O YXYX", "YXYXYXYXY.MXSXKXIXZX} qXDXE.4.Z.-.6 3 , e { l.m b A.A.n.v X YXYX", "YXYXYXYXJ.nXBXFXPXzX4.%XIXDX+Xp.| , > b ,.a.l.t H n.A.t.a YXYX", "YXYXYXYX<.XXiXvXLXvX} Y.LXGXmX5XF 6 K ) 3.i.e.4 H n.A.t.8 YXYXYX", "YXYXYXYXYXYXk.7XbXzX4.Y.GXGXcX8X! 6 K I { e.i.> K A.l.%.& YXYXYX", "YXYXYXYXYXYXYXYXZ.7X} (.AXAXcX8X! q K K ) e.{ - K >.v 1 o YXYXYX", "YXYXYXYXYXYXYXYXYXG G J.cXAXcX8X! 6 S K %.t.%.- 1 $ YXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXl (.3XkX5X! 6 S I %.>.v @ YXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYX<.3X3X! q m E ] k + YXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXG ].-.6 N k : YXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX-.6 8 + YXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX# YXYXYXYXYXYXYXYXYXYXYXYXYXYX", "YXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYX" }; end-of-xpm return $xpm; } # end icon #}}}2 sub tos { #{{{2 my $xpm = <<'end-of-xpm'; /* XPM */ static char *tk_________x__[] = { /* columns rows colors chars-per-pixel */ "48 48 220 2", " c #000000", ". c #0C0504", "X c #0C0905", "o c #030609", "O c #0C0C0B", "+ c #160404", "@ c #1D0505", "# c #110C03", "$ c #0F100F", "% c #171102", "& c #161209", "* c #1A150B", "= c #1F180B", "- c #090B13", "; c #171717", ": c #17181A", "> c #1C1C1C", ", c #2F0001", "< c #220808", "1 c #2B0909", "2 c #320000", "3 c #3E0101", "4 c #300F0F", "5 c #3E0F0F", "6 c #231C0D", "7 c #3E0D11", "8 c #261F11", "9 c #18211A", "0 c #2A200C", "q c #32250D", "w c #272010", "e c #2B2211", "r c #22201B", "t c #2A211F", "y c #2E2F1B", "u c #302613", "i c #352A15", "p c #392D17", "a c #3E3219", "s c #1B2029", "d c #242423", "f c #292926", "g c #2B2A2B", "h c #3A3521", "j c #333333", "k c #373837", "l c #373839", "z c #3C3D3C", "x c #470E0E", "c c #441111", "v c #4D1313", "b c #541414", "n c #5B1717", "m c #5E1818", "M c #6A1213", "N c #601818", "B c #6C1B1B", "V c #7F1F1F", "C c #43351B", "Z c #47391D", "A c #4A3C1E", "S c #4A3D20", "D c #7B2A2D", "F c #6B511E", "G c #4F452E", "H c #544322", "J c #5D4B25", "K c #494435", "L c #624E26", "P c #624D28", "I c #645027", "U c #645029", "Y c #6B552C", "T c #6E582C", "R c #745C2D", "E c #645C3B", "W c #775F30", "Q c #76602F", "! c #7B6231", "~ c #7C683D", "^ c #444444", "/ c #4A4B4A", "( c #535454", ") c #5B5B5B", "_ c #635A44", "` c #795655", "' c #5F625F", "] c #6E6957", "[ c #756A50", "{ c #5E6360", "} c #626362", "| c #676B67", " . c #6D6D6C", ".. c #6F726F", "X. c #737373", "o. c #757975", "O. c #7B7A7B", "+. c #AB1E1F", "@. c #892222", "#. c #942525", "$. c #9B2323", "%. c #A12627", "&. c #A42828", "*. c #AD2C2C", "=. c #B82324", "-. c #B52D2D", ";. c #CD2C2C", ":. c #D22A2A", ">. c #DB2D2D", ",. c #CC3333", "<. c #D43434", "1. c #DB3636", "2. c #DE3838", "3. c #E23939", "4. c #E83A3A", "5. c #806531", "6. c #856B36", "7. c #8D6F36", "8. c #8E7238", "9. c #96793B", "0. c #9B7C3E", "q. c #9F7F40", "w. c #927B49", "e. c #886D69", "r. c #D37975", "t. c #7E817E", "y. c #9E803F", "u. c #AC883E", "i. c #A38341", "p. c #A88643", "a. c #AB8943", "s. c #B08D46", "d. c #B38F48", "f. c #B59249", "g. c #BA944B", "h. c #BA9C5A", "j. c #8C8A74", "k. c #B8A373", "l. c #C39C4E", "z. c #CAA24E", "x. c #CBA251", "c. c #D0A753", "v. c #D4A955", "b. c #D9AD56", "n. c #DEB259", "m. c #E3B55B", "M. c #E7BA5C", "N. c #EBBC5E", "B. c #EFBF60", "V. c #F0C05F", "C. c #ECC166", "Z. c #F4C362", "A. c #F9C763", "S. c #FFCC66", "D. c #FFCF68", "F. c #FFD267", "G. c #FFD369", "H. c #FFDB6D", "J. c #F9CF74", "K. c #FFDF70", "L. c #FFE06F", "P. c #FFE371", "I. c #FFE974", "U. c #FFE779", "Y. c #FFED78", "T. c #FFF67C", "R. c #7F8288", "E. c #848484", "W. c #838A87", "Q. c #8A8B8B", "!. c #8D8E90", "~. c #939393", "^. c #959A95", "/. c #9E9D92", "(. c #9B9C9B", "). c #99A099", "_. c #A4A6A4", "`. c #A5AAA5", "'. c #A5ACA8", "]. c gray67", "[. c #ACB4B1", "{. c #B3B4B3", "}. c #B4BDB8", "|. c #BBBBBB", " X c #DA8D89", ".X c #EEABA6", "XX c #BCC3BC", "oX c #DFC488", "OX c #F6D58E", "+X c #C1C3BB", "@X c #ECD7A9", "#X c #E1C4BD", "$X c #FFE9B5", "%X c #C3C3C4", "&X c #C4CAC4", "*X c #C4CEC8", "=X c #CCCDCC", "-X c #CBD2CC", ";X c #D2D2D2", ":X c #D3DAD5", ">X c #DFDCD4", ",X c #D9D9D9", "<X c #DBE3DB", "1X c #E6E5DD", "2X c #F1F1D9", "3X c #DFE7E0", "4X c #DEEAE2", "5X c #E3E6E3", "6X c #E3EBE3", "7X c #E6EFE8", "8X c #EBEBEB", "9X c #E7F0E7", "0X c #E4F1E9", "qX c #EBF3EB", "wX c #E7F8EF", "eX c #FFFFE7", "rX c #EDFAF1", "tX c gray96", "yX c #F2FBF3", "uX c #FFFFFF", /* pixels */ "<X<X<X<X<X<X<X<X<X<X<X<X<XqX{.) j t.&XqX6X<X< +X<X<X<X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X<X<X<X<X<X8X5X; ; ) j %XqX6 +X<X<X<X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X<X<X5X3XQ.uX%XuXuX5Xz j ;X].) / ^ | 3 +X6X<X<X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X<X3X7X^ ,XuX_.j uX^ j ( ~.%XuXuXuX%X - + XX9X<X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X<X7X{ |.' ,X&X5XuX} ^ ) O O.z uX5X;X=XQ.=X + . {.9X1X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X9Xj.O.X. %X^ / > ~.E.g > ;X~.|.' (.|.Q. + g '.0X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X6X<X o ; (.uX|.(.;X=X%XuXuXuXuXuXuXE. Q +.^.O -X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X9XX./ Q.uXuXuXuXuX8X~.uX=X/ 8XuXuX~.(.X. g + O > ;X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X6X j tXuXuXuXuXuXuX5X( j ( ;X8XX.E.(.uXr + ( 5XuX<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X6X). `.uXuXuXuXuXuXuX{. ].uXuXuXuXuXuXuXuXQ.o + | 6X<X<X<X<X<X<X<X<X", "<X<X<X<X<XqX . tXuXuXuXuXuXuX,X{.%X_.k.b.w.J.J.OX$XeXuXR. + _.6X<X<X<X<X<X<X<X<X", "<X<X<X<X<XqXj o ,XuXuXuXuXuXuX|.Q. # d.R z.F.S.V.V.F F w.@X .s + yX<X<X<X<X<X<X<X<X<X", "<X<X<X<X<XqXz ) uXuXuX_.tXuXuXuXC.0.P.S.x.F.S.S.S.G.F.v.0.u.I.o +Xd $ yX<X<X<X<X<X<X<X<X<X", "<X,X<X<X<XqX/ {.uXuXE.Q.uXuXuX[ # J n.l.D.S.S.S.S.S.g.a.n.F.H +. . yX<X<X<X<X<X<X<X<X<X", "<X<X<X<X<XqX) > %XuXuXuXuXuXuXl % H Z.G.S.D.S.S.S.S.S.F.x.Y C.x +. :X4X<X<X<X<X<X<X<X<X", "<X<X<X<X<XqX.. O.X.%X(.|.uX8X!.8 A P.F.D.S.S.S.S.S.S.S.F.N.y.G.G +.n.= ).1X<X:X<X<X<X<X<X<X", "<X<X<X<X<X7XW. O {.|. : * m.x.G.S.S.S.S.S.S.S.S.S.D.D.D.S.D +.H.. ^.6X<X<X<X<X<X<X<X<X", "<X<X<X<X<X7X(. - g = Z.G.S.S.S.S.D.D.H.G.G.D.S.S.S.S.S +.H.A _.6X<X<X<X<X<X<X<X<X", "<X<X<X<X<X6X[. h.I.M.K G L.G.S.S.S.S.S.D.Y J J R B.S.S.S.S.S +.P.Q :X4X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<XXX8 I.g.H.G.Y 7.H.S.S.S.S.S.S.D.G.K.K.G.Z.D.S.S.S.H +.x. * yX<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X6X}.S a.0.F.F.P.= S.F.S.S.S.S.S.D.F.H.K.b.f.v.G.G.D.H.v +.. _ qX<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X6X[.H L F.F.B.H.0. w F.D.S.S.S.S.D.K.c.P S G.F.n. + /.6X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X6X'.0 P K.D.x.v.P.X x.G.S.S.S.S.D.H * g.! i 8.G.G.9. + C # XX6X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X-X 5.G.D.F.F.P.& n.G.S.S.S.S.F.B.v.U c.c.! U.G.F.G.6. + & &X6X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<XqXf 8.H.S.S.F.D. a.G.S.S.S.S.S.S.G.Z.6. D.S.S.F.x. + :X3X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X7XW. A.G.F.G.f. P K.S.S.S.S.S.S.G.Z.w.q.g.G.S.S.D.P. + qX<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X1X4Xo = A.G.K.! . K.S.S.S.S.S.S.D.D.F.G.F.S.S.S.S.H.A + yX<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X6X-X X b.U.i 9.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.G.q +. O yX<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X<XrX( L. W T H.F.S.S.S.S.S.S.S.S.S.S.S.S.S.F.H +. d qX<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X<X9XQ. n. . v.Y ! G.S.S.S.S.S.S.S.S.S.S.F.G.H.P.Z +. z qX<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X<X7X^. v.J 6.Z.w H.S.S.S.S.S.S.S.S.S.S.m.U H 0.u + o.9X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X<X9X'. a.x. ! H.f.H.S.S.S.S.S.S.S.S.S.D.G.K. e + XX1X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X<X6X0X^ 6.Y.% a C.a H.G.S.S.S.F.G.H.D.S.S.S.H.M.I.0 + O yX<X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X<X6X0Xk U U.! p . A 0 J H.F.D.F.B.a W P.P.P.H.l.C w + ' 0X<X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X<X6X6Xt Z P.Z. & f.H.F.H.a # S * * X . + <X6X<X<X<X<X<X<X<X<X<X<X<X", "<X<X<X<X6X1X4 V @ w L.H.f. i F.f.P.x.l.U.S.S.I.T.I ] + qX<X<X<X<X<X<X<X<X<X<X<X<X", "<X<X<X0X#X, <.*. O P.S.H.Q u H H e P.F.F.l.X a p X +X6X<X<X<X<X<X<X<X<X<X<X<X<X", "4X4X4X X3 @ b 4.4.< P.D.F.H.a X 8.H.G.W Y . e y +X<X<X<X<X<X<X<X<X<X<X<X<X<X", ">Xr.:.:.$.1.3. 4.,.+ A.D.S.G.A.w l.K.U.R j.7 +X<X<X<X<X<X<X<X<X<X<X<X<X<X", "%.>.<.<.<.<.1.c < v.F.S.S.G.G.A 6 H d.m.P # 9X< +X<X<X<X<X<X<X<X<X<X<X<X<X<X", "@ B V @.&.2.2.#. f.G.D.S.S.D.K.W * X 0.q _ qX< +X<X<X<X<X<X<X<X<X<X,X<X<X<X", " v #.n @.-.7 E H.D.S.S.S.F.H.i. L Y :X4X< +X<X<X<X<X<X<X<X<X<X<X<X<X<X", " v . < 4.1.<.9 S.G.D.S.S.S.D.H.m.Y d.2X6X<X< +X<X<X<X<X<X<X<X<X<X<X<X<X<X", " B 4.3.,.#.b 3.,.<.D y H.F.S.S.S.S.D.F.K.F.p.0.0.s.= +X6X<X<X< +X<X<X<X<X<X<X<X<X<X<X<X<X<X", "n b 3.<.,.<.2.<.1 #.<.<.1.O h A.K.D.S.S.S.S.S.F.G.P.P.H *X4X<X<X< +X<X<X<X<X<X<X<X<X<X<X<X<X<X", "N m 2.<.,.,.<.2.5 4.3.<.%. ~ b.U.K.P.P.K.P.D.d.u .X7XwX9X< +X<X<X<X<X<X<X<X<X<X<X<X<X<X", " 5 ,.2.,.,.2.b + . o & 8 p 8 =.+.< e.q +X0X<X<X<X<X<X<X<X<X<X<X<X<X", " #.<.<.2.c ;.;.b 1 5 x $.M 2 + + ` rX6X<X<X<X<X<X<X<X<X<X<X" }; end-of-xpm return $xpm; } # end icon #}}}2
        sub greyCubeLogo { #{{{2 my $xpm = <<'end-of-xpm'; /* XPM */ static char *qb3_greyCubeLogo[] = { /* columns rows colors chars-per-pixel */ "128 128 149 2", " c black", ". c #2D2D2D", "X c gray21", "o c #15064C", "O c #1D0867", "+ c #220A7B", "@ c #5D0000", "# c #7D0000", "$ c #7E075E", "% c #7C5301", "& c #484848", "* c gray33", "= c #5B5B5B", "- c #626262", "; c #6C6C6C", ": c #747474", "> c #7B7B7B", ", c #270B8B", "< c #2B0C99", "1 c #2E0DA6", "2 c #310EB1", "3 c #340FBB", "4 c #3710C5", "5 c #3A11CE", "6 c #3C11D7", "7 c #3E12DF", "8 c #4013E7", "9 c #4313EE", "0 c #4514F6", "q c #4715FD", "w c #6744FA", "e c #8A0000", "r c #9F0000", "t c #A90000", "y c #B20000", "u c #BA0000", "i c #8C5E01", "p c #9A6701", "a c #A77001", "s c #B27702", "d c #BD7E02", "f c #C90000", "g c #D30000", "h c #DD0000", "j c #D63F3F", "k c #E40000", "l c #DF064C", "z c #DB0867", "x c #D60A7B", "c c #D76A6A", "v c #DA7474", "b c #D97C7C", "n c #880CA1", "m c #A00DA7", "M c #9B10D2", "N c #9D12DF", "B c #8411E0", "V c #8713EE", "C c #9313E7", "Z c #AE11CE", "A c #A611D7", "S c #B510C5", "D c #8D7CEF", "F c #8774F1", "G c #CC0C99", "H c #D10B8B", "J c #C10EB1", "K c #D5559A", "L c #C78502", "P c #D08B02", "I c #D99102", "U c #E19702", "Y c #E99C02", "T c #F8A602", "R c #FFAB03", "E c #EDA33B", "W c #FCAA2F", "Q c #F9A93F", "! c #DFA475", "~ c #DAA37B", "^ c #EFA75C", "/ c #F2A854", "( c #FEBA45", ") c #EBA763", "_ c #E8A66A", "` c #E3A570", "' c #FBC67B", "] c #848484", "[ c gray54", "{ c #959595", "} c #9A9A9A", "| c #A4A4A4", " . c #A9A9A9", ".. c #B2B2B2", "X. c #BEB9B9", "o. c #9689E9", "O. c #9A8FE6", "+. c #9983F9", "@. c #9E95E3", "#. c #A29ADF", "$. c #A998F7", "%. c #A8A4D6", "&. c #B6A9F4", "*. c #C19E8D", "=. c #D29191", "-. c #CFA184", ";. c #C9A089", ":. c #D5A280", ">. c #C6A8A8", ",. c #CAA2A2", "<. c #C1BCBC", "1. c #C4BFC0", "2. c #C4C0BF", "3. c #F4D2AD", "4. c #C5C1C1", "5. c #C9C4C4", "6. c #CBC7C8", "7. c #CBC8C7", "8. c #CDC9C9", "9. c #D1CDCD", "0. c #D3CFD0", "q. c #D3D0CF", "w. c #D5D2D2", "e. c #D8D5D5", "r. c #DAD7D8", "t. c #DAD8D7", "y. c #DCDCDC", "u. c #CAC4EE", "i. c #D0CBEC", "p. c #EFD7C3", "a. c #EDD8CA", "s. c #E0DEDE", "d. c #E1DFE0", "f. c #E1E0DF", "g. c #E4E2E2", "h. c #E8E6E6", "j. c #E9E7E8", "k. c #E9E8E7", "l. c #ECEBEB", "z. c #F0EEEE", "x. c #F0EFF0", "c. c #F0F0EF", "v. c #F4F3F3", "b. c #F7F7F8", "n. c #F7F8F7", "m. c #F8F6F6", "M. c #F8F7F8", "N. c #F8F8F7", "B. c #FBFAFA", /* pixels */ "X.X.X.X.X.X.X.X.X.X.X.X.X.X.X...<.>.<.X.X.X.X.X.X.X...>.X.X.X.X.X...< +.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X. +<.X.X.X.X.<.>.X.X.X.X.X.X...X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X +.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.>.X.", "X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.<...X.X.X.X.X.X.X.X.<.<.X.X.X.X.X.X.X +.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X. +X.X.X.X.X...<.X.X.X.X.X.X.2.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X +.X.X.X.X.X.X.X.X.X.X.X.X.<.X.X.X.X.X.X.X.X.X.2.X.", "X.X.X.X.X.X.X.X.X.X.X.X.<.X.<.<.X.<.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.< +.2.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X. +X.X.X.X.X.X.X.X.X.X.X...2.X.2.X.X.X.X.X.X.X.X.<.X.<.X.X.X.X.X.X.X.X.X +.X.X.<.X.X.2.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.", "X.X.X.X.X.X.X.X.X.X.<.X.X.X.X.X.X.X.X.X.<.X.X.X.X.<.<.X.<.X.X.X.<.X.X +...X.X.<.X.X.X.X.X.<.X.X.<.X.X.X.<.X.X.X.X.<.X.X.X.X.X.X.X.X.X.X.X.X. +2.X.X.<.X.<.X.<.X.X.<.<.X.<...X.<.X.X.<.X.X.X.X.X.X.X.X.<.<.X.<.X.X.X +.X.<.X.X.<.X.X.X.X.X.2.X.X.<.X.<.<.X.<.X.<.X.<.X.", "<.X.X.<.X.<.X.<.<.>.<.X.<.X.<.<.X.<.X.<.X.X.X.X.<.X.<.X.X.<.X.X.X.<.X +.X.<.X.X.<.<.X.X.X.<.X...2.X.X.<.X.<.X.<.X.X.<.X.<.X.<.X.<.2.X.<.X.X. +<.X.X.<.X.<.X.X.X.X.<.X.X.<.<.X.<.<.X.X.<.<.X.<.X.X.X.X.X.X.<.X.X.X.< +.X.X.<.X.X.X.2.%.2.X.X.X.X.X.<.X.<.X.<.X.X.<.X.<.", "X.X.<.X.<.X.<.X.<...<.<.X.<.<.<.<.X.<.X.X.<.<.<.X.X.<.X.<.X.X.<.<.X.< +.<.<.<.<.X.X.<.<.<.<.<.<.<.<.<.X.<.X.<.<.<.<.X.<.X.X.X.<.X.X.2.X.<.<. +X.<.X.X.<.X.<.<.<.<.<.<.<.<.X.2.X.<.X.<.<.X.<.<.<.<.<.<.<.<.X.<.<.<.X +.<.<.<.X.<.<.<.<.<.2.<.X.X.2.X.<.<.<.<.<.2.X.X.<.", "<.<.X.<.X.<.<.<.<.<.<.<.<.<.<.<.<.<.<.X.<.<.<.X.<.<.<.<.<.X.<.<.<.<.< +.<.X.<.X.<.<.<.<.<.<.<.<.X.<.<.X.<.<.<.<.X.<.<.<.X.<.1.<.<.<.X.2.X.<. +<.<.2.<.<.<.X.<.<.<.X.<.<.<.<.X.<.<.<.<.<.X.<.<.X.<.<.<.<.<.<.<.<.2.< +.X.<.<.<.<.<.<.<.<.<.<.<.X.X.X.2.X.<.<.X.<.<.<.<.", "X.<.<.<.<.<.<.X.<.<.<.<.<.<.<.<.X.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.X.<.< +.X.<.<.2.X.<.<.<.X.X.<.<.<.<.<.<.<.<.<.<.<.X.<.<.1.X.1.<.<.X.2.<.<.2. +X.<.X.<.<.<.<.<.<.<.<.X.2.X.<.X.2.<.<.<.<.<.<.<.<.<.<.<.X.<.<.<.X.<.< +.<.<.<.<.<.<.<.<.<.<.<.<.2.2.2.2.<.<.<.<.<.<.<.<.", "<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.X.2.X +.X.2.X.<.<.<.<.<.<.<.<.<.4.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<.<. +<.<.<.<.<.<.<.<.<.<.<.<.<.<.2.<.<.2.<.<.<.<.<.<.<.<.2.<.2.2.X.<.<.<.< +.2.<.<.<.<.<.<.<.<.<.4.<.<.<.1.<.<.2.2.2.X.X.2.2.", "<.<.<.<.<.5.<.<.<.<.<.<.<.<.<.<.<.<.2.<.2.<.<.<.<.<.<.<.<.<.<.<.2.2.2 +.2.2.2.2.X.2.<.<.<.<.<.2.4.<.<.<.<.<.<.<.2.<.2.1.1.<.<.4.<.<.5.<.<.<. +2.<.<.<.<.2.<.<.2.5.<.2.X.2.X.<.2.2.X.<.4.<.<.2.<.<.<.2.<.2.2.1.<.<.1 +.<.2.2.<.<.<.4.<.4.<.<.<.1.<.<.1.2.<.X.2.2.2.<.<.", "<.<.<.<.<.<.5.<.<.<.<.5.<.2.<.<.2.2.<.<.<.2.<.<.<.<.<.<.<.<.<.5.X.2.2 +.2.2.2.<.<.<.2.<.2.2.<...4.2.<.2.<.<.4.<.<.<.<.1.1.<.<.<.<.<.<.<.1.2. +<.<.<.<.5.<.<.<.<.<.<.2.2.2.2.2.X.2.2.<.4.4.<.<.4.2.<.2.<.<.2.<.1.2.< +.1.<.2.<.<.2.<.4.<.<.4.<.<.1.1.1.<.2.<.2.<.<.<.2.", "<.<.<.<.<.<.<.<.5.<.<.<.<.<.5.2.2.<.2.2.2.<.<.5.<.<.<.5.5.<.<.<.2.2.2 +.2.X.2.2.2.2.2.2.<.2.2.2.2.2.<.2.2.<.2.4.2.2.<.1.1.4.<.4.4.<.5.<.<.2. +2.5.<.<.<.<.<.5.5.2.<.<.2.2.2.2.2.2.2.<.2.<.<.4.<.2.<.2.2.<.2.2.1.<.2 +.2.2.2.1.1.4.<.<.<.4.<.1.<.4.<.2.2.2.2.X.2.<.<.2.", "5.<.<.<.<.5.<.1.<.<.5.<.<.<.1.<.2.<.2.2.5.<.<.<.5.<.<.<.<.<.5.<.2.4.% +.4.2.2.<.4.2.2.2.<.2.2.2.2.<.2.2.2.2.2.<.2.2.<.<.4.<.4.4.<.<.2.1.2.<. +1.1.2.<.<.2.2.<.<.<.5.2.2.2.4.%.2.2.4.4.<.4.2.2.2.2.4.2.1.1.2.1.2.2.2 +.1.2.1.2.4.<.<.4.2.2.2.2.1.5.2.2.2.2.2.2.2.5.<.5.", "5.<.5.1.5.<.<.5.<.5.1.<.<.5.1.<.2.2.1.1.<.<.5.<.<.<.5.<.5.<.5.<.2.2.4 +.4.4.4.4.<.2.2.4.2.2.2.2.2.2.2.4.2.2.2.4.2.2.4.4.4.<.4.4.y.y.0.2.2.2. +2.5.<.5.5.<.<.<.5.<.<.2.2.4.2.4.2.4.2.2.4.<.4.2.4.4.2.1.1.1.4.4.1.4.2 +.1.1.1.1.4.4.4.1.2.2.1.2.1.1.2.2.2.<.5.<.2.2.5.<.", "<.<.5.<.<.5.<.<.5.<.<.<.5.<.5.<.5.1.1.1.<.5.<.<.5.<.<.5.<.5.<.5.4.2.4 +.2.2.2.<.4.4.4.4.2.4.4.4.4.2.2.2.2.4.4.2.<.4.4.9.y.y.y.y.y.d.y.y.y.y. +y.2.2.<.5.2.5.2.2.2.2.2.2.4.4.4.4.2.4.4.4.4.4.4.2.2.4.1.1.1.4.4.4.4.2 +.1.4.4.4.4.4.2.4.1.2.1.1.1.1.2.2.5.<.<.5.2.5.<.5.", "5.<.<.5.5.<.5.<.<.5.5.5.<.5.<.5.2.1.2.5.<.5.5.5.<.5.5.<.5.<.5.<.4.4.2 +.4.4.4.4.4.4.4.4.2.4.2.4.4.4.2.4.4.4.4.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y. +y.y.y.y.y.9.5.5.2.5.2.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.2 +.1.4.4.4.4.4.4.2.1.5.2.5.1.5.1.2.5.2.5.<.5.<.5.<.", "4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4.1.5.1.5.4.4.4.4.4.4.4.4.4.5.4.4.4.4.4 +.4.4.4.4.4.4.4.4.4.8.4.4.4.5.w.y.y.y.y.y.y.y.y.y.f.y.y.y.y.y.y.y.y.y. +y.y.y.y.y.y.y.f.y.y.4.4.5.5.4.4.4.4.4.2.4.4.4.4.4.4.4.4.4.4.4.4.4.4.4 +.4.5.4.4.5.4.4.4.5.5.2.2.2.2.5.2.5.2.1.5.2.1.5.1.", "4.4.4.4.4.4.4.4.4.5.4.4.4.5.4.4.5.1.5.2.4.5.4.4.4.4.5.4.4.1.5.4.4.4.5 +.4.4.4.5.4.4.4.4.4.8.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.d.y.y.y.y. +y.y.y.y.y.y.y.y.y.y.y.y.y.y.w.4.4.4.4.5.4.5.4.4.4.4.5.4.4.4.4.5.4.5.4 +.4.4.4.4.4.4.5.4.5.2.5.5.5.5.2.5.2.5.5.1.1.5.1.5.", "5.4.4.4.4.4.4.5.4.5.4.5.4.5.4.4.5.1.1.5.4.4.4.4.5.5.4.4.5.2.4.5.4.5.4 +.5.5.5.4.4.w.y.y.y.y.y.y.y.y.y.g.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y. +d.d.y.y.y.y.y.y.f.y.y.y.y.y.y.y.y.y.y.5.5.8.8.5.4.5.4.5.4.4.5.4.5.4.5 +.5.4.4.5.5.4.4.5.5.2.1.5.2.5.2.4.5.5.5.2.1.5.5.5.", "5.5.5.4.5.5.4.5.5.4.4.5.4.4.5.4.5.5.5.1.5.4.5.5.5.4.4.5.5.4.5.4.5.4.5 +.w.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.f.y.y.y.y.y.y.y.y.y. +y.y.y.y.y.y.f.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.w.4.4.5.5.5.5.5.5.4.4.5 +.5.5.5.5.4.5.5.4.1.5.5.5.5.5.5.5.5.1.5.5.5.1.5.5.", "4.5.5.4.4.5.5.4.5.4.4.5.5.4.5.4.5.2.5.5.2.5.5.5.4.5.5.5.5.5.4.w.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q d.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.4.4.5.5.5.5.5 +.4.5.4.5.5.4.5.4.5.5.5.5.5.2.2.7.5.5.5.5.5.5.1.5.", "5.5.5.5.5.5.5.5.4.8.5.5.4.4.8.4.5.5.5.5.5.5.5.5.5.5.8.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.f.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.g.y.y.y.f.y.y.y.g.y.y.y.y.y.y.y.y.y.y.y.w.5.5 +.7.5.5.5.5.5.5.7.5.5.5.5.5.5.5.5.5.1.5.5.6.5.5.6.", "5.5.5.5.5.5.5.5.4.8.4.8.4.8.5.4.5.5.5.5.5.5.w.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.5.5.5.5.7.8.5.6.5.5.5.5.5.5.5.5.5.7.5.5.5.5.", "5.5.5.5.5.5.5.5.5.4.8.4.8.5.5.8.5.9.d.y.y.y.y.y.y.y.y.y.y.y.y.y.y.i.k +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.w.8.5.5.5.7.6.5.6.7.6.6.5.6.5.6.5.5.", "8.5.5.5.5.5.5.8.8.4.8.4.8.w.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q f.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.f.y.y.y.y.y.y.y.8.5.8.5.5.5.5.5.7.5.6.5.5.", "5.5.5.8.8.5.5.5.8.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.g.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.y.y.g.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.g +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.t.6.6.7.7.6.5.6.6.", "8.5.8.5.5.5.8.5.{ } ..y.y.y.y.y.y.g.y.y.y.y.y.y.y.y.d.y.y.y.y.y.y.y.y +.y.y.y.y.y.k.i.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.8.X...6.6.7.7.7.7.6.7.", "8.5.5.8.8.8.5.8. .{ { { | 8.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.d.y.y.y +.i.y.y.y.y.y.y.y.y.y.y.y.g.y.y.y.y.g.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.w.5.........6.6.6.6.6.7.6.6.", "7.7.7.7.8.5.8.8...{ { { { { } ..i.y.y.y.y.y.y.y.y.y.g.y.y.y.y.y.y.y.y +.k.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.g.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.g.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.t.8.X...........4.6.8.7.7.6.7.8.7.", "7.7.7.7.5.8.5.8.8.{ { { { { } { } .8.y.y.y.y.y.y.y.y.y.d.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.y.y.g.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.w.4.................q.7.8.8.8.8.8.8.6.", "8.8.8.8.8.8.8.8.y.{ { { { { { { { { { } X.w.y.y.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q f.y.y.y.y.y.y.y.y.y.y.y.y.y.y.i.g.y.y.g.y.y.y.y.g.y +.y.y.t.8.%.....................y.8.8.8.8.8.8.8.8.", "8.8.8.8.8.8.8.8.8.{ { { { { { { { { { { { } .9.y.y.y.y.y.y.y.y.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.y.y.y.y.g.y.y.y.y.g.y.y.y.y.y.y.y.y.y.y +.q.5...........................9.8.8.8.8.8.8.8.8.", "8.8.8.8.8.8.8.8.8.{ { { { { { { { { { { { { { { } 4.t.y.y.y.y.y.y.y.y +.d.y.f.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.d.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.y.y.s.f.y.y.y.y.y.y.y.y.y.y.y.y.y.y.8.. +...............................9.8.9.8.8.8.8.8.8.", "8.8.8.8.8.9.8.8.8.| { { { { { { { { { { { { { { { { { ..8.d.y.y.y.y.y +.y.y.y.y.y.y.f.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.f.y.y.y.y.f.y.y.y.y.y.y.y.y.y.y.y.w.4...... +...............................9.8.8.9.8.9.8.8.9.", "8.8.8.8.8.8.8.9.8...} { { { { { { { { { { { { { { { { { { } <.t.y.y.y +.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.q q q q q q q q q q q q +q q q q q q q y.y.y.y.y.y.f.y.f.f.y.y.y.y.y.y.d.y.y.8............ +.............................1.8.9.8.9.8.8.8.8.9.", "9.9.8.9.9.8.9.8.8.8.} { { { { { { { { { { { { { { { { { { ;.^ R R R R + R R R R R R 3.y.y.y.y.g.y.y.d.y.y.y.y.d.y.y.q q q q q q q q q q q q +q q q q q q q y.f.i.$.q q q q q q q q q q +.u.q.X................ +.............................w.9.8.9.8.9.9.9.8.9.", "9.8.8.9.9.9.8.9.8.y.{ { { { { { { { { { { { { { { { { ~ R R R R R R R + R R R R R R R R ( t.f.y.y.' R R R R R R R R R R R R R R R R R q q q +q q q q q q q &.q q q q q q q q q q q q q q q V K k k k k u h k k + ~ ,................. .......y.9.9.9.9.9.9.8.9.9.", "9.9.9.9.9.9.9.9.q.8.{ { { { { { { { { { { { { { { ;.R R R R R R R R R + R R R R R R R R R R ' y.y.R R R R R R R R R R R R R R R R R R q q q +q q q q q q q < q q q q q q q q q q q q q q q q J k k k k k k g h k k + k k b ......................9.9.9.9.9.9.9.9.9.9.", "9.9.9.9.9.9.9.9.q.8.{ { { { { { { { { { { { { { ` R R R R R R R R R R + R R R R R R R R R R R R a.R R R R R R R R R R R R R R R R R R q q q +q q q q q q q q q q q q q q q q q q q q q q q x k k k k k k k k k k k + k k k v ....................0.9.9.9.9.9.9.9.9.9.", "9.9.9.9.9.9.8.9.q.q.| { { { { { { { { { { { { ) R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q m k k k k k k k k k k k k + k k k h =...................0.0.9.9.9.9.9.9.9.9.", "9.9.q.q.9.q.9.q.q.q...{ { { { { { { { { { { _ R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q V k k k k k k k k k k k k k + k k k k j ................4.q.9.9.9.0.q.q.q.q.q.", "q.q.q.q.9.9.9.q.q.q.5.{ { { { { { { { { { ~ R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q J k k k k k k k h @ y k k k + k k k k h { ..............w.0.q.0.0.0.0.0.0.q.q.", "0.0.0.0.q.0.q.q.q.q.y.{ { { { { { { { { { R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q z k k k k k k k e k k k + k k k k k ; ..............y.q.q.0.0.0.0.w.0.q.0.", "q.0.0.0.0.0.q.q.q.q.q.{ { { { { { { { { ^ R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q n r f k k k k O B k k k + k k k k f ..............w.q.q.0.0.0.0.0.0.0.0.", "w.0.w.0.w.q.q.w.w.w.w.{ { { { { { { { *.R R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q O 6 x k k k + k k k k e ..............q.q.e.w.q.0.q.w.0.w.0.", "0.w.w.w.w.q.w.q.w.w.w. .{ { { { { { { / R R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q 8 4 , f k k k k k + k k k u - ............X.w.q.q.w.q.e.w.w.w.w.w.", "w.w.w.w.w.q.w.w.w.q.w...{ { { { { { { R R R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q H k k k k k + k k e } ............2.e.0.w.e.q.w.w.0.w.e.q.", "w.w.w.w.w.w.w.w.w.w.w.8.{ { { { { { ! R R R R R R R R R R R R R R R R + R R R R R s % d R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q 5 O < q q q q q q q q q q q q q q q H k k k k k + k k t > ..............w.0.e.q.e.w.w.w.e.w.w.e.", "w.w.w.w.w.w.w.e.e.w.w.y.{ { { { { { R R R R R R R R R R R R R R R R R + R R R T T R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q O 9 q q q q q q q q q q q q q z k k k k k + k k k k ,...............r.e.w.w.e.w.w.w.w.w.w.w.", "w.w.e.w.w.e.e.w.w.w.w.w.{ { { { { { R R R R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q : .{ q q q q q q q q q q q q q k k k k k k + k k k k k >.............e.e.e.w.w.w.e.w.e.e.e.e.", "w.e.w.w.w.e.w.e.e.w.w.w.{ { { { { *.R R R R R R R R R R R R R R R R R + R R a : ] ; a R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q 1 | ......@.q q q q q q q q q q q q C $ @ h k k + k k k k k c ............w.e.e.w.e.w.e.e.w.e.w.e.", "e.w.e.e.e.w.e.w.e.w.e.e. .{ { { { ^ R R R R R R R R R R R R R R R R R + R R . { { { { { R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q ............q q q q q q q q q q q q q # k k + k k k k k g ...........e.w.e.e.e.e.w.e.e.w.e.e.", "w.e.e.e.e.w.e.e.e.e.e.w.X.{ { { { R R R R R R R R R R R R R R R R R R + R R { { { { { { ( R R R R R R R R R R R R R R R R R R R q +q q q q q q q 9 { ............w q q q q q q q q q q q q 8 8 9 k k + k k k k k k : ........4.e.e.e.e.e.e.e.e.e.e.w.e.", "e.e.e.e.e.e.e.e.e.e.e.e.5.{ { { { R R R R R R R R R R R R R R R R R R + R I > { { { { { { ! R R R R R R R R R R R R R R R R R R R q +q q q q q q q 2 ..............D q q q N G l k k k k k V q q q k k + k k k k k k & ........w.e.e.e.e.e.e.e.e.e.e.e.e.", "e.e.e.e.e.e.e.e.e.e.e.e.t.{ { { { R R R R R R R R R R R R R R R R R R + R s } { { { { { { ;.R R R R R R R R R R R R R R R R R R R q +q q q q q q q O & ..............#.q q q x k k k k k k k Z q q A k k + k k k k k g ........y.t.e.e.t.t.t.r.e.e.e.r.e.", "e.e.e.e.e.e.e.e.t.e.r.e.t.{ { { { R R R R R R R R R R R R R R R R R R + R % { { { { { { { { R R R R R R R R R R R R R R R R R R R q +q q q q q q q [ ................q q q S k k k k k k k k M N k k k + k k k k k y ........t.t.e.r.t.e.e.e.r.t.r.e.r.", "r.r.e.r.e.e.t.e.e.e.t.e.e.{ { { { R R R R R R R R R R R R R R R R R R + R = { { { { { { { { R R R R R R R R R R R R R R R R R R R q +q q q q q q q .................q q q q k k k k k k k k k k k k k + k k k k k @ * ........e.e.e.e.e.t.t.r.r.t.r.r.r.", "e.r.e.y.e.e.s.e.e.e.e.s.e.| { { { R R R R R R R R R R R R R R R R R R + R : { { { { { { { { R R R R R R R R R R R R R R R R R R R q +q q q q q q q ..................q q q q m k k k k k k k k k k k k + k k k k y > ......X.e.e.s.y.t.t.t.t.r.t.y.r.r.", "t.e.r.y.e.s.e.e.e.e.e.e.e.X.{ { { R R R R R R R R R R R R R R R R R R + R [ { { { { { { { { R R R R R R R R R R R R R R R R R R R q +q q q q q q q ..................q q q q q u k k k k k k k k k k k + k k k g .......2.y.s.e.e.t.y.r.r.r.e.e.r.y.", "t.y.t.r.e.e.s.s.r.e.s.y.e.5.{ { { R R R R R R R R R R R R R R R R R R + R { { { { { { { { { R R R R R R R R R R R R R R R R R R R q +q q q q q q q ..................q q q q q 6 r k k k k k k k k k k + k k u > ........9.e.s.e.s.e.t.y.t.y.y.y.y.e.", "y.r.y.e.r.y.e.e.y.s.s.e.e.y.{ { { R R R R R R R R R R R R R R R R R R + R { { { { { { { { { R R R R R R R R R R R R R R R R R R R q +q q q q q q q ................%.q q q q q q 1 t k k k k k k k k + u @ & ..........y.y.s.e.s.e.e.s.e.s.t.s.e.s.", "t.y.r.y.e.y.s.e.s.e.y.t.s.y.{ { { R R R R R R R R R R R R R R R R R R + R p { { { { { { { { ;.R R R R R R R R R R R R R R R R R R R q +q q q q q q q + ................O.q q q q q q q 4 + ............y.t.t.e.e.s.t.t.s.e.y.y.s.e.", "y.y.t.y.y.s.e.s.e.e.s.e.e.s.{ { { R R R R R R R R R R R R R R R R R R + R P { { { { { { { { ! R R R R R R R R R R R R R R R R R R R q +q q q q q q q 3 ................F q q q q q q q q q 3 + 1 ............y.y.e.s.s.s.y.y.t.s.e.s.e.s.", "y.t.y.y.y.y.s.e.s.s.e.s.y.s.| { { R R R R R R R R R R R R R R R R R R + R R { { { { { { { { Q R R R R R R R R R R R R R R R R R R R q +q q q q q q q 9 | ..............q q q q q q q q q q q q q q q q q q + q q ..........X.e.s.s.s.e.e.s.s.s.e.s.s.e.s.", "s.s.s.s.s.e.s.y.t.s.s.s.y.y.X.{ { R R R R R R R R R R R R R R R R R R + R R > { { { { { { { R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q ] ..............q q q q q q q q q q q q q q q q q q + q 6 ..........5.y.y.y.s.y.s.s.s.s.e.s.e.y.s.", "e.e.s.e.s.s.s.y.y.y.y.y.y.y.8.{ { / R R R R R R R R R R R R R R R R R + R R p - { { { { { { ~ R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q 1 & ............@.q q q q q q q q q q q q q q q q q q + q , ..........e.y.y.s.y.s.y.e.s.s.s.s.s.s.s.", "s.s.s.s.s.s.s.s.y.y.y.y.f.y.y.{ { -.R R R R R R R R R R R R R R R R R + R R R . { { { { { { R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q ............q q q q q q q q q q q q q q q q q q q + q ; ..........f.y.y.y.s.y.y.s.s.s.e.s.e.s.s.", "s.s.s.s.y.e.s.s.s.s.y.y.y.f.y.{ { { R R R R R R R R R R R R R R R R R + R R R Y { { { { { W R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q 0 { ........w q q q q q q q q q q q q q q q q q q q + q } ..........s.s.y.s.s.s.s.s.s.s.s.s.s.s.s.", "s.s.e.y.s.s.d.s.s.y.s.s.y.d.y.} { { R R R R R R R R R R R R R R R R R + R R R R R :.*.) R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q o.%.O.q q q q q q q q q q q q q q q q q q q q q + 2 ............s.f.y.y.f.s.s.s.s.s.s.s.s.s.s.", "s.s.s.s.s.s.s.s.s.s.s.s.d.y.d. .{ { ! R R R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q + ..........X.s.f.d.g.y.s.s.s.s.f.s.s.s.s.s.", "s.s.s.s.s.s.s.s.s.s.s.s.f.f.f.X.{ { { R R R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q 7 + [ ..........5.d.d.d.y.s.f.s.s.f.s.f.s.s.s.s.", "s.s.s.s.s.s.f.s.s.s.s.s.f.g.y.8.{ { { _ R R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q O + ............w.d.d.d.g.s.g.s.f.s.f.f.f.s.s.s.", "d.s.f.f.g.g.s.f.d.d.d.d.f.f.d.y.{ { { { R R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q 6 + - ............g.s.g.s.s.d.f.f.f.f.f.f.f.d.s.s.", "s.s.h.s.f.f.s.g.g.f.d.d.g.f.d.d.{ { { { ! R R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q + .............s.s.g.s.f.d.h.s.h.f.f.d.f.h.d.h.", "h.f.g.s.g.f.g.s.g.f.g.f.d.d.d.g.} { { { { E R R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q < + ; ..............g.s.g.g.h.s.d.d.s.f.h.d.d.d.f.h.", "s.h.f.s.f.g.h.s.f.g.g.f.g.d.g.g. .{ { { { { T R R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q 4 + ..............X.s.h.s.g.d.h.h.f.h.s.s.h.f.h.f.d.", "g.g.g.h.g.s.s.h.g.g.g.g.g.g.g.g.X.{ { { { { : T R R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q q q q q q q q q q q q q q q q q q q q q q q q q 5 { + ..............5.h.g.g.h.h.d.f.d.f.d.h.d.h.d.h.d.", "g.g.g.s.g.g.h.s.g.g.f.g.f.g.g.g.8.{ { { { { { * I R R R R R R R R R R + R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R q +q q q q q q + q q q q q q q q q q q q q q q q q q q q q q 3 > . +...............e.h.s.g.s.f.d.h.h.h.h.d.h.h.d.d.h.", "g.g.h.g.g.h.s.h.g.h.g.g.g.g.g.g.y.{ { { { { { { . a R R R R R R R R R + R R R R R R R R R R R a R R R R R R R R R R R R R R R R R R R q +q q q q q q 7 q q q q q q q q q q q q q q q q q q q , : ... +...............y.h.g.h.g.h.h.d.h.h.f.h.f.f.h.h.f.", "g.g.s.g.g.h.s.h.g.g.h.g.g.g.g.g.h.{ { { { { { { { . L R R R R R R R + R R R R R R R R R d R R R R R R R R R R R R R R R R R R R q +q q q q q 7 } , 0 q q q q q q q q q q q q q q q 1 ] ..... +...............g.g.g.h.g.d.h.h.d.h.h.f.h.j.f.h.h.", "g.g.h.g.g.g.h.g.g.h.g.h.g.g.j.g.g.} { { { { { { { { = i U R R R R + R R R R R R I % R R R R R R R R R R R R R R R R R R R + ....- 2 q q q q q q q q q q 6 + } ....... +...............h.g.g.g.h.g.h.h.g.k.g.g.h.g.g.h.g.", "h.g.g.h.h.g.g.h.g.g.g.g.h.g.g.h.g. .{ { { { { { { { { > + R R R R R R R R R R R R R R R R R R R + - ......} X { ........... +...............h.h.h.g.h.g.h.h.g.h.k.h.g.h.h.g.h.", "h.g.h.g.g.j.h.h.j.j.g.h.g.h.h.h.h.X.{ { { { { { { { { { { ; + ; R R R R R R R R R R R R R R R R R R R .. +............................[ ; | ............... +.............5.k.j.g.h.h.g.h.h.h.h.h.h.h.h.g.h.h.", "h.h.h.j.h.h.g.h.j.g.j.h.h.j.g.h.h.9.{ { { { { { { { { { { { } ] * + = [ { { R R R R R R R R R R R R R R R R R R R .. +..................................................................... +.............w.h.h.h.h.j.h.h.h.h.h.g.h.h.h.h.h.h.", "h.h.h.h.h.h.h.h.h.h.h.h.j.h.h.h.k.g.8.{ { { { { { { { { { { { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +..................................................................... +...........8.k.h.j.h.j.k.j.k.k.h.j.k.k.k.h.h.h.k.", "h.h.h.h.h.h.j.j.h.k.h.h.j.h.j.h.k.j.j.h.} { { { { { { { { { { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +..................................................................... +.........f.j.k.k.j.h.k.k.j.j.k.j.k.j.j.k.h.h.k.k.", "h.j.h.h.h.j.h.k.j.h.j.j.k.k.h.k.j.j.j.j.j. .{ { { { { { { { { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +..................................................................... +.....X.j.j.j.j.k.j.j.j.k.j.j.j.j.k.j.k.k.j.k.k.k.", "j.j.k.l.k.j.k.k.k.k.k.j.k.j.k.j.j.j.j.j.l.j.4.{ { { { { { { { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +..................................................................... +...5.j.j.j.j.l.k.j.j.k.k.j.j.l.j.j.j.j.k.l.k.k.l.", "k.k.k.j.k.j.k.j.k.k.j.l.j.j.k.k.j.k.k.k.k.j.k.w.} { { { { { { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +..................................................................... +.w.j.l.j.k.l.j.j.j.l.j.j.j.l.k.l.j.l.j.l.j.j.l.j.", "l.j.l.j.k.l.k.l.k.l.l.k.k.l.k.l.j.j.l.l.k.l.k.l.l.} { { { { { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +....................................................................h +.j.l.k.l.k.j.l.k.l.k.k.l.l.k.l.k.l.j.l.j.j.l.l.l.", "l.k.j.l.l.l.l.k.l.k.l.j.l.j.l.l.l.l.k.l.j.l.j.j.l.k...{ { { { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +.................. ......................... ...................X.j.j +.k.l.k.l.l.l.j.j.l.k.j.l.k.l.l.l.l.l.l.l.l.j.j.l.", "l.l.l.l.k.l.l.k.l.l.l.l.k.l.l.j.l.j.l.l.l.l.l.l.l.l.l.5.{ { { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +..............................................................8.l.l.l +.l.l.l.l.l.l.l.l.l.l.l.l.l.l.k.l.l.j.j.l.l.l.l.l.", "k.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.j.l.l.l.l.l.l.l.y.} { { { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +............................................................y.l.l.l.l +.l.l.l.l.l.l.l.l.l.l.l.k.l.l.l.l.l.l.l.l.l.l.l.l.", "l.l.l.l.l.l.l.l.k.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l. .{ { { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +..........................................................l.l.l.l.l.l +.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.c.l.l.l.l.l.l.l.l.", "l.l.l.l.l.l.l.l.l.l.l.l.z.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.z.X.{ { { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +......................................................4.l.l.l.l.z.l.z +.l.l.z.l.z.l.l.l.l.l.l.z.l.l.l.l.l.l.c.l.c.l.l.l.", "l.z.l.l.l.x.l.z.l.l.x.l.l.l.l.l.l.z.l.z.l.l.z.l.z.l.l.l.z.l.l.l.w.{ { + { { { { { { { { { { { { R R R R R R R R R R R R R R R R R R R .. +....................................................q.l.z.l.z.l.l.l.z +.z.l.l.l.z.l.z.l.z.l.z.l.l.c.c.l.l.c.l.l.l.l.l.l.", "l.z.l.l.z.l.z.l.l.l.z.z.l.l.z.l.z.z.l.z.z.l.l.l.x.l.c.l.x.c.l.x.l.l.} + { { { { { { { { { { { { { { .. +................................................X.g.l.l.z.z.l.l.l.l.x +.l.z.l.c.l.x.x.l.l.l.l.x.l.l.x.c.x.l.l.l.x.l.x.l.", "l.z.z.l.z.z.l.z.l.z.z.l.l.x.l.z.z.l.z.l.l.l.z.z.l.x.l.l.l.l.l.x.c.l.c +. .{ { { { { { { { { { { { { .. +..............................................X.l.l.l.z.z.z.l.x.z.z.z +.c.l.c.l.c.l.z.l.c.x.l.x.x.l.x.l.c.l.x.l.l.c.x.c.", "z.z.z.l.z.l.z.z.z.z.c.l.v.z.z.z.z.l.l.c.z.x.l.z.c.l.c.l.c.c.l.c.c.c.x +.l.4.{ { { { { { { { { { { { .. +............................................5.l.l.l.v.z.l.x.z.l.z.z.l +.l.c.x.l.z.c.x.l.c.l.c.c.c.x.x.l.c.l.c.x.z.z.x.x.", "z.z.z.x.z.z.z.z.l.v.l.l.l.z.z.l.z.z.z.c.z.z.z.z.c.c.x.x.l.c.l.c.l.c.l +.x.c.e.} { { { { { { { { { { { { { { { { { { { { { { { { } .......... +..........................................e.c.l.c.c.l.z.z.z.z.x.z.z.x +.x.x.c.x.c.z.x.x.c.x.x.c.l.x.x.x.c.x.c.x.z.c.c.l.", "l.x.x.x.z.z.z.z.l.v.l.v.z.z.l.z.z.z.z.x.z.z.z.z.z.z.z.z.c.v.x.x.x.x.x +.x.z.z.z.| { { { { { { { { { { { { { { { { { { { { { { { } .......... +........................................k.v.z.c.v.l.z.c.c.x.c.x.x.x.x +.x.x.x.x.c.x.x.x.c.c.z.c.c.c.x.x.x.x.c.z.c.c.v.x.", "c.x.x.x.z.c.z.v.v.l.v.l.x.x.v.x.z.c.x.x.z.v.v.x.v.x.x.x.c.c.x.c.x.x.c +.c.v.c.z.z...{ { { { { { { { { { { { { { { { { { { { { { } .......... +....................................1.c.v.c.z.l.v.c.v.c.c.v.x.x.c.x.c +.x.x.c.c.c.c.x.x.c.c.c.z.z.v.v.x.x.x.v.c.c.c.x.x.", "c.c.v.x.x.v.z.c.l.v.c.z.v.l.c.c.c.z.c.x.z.z.z.z.x.z.x.c.c.z.c.c.x.x.v +.c.z.z.c.v.c.8.{ } { { { { { { { { { { { { { { { { { { { { .......... +..................................8.c.c.x.v.z.v.l.v.c.c.x.c.x.v.x.v.x +.z.v.x.x.c.c.v.x.c.c.v.x.z.z.x.x.c.v.x.c.v.c.c.v.", "c.v.c.c.x.c.z.v.v.z.v.v.z.v.v.l.v.z.v.z.z.v.v.z.c.v.z.v.c.x.v.c.v.c.x +.z.v.c.c.c.v.c.y.} { { { { { { { { { { { { { { { { { { { { .......... +................................y.v.c.c.z.v.c.c.v.c.c.v.x.c.v.x.x.v.c +.c.v.c.v.x.v.x.v.v.c.c.v.v.v.v.z.c.x.v.c.x.x.v.z.", "v.c.v.x.v.z.c.v.z.z.c.v.l.v.v.v.v.x.v.x.v.c.c.z.v.c.v.c.c.x.c.v.c.v.c +.c.v.c.v.c.v.c.v.c. .{ { { { { { { { { { { { { { { { { { { .......... +..............................v.v.x.v.l.v.v.v.l.v.c.v.v.x.v.v.l.v.v.x +.c.v.x.v.v.c.c.c.x.v.v.x.z.v.v.c.v.v.c.v.v.c.v.v.", "v.c.c.v.v.c.v.c.v.v.v.x.v.v.v.c.v.z.v.v.c.v.v.v.v.v.c.x.v.v.x.v.v.c.v +.v.c.v.v.c.v.v.c.v.c.X.{ { { { { { { { { { { { { { { { { { .......... +..........................4.v.v.v.v.x.v.v.v.c.v.v.v.c.x.v.c.v.v.v.v.v +.v.v.l.v.v.c.v.v.v.x.v.v.v.v.c.v.v.x.z.v.c.v.c.v.", "v.c.v.v.c.v.v.c.v.z.v.v.l.v.v.v.c.v.v.c.v.v.v.v.v.v.x.v.v.x.v.v.v.c.v +.v.v.v.c.v.c.v.v.c.c.n.q.} { { { { { { { { { { { { { { { { .......... +........................w.v.x.v.v.v.x.v.v.v.v.c.v.v.v.v.x.v.v.v.v.v.v +.v.v.v.v.v.v.v.v.v.v.v.x.v.v.v.v.v.x.v.v.v.v.v.v.", "x.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.c.v.v.v.v.v.v.v.v.v.v.v.v.v.v.c.v +.v.v.v.v.v.v.v.v.v.c.v.n.l.| { { { { { { { { { { { { { { { .......... +......................y.x.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v +.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.", "v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v +.v.v.v.b.v.v.v.v.v.v.v.v.v.v. .{ { { { { { { { { { { { { { .......... +..................%.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.c.n.v.v.v.v +.v.v.b.v.v.v.v.v.v.v.v.v.v.m.v.v.v.v.v.v.v.v.v.v.", "v.v.v.v.v.v.m.v.v.v.v.v.v.m.m.v.v.v.v.v.v.v.v.v.v.b.v.v.v.v.v.v.v.v.n +.v.v.v.v.v.v.v.v.v.v.v.v.n.v.b.1.{ { { { { { { { { { { { { .......... +................2.n.v.n.v.v.n.v.v.n.v.v.v.v.v.v.v.n.v.n.v.n.c.n.v.v.v +.v.v.v.v.v.v.v.v.v.v.m.v.v.v.v.m.b.v.v.v.v.v.v.v.", "v.v.b.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.m.v.v.v.v.v.m.v.v.v.v.v.v.v.v.v +.m.v.v.v.v.b.v.v.b.v.v.n.v.v.v.m.y.} { { { { { { { { { { { .......... +..............y.n.b.v.v.v.v.v.v.v.v.n.v.m.v.v.m.v.v.v.v.v.n.n.v.v.v.v +.v.b.v.v.b.b.v.b.m.v.v.v.v.b.v.m.v.v.v.b.v.v.b.v.", "b.v.v.b.v.b.v.b.v.b.b.v.m.v.m.v.m.v.m.v.m.v.b.m.v.v.v.b.v.b.v.b.m.v.m +.v.b.v.b.v.v.v.v.b.m.v.v.v.b.v.v.m.b.| { { { { { { { { { { .......... +............c.v.n.v.v.n.n.v.n.n.n.v.n.m.v.m.m.v.m.m.v.v.n.n.v.v.n.n.n +.v.v.n.v.b.v.b.v.m.m.v.m.v.m.v.v.b.b.b.v.b.b.v.b.", "v.m.v.m.v.v.v.m.m.v.m.m.v.n.v.v.b.m.v.m.v.m.v.v.v.m.m.v.m.v.m.v.m.n.v +.v.m.m.v.v.m.v.m.n.n.v.m.m.v.m.m.v.v.v.X.{ { { { { { { { { .......... +........<.n.v.v.v.b.n.v.m.v.v.m.v.m.v.m.m.v.m.m.v.m.m.v.n.v.n.v.n.m.m +.m.v.v.n.n.v.m.m.v.m.m.v.m.m.m.m.v.m.m.n.v.n.v.m.", "m.v.m.m.m.m.m.m.m.m.v.b.m.m.m.n.m.v.v.m.m.m.m.m.m.n.v.m.n.m.m.m.v.m.m +.m.m.v.n.m.b.m.b.v.m.m.n.v.m.v.n.n.b.n.n.8.{ { { { { { { { .......... +......8.v.v.n.b.b.b.b.m.m.m.m.m.m.m.m.m.m.v.m.m.m.m.v.m.m.m.n.m.m.m.m +.b.n.m.m.m.n.m.m.m.m.m.m.m.m.v.m.n.m.m.m.m.n.m.n.", "m.m.b.m.m.m.m.m.m.m.v.b.m.n.m.m.m.b.m.m.m.m.m.m.n.b.n.m.m.m.n.v.m.v.m +.m.b.m.m.m.n.m.b.m.m.m.m.m.b.m.n.m.m.n.m.m.l.} { { { { { { .......... +....y.n.n.n.n.b.b.v.b.m.m.N.N.m.b.m.m.b.m.m.m.m.m.m.m.m.m.m.m.m.m.m.m +.m.m.m.m.m.m.m.m.b.b.m.b.b.m.m.m.m.m.m.m.m.m.m.m.", "m.m.b.b.v.m.N.N.n.m.b.m.m.m.m.m.m.b.m.m.m.m.m.m.m.m.m.b.b.b.b.b.m.m.m +.m.m.b.b.m.b.m.b.b.m.m.m.m.m.b.m.b.m.m.m.m.b.b. .{ { { { { .......... +X.n.n.n.n.n.B.b.b.b.b.m.m.B.b.m.b.m.m.b.m.m.m.m.m.m.m.b.b.m.m.m.m.m.m +.b.b.m.b.m.m.b.m.b.b.b.b.b.m.m.m.m.m.b.b.b.b.m.m.", "m.b.B.m.m.m.m.N.m.b.b.B.m.m.m.m.m.m.B.m.m.m.N.m.b.N.m.m.b.B.m.m.B.m.m +.m.b.b.b.b.b.b.m.m.b.N.m.b.b.m.m.b.m.b.B.m.b.B.m.4.{ { { { ........2. +B.b.B.m.B.B.b.b.N.B.b.m.N.m.b.b.b.B.b.b.b.m.b.B.m.m.m.b.m.b.N.m.b.B.m +.b.B.m.m.B.m.b.b.B.m.m.b.B.m.B.m.b.B.N.b.b.N.N.N.", "b.b.m.m.B.m.b.b.b.b.m.m.B.N.b.B.b.m.b.m.B.b.N.m.B.N.m.m.B.m.m.B.N.N.N +.B.B.b.B.N.B.b.B.N.m.B.m.m.b.B.m.B.m.m.m.B.B.b.b.b.e.} { { ......w.n. +B.b.B.N.b.b.B.N.N.b.B.m.B.B.m.B.m.B.b.b.B.m.m.m.B.B.m.B.b.b.B.m.B.m.B +.B.b.B.N.B.b.B.m.B.b.N.m.B.b.b.m.B.b.B.b.N.N.b.B.", "B.b.B.B.B.m.B.b.m.B.b.B.B.b.b.B.b.B.m.m.b.B.m.B.B.m.B.m.b.m.b.B.m.m.N +.B.N.N.B.b.B.m.b.N.B.N.B.B.N.m.B.m.m.B.b.m.m.B.B.b.b.v.| { ....l.n.B. +n.B.b.B.N.B.b.N.N.B.m.b.B.m.B.B.N.b.B.B.B.B.B.b.B.m.B.b.B.B.m.b.B.m.m +.N.B.b.B.B.b.b.B.B.M.B.B.N.N.B.m.b.B.B.b.N.N.B.N.", "N.B.N.m.N.B.N.m.B.B.b.B.b.B.B.b.B.B.B.B.B.N.B.N.B.N.m.B.B.B.m.B.B.B.B +.N.B.B.B.N.m.B.B.B.N.B.N.B.B.B.N.B.B.B.B.B.B.B.N.B.B.B.b...X.B.B.B.n. +B.b.B.N.B.N.B.B.m.B.B.b.B.B.b.B.B.B.B.B.b.B.b.B.B.B.b.B.N.B.B.b.B.B.B +.B.m.B.B.B.N.B.B.N.B.B.m.B.B.B.B.b.B.B.B.B.B.B.B.", "B.B.N.B.B.B.B.B.B.B.B.b.B.B.B.B.b.B.B.B.B.B.B.B.B.B.B.B.b.B.B.B.B.B.B +.N.B.B.B.B.N.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B. +B.B.B.B.B.B.B.B.B.B.N.B.B.B.B.N.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.", "B.B.B.B.B.N.B.B.B.B.B.B.B.B.B.B.B.B.B.B.b.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.N.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B. +B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.", "B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B. +B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.", "B.B.B.B.B.B.B.B.B.B.B.B.B.N.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B. +B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.", "B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B. +B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.", "B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B. +B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.", "B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B. +B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.", "B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B. +B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B +.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B.B." }; end-of-xpm } # end greyCubeLogo #}}}2 sub wilbur { #{{{2 my $xpm = <<'end-of-xpm'; /* XPM */ static char * wilbur_xpm[] = { "110 44 988 2", " c None", ". c #C0C0C0", "+ c #BBBAB9", "@ c #979284", "# c #B0AEAA", "$ c #CAC4B3", "% c #C0C0BF", "& c #BFBEBE", "* c #ADAAA5", "= c #827967", "- c #ADACA7", "; c #C9C1AD", "> c #C3BCAA", ", c #BFBEBD", "' c #BDBDBD", ") c #B4B3B1", "! c #5B4F43", "~ c #B9B8B7", "{ c #B5B4B2", "] c #898374", "^ c #79715E", "/ c #A09D95", "( c #C3C0B6", "_ c #BBB095", ": c #B6B1A3", "< c #BFBFBF", "[ c #B2B0AE", "} c #493C2D", "| c #B7B6B5", "1 c #B8B8B7", "2 c #938E82", "3 c #78715D", "4 c #746D5A", "5 c #A3A19C", "6 c #C0BEBB", "7 c #B9AF9A", "8 c #A69D83", "9 c #ABA598", "0 c #B7B7B6", "a c #B7B7B7", "b c #A19B95", "c c #90867D", "d c #7C6F62", "e c #7B6F62", "f c #796E62", "g c #766C62", "h c #71685D", "i c #433728", "j c #88827C", "k c #A09D9A", "l c #A5A3A0", "m c #B5B4B3", "n c #B8B8B8", "o c #9D9A91", "p c #706956", "q c #706955", "r c #A19F9B", "s c #BCB6A9", "t c #A69D81", "u c #979079", "v c #92897A", "w c #7F7162", "x c #5A442C", "y c #4B3319", "z c #422C15", "A c #3C260F", "B c #38240E", "C c #34210D", "D c #311F0C", "E c #2D1D0B", "F c #2A1B0A", "G c #2B1D10", "H c #2B2014", "I c #281D13", "J c #291F16", "K c #352D25", "L c #73706C", "M c #B6B6B5", "N c #BEBEBE", "O c #BCBCBC", "P c #959186", "Q c #76715E", "R c #6E6755", "S c #6A6351", "T c #6B6453", "U c #A1A09E", "V c #BAB8B5", "W c #ACA288", "X c #85775E", "Y c #543B1F", "Z c #472D10", "` c #452C11", " . c #412910", ".. c #3D270F", "+. c #3A250E", "@. c #36230D", "#. c #33200D", "$. c #2F1E0C", "%. c #2B1C0B", "&. c #281A0A", "*. c #241709", "=. c #211508", "-. c #1D1207", ";. c #191006", ">. c #160E06", ",. c #18130C", "'. c #5C5956", "). c #BABABA", "!. c #908C7E", "~. c #746C5A", "{. c #6D6654", "]. c #686150", "^. c #645E4D", "/. c #6B6657", "(. c #A3A3A3", "_. c #D4D0C8", ":. c #FCFFFC", "<. c #F6F9ED", "[. c #F0F3EF", "}. c #FEFBFF", "|. c #EFF3F7", "1. c #F8F3F1", "2. c #E6EBE8", "3. c #EFEBF0", "4. c #EEE8E5", "5. c #DFE2DF", "6. c #E2E7E4", "7. c #B1AB9B", "8. c #60472B", "9. c #482C0F", "0. c #462C10", "a. c #422A10", "b. c #3F280F", "c. c #3B260F", "d. c #37230E", "e. c #301F0C", "f. c #291A0A", "g. c #251809", "h. c #221608", "i. c #1E1408", "j. c #1B1107", "k. c #170F06", "l. c #120C04", "m. c #0D0702", "n. c #18140F", "o. c #A09D94", "p. c #807A6A", "q. c #756D5A", "r. c #686251", "s. c #625C4C", "t. c #60584A", "u. c #747065", "v. c #A7A4A5", "w. c #B7B3B9", "x. c #B2AEB3", "y. c #B1ACB1", "z. c #A9A4A8", "A. c #7B7C7C", "B. c #787F7A", "C. c #C3C8CB", "D. c #E0DEE2", "E. c #EAEAE1", "F. c #D9D8CF", "G. c #D3DBDD", "H. c #DBD8DC", "I. c #D2DADC", "J. c #D2D5D1", "K. c #DFD7D5", "L. c #D8D2D0", "M. c #B6B6B6", "N. c #B1AFA8", "O. c #69543A", "P. c #462B0F", "Q. c #432A10", "R. c #39250E", "S. c #36220D", "T. c #321F0B", "U. c #2E1D0A", "V. c #251708", "W. c #221507", "X. c #1E1306", "Y. c #1A0F04", "Z. c #1A1208", "`. c #1A130B", " + c #1C150D", ".+ c #2E2820", "++ c #5C5747", "@+ c #7C7360", "#+ c #726B59", "$+ c #6E6754", "%+ c #696251", "&+ c #645E4E", "*+ c #5F5849", "=+ c #5F5A4B", "-+ c #7E7C77", ";+ c #A9A6A9", ">+ c #B2ADB2", ",+ c #A1A0A3", "'+ c #656867", ")+ c #7D7C82", "!+ c #D1CFDA", "~+ c #D3CBCB", "{+ c #CAC8CC", "]+ c #C3C5C8", "^+ c #CCCDCC", "/+ c #C0BFC7", "(+ c #C0BDC2", "_+ c #C4BDC3", ":+ c #C4BEC3", "<+ c #C5C3CC", "[+ c #C3BFC8", "}+ c #BFBFC7", "|+ c #C3C1C5", "1+ c #C0BEC2", "2+ c #C3BFBF", "3+ c #C3BFC7", "4+ c #BEC1C3", "5+ c #C2BFC7", "6+ c #C1C0C1", "7+ c #C2C3C3", "8+ c #C0C5C4", "9+ c #BFC0BF", "0+ c #BABBBB", "a+ c #ADADAD", "b+ c #938A7C", "c+ c #5B472B", "d+ c #3D250B", "e+ c #3A2209", "f+ c #362009", "g+ c #311C06", "h+ c #2D1A05", "i+ c #2D1D09", "j+ c #372815", "k+ c #3A2C1C", "l+ c #463C2D", "m+ c #493F32", "n+ c #554D41", "o+ c #4E4639", "p+ c #4F483A", "q+ c #5D5749", "r+ c #6C6555", "s+ c #756E5A", "t+ c #726B57", "u+ c #6F6855", "v+ c #6A6452", "w+ c #635C4D", "x+ c #605949", "y+ c #5D5748", "z+ c #646054", "A+ c #878786", "B+ c #AFAAAF", "C+ c #AEA9AE", "D+ c #655F5E", "E+ c #5E5252", "F+ c #CDC3C9", "G+ c #C3BEC9", "H+ c #C2C1C5", "I+ c #C3C1C4", "J+ c #C2C1C4", "K+ c #C2C0C4", "L+ c #C3C0C5", "M+ c #C1C0C3", "N+ c #C0C0C1", "O+ c #B4B4B4", "P+ c #C0BCB2", "Q+ c #AFA794", "R+ c #918771", "S+ c #8A806B", "T+ c #817865", "U+ c #88826F", "V+ c #9A9384", "W+ c #A19C8D", "X+ c #9D9684", "Y+ c #857E6A", "Z+ c #7F7862", "`+ c #7C7662", " @ c #766F5E", ".@ c #6F6856", "+@ c #6B6552", "@@ c #6B6452", "#@ c #66614E", "$@ c #645D4D", "%@ c #635C4C", "&@ c #60594A", "*@ c #5C5647", "=@ c #5C5446", "-@ c #6E6D68", ";@ c #A5A4A6", ">@ c #BAB7BB", ",@ c #AAA5AA", "'@ c #4B5948", ")@ c #E0D8D6", "!@ c #D0CED8", "~@ c #C8C6CC", "{@ c #C1C0C2", "]@ c #BBBBBB", "^@ c #D4D4D3", "/@ c #FAFAFA", "(@ c #FFFFFF", "_@ c #FBFBF8", ":@ c #C3BDAF", "<@ c #8D846D", "[@ c #A29B8C", "}@ c #E4E2DE", "|@ c #FEFDFD", "1@ c #FAF9F8", "2@ c #D3D1CA", "3@ c #898472", "4@ c #79725D", "5@ c #726B58", "6@ c #6C6553", "7@ c #655F4E", "8@ c #625B4B", "9@ c #5E5847", "0@ c #5C5646", "a@ c #595344", "b@ c #575143", "c@ c #565041", "d@ c #565142", "e@ c #585444", "f@ c #5E5C52", "g@ c #757576", "h@ c #BEBCC0", "i@ c #B5B1B6", "j@ c #B0ABB0", "k@ c #4F564F", "l@ c #5D636D", "m@ c #C1C7C5", "n@ c #000000", "o@ c #B3B3B3", "p@ c #8D8D8D", "q@ c #777777", "r@ c #898989", "s@ c #C7C6C2", "t@ c #FBFBFB", "u@ c #D8D8D8", "v@ c #919192", "w@ c #C2C2C2", "x@ c #FBF9F8", "y@ c #B6B09F", "z@ c #F9F9F8", "A@ c #F7F7F7", "B@ c #ECEDED", "C@ c #F3F3F3", "D@ c #FCFCFD", "E@ c #D5D5CF", "F@ c #807965", "G@ c #6A6352", "H@ c #625B4A", "I@ c #5B5545", "J@ c #555041", "K@ c #514C3E", "L@ c #4D493B", "M@ c #4B4539", "N@ c #4C4639", "O@ c #4E493B", "P@ c #524D40", "Q@ c #535047", "R@ c #595858", "S@ c #908F90", "T@ c #C0BDC1", "U@ c #B6B2B6", "V@ c #A9A2A7", "W@ c #6F7366", "X@ c #E3DEED", "Y@ c #C7CBCF", "Z@ c #C3C0C4", "`@ c #AFAFAF", " # c #6B6B6B", ".# c #535353", "+# c #484848", "@# c #323232", "## c #4D4D4E", "$# c #93918D", "%# c #C0B9A9", "&# c #333333", "*# c #191919", "=# c #F4F5F5", "-# c #E8E6E3", ";# c #757575", "># c #5F5F5F", ",# c #DDDDDD", "'# c #E4E3E4", ")# c #938E81", "!# c #575242", "~# c #4F4A3C", "{# c #4A4537", "]# c #454134", "^# c #433F32", "/# c #443F33", "(# c #49463E", "_# c #484948", ":# c #656364", "<# c #B6B4B7", "[# c #BBB7BC", "}# c #A2A0A5", "|# c #574F56", "1# c #697376", "2# c #C6C4CD", "3# c #7B7B7B", "4# c #656565", "5# c #AEAEAE", "6# c #929292", "7# c #29292A", "8# c #45423C", "9# c #9C9584", "0# c #FBFAF8", "a# c #212122", "b# c #010101", "c# c #1D1E1E", "d# c #EAE9E8", "e# c #EAE8E7", "f# c #FAFAFB", "g# c #E8E8E8", "h# c #858585", "i# c #797979", "j# c #060606", "k# c #999999", "l# c #DDDEDF", "m# c #99958A", "n# c #6C6552", "o# c #655E4D", "p# c #544E40", "q# c #4C4739", "r# c #453F34", "s# c #413D31", "t# c #3E3B2F", "u# c #3E3931", "v# c #383838", "w# c #888789", "x# c #BEBBC0", "y# c #A3A1A2", "z# c #68736E", "A# c #645461", "B# c #C3C8C1", "C# c #B5B5B5", "D# c #545454", "E# c #7C7C7C", "F# c #CDCDCD", "G# c #A6A6A6", "H# c #4B4B4B", "I# c #2F2F2F", "J# c #333433", "K# c #5E5A50", "L# c #BBB6A8", "M# c #C6C7C6", "N# c #B9B3A6", "O# c #B6B2A5", "P# c #F5F5F6", "Q# c #E0E0E0", "R# c #3A3A3A", "S# c #080808", "T# c #CBCCCA", "U# c #848071", "V# c #67604E", "W# c #615B4A", "X# c #575244", "Y# c #504A3C", "Z# c #474237", "`# c #423D31", " $ c #3F3A2F", ".$ c #3F392E", "+$ c #3B3930", "@$ c #292A27", "#$ c #393939", "$$ c #4F4F4F", "%$ c #B3B1B4", "&$ c #ABA6AB", "*$ c #D1D3D0", "=$ c #C7C4C8", "-$ c #A9A9A9", ";$ c #3E3E3E", ">$ c #5D5D5D", ",$ c #727272", "'$ c #3D3D3D", ")$ c #353536", "!$ c #414141", "~$ c #504F4B", "{$ c #797160", "]$ c #A09888", "^$ c #ABA495", "/$ c #A39C8A", "($ c #89806B", "_$ c #8F8774", ":$ c #E0DFDC", "<$ c #EAEAEB", "[$ c #9F9F9F", "}$ c #3C3C3C", "|$ c #707070", "1$ c #D1D1D1", "2$ c #A7A5A0", "3$ c #706857", "4$ c #665F4D", "5$ c #5D5747", "6$ c #4C473B", "7$ c #464236", "8$ c #413D30", "9$ c #3E3A2D", "0$ c #413C2F", "a$ c #33302A", "b$ c #282828", "c$ c #404040", "d$ c #575757", "e$ c #C1BFC3", "f$ c #5C6967", "g$ c #C8C6D1", "h$ c #C6CCCB", "i$ c #AAAAAA", "j$ c #555555", "k$ c #3B3B3B", "l$ c #424242", "m$ c #505050", "n$ c #5B5B58", "o$ c #6A6457", "p$ c #7B725D", "q$ c #7D7661", "r$ c #817B66", "s$ c #857D67", "t$ c #837C65", "u$ c #8D8776", "v$ c #C2C0BA", "w$ c #D7D6D5", "x$ c #E3E2E3", "y$ c #D5D4D3", "z$ c #A7A39B", "A$ c #716B59", "B$ c #5A5444", "C$ c #504B3D", "D$ c #4A4538", "E$ c #444034", "F$ c #403C30", "G$ c #3F3B31", "H$ c #403B31", "I$ c #262322", "J$ c #2D2D2D", "K$ c #494949", "L$ c #626262", "M$ c #AEA9AF", "N$ c #626E52", "O$ c #C5D5C8", "P$ c #C5BBCE", "Q$ c #515151", "R$ c #2B2B2B", "S$ c #3F3F3F", "T$ c #454545", "U$ c #525252", "V$ c #5E5E5E", "W$ c #6A6969", "X$ c #656156", "Y$ c #6E6855", "Z$ c #76705B", "`$ c #7E7662", " % c #817965", ".% c #807863", "+% c #7C7460", "@% c #807865", "#% c #807A68", "$% c #817B6B", "%% c #7B7563", "&% c #6F6654", "*% c #67604F", "=% c #4B463A", "-% c #464135", ";% c #37332C", ">% c #232322", ",% c #363636", "'% c #6E6D6D", ")% c #B4AFB4", "!% c #ABA7AC", "~% c #4F5663", "{% c #5F6358", "]% c #D2D0DB", "^% c #B7C9BD", "/% c #CDCECD", "(% c #828282", "_% c #444444", ":% c #5F5E5E", "<% c #6C6B6B", "[% c #747473", "}% c #615D52", "|% c #635D4B", "1% c #6A6451", "2% c #736E58", "3% c #79725E", "4% c #7B725F", "5% c #776F5B", "6% c #756D59", "7% c #716956", "8% c #6E6553", "9% c #675F4F", "0% c #4D483D", "a% c #3C3831", "b% c #4A453A", "c% c #474336", "d% c #423E32", "e% c #3E3A2F", "f% c #3E3A2E", "g% c #423F32", "h% c #262522", "i% c #2A2A2A", "j% c #A9A8AA", "k% c #BFBEC1", "l% c #B6B1B6", "m% c #ACA8AC", "n% c #495951", "o% c #5F5B67", "p% c #D4CFD4", "q% c #C8C5CA", "r% c #C5C7C5", "s% c #C5C3C8", "t% c #B1B1B1", "u% c #686868", "v% c #4C4C4C", "w% c #626261", "x% c #6D6D6D", "y% c #757471", "z% c #524E41", "A% c #585343", "B% c #5E5747", "C% c #655D4C", "D% c #6D6653", "E% c #6C6554", "F% c #635D4C", "G% c #5E5849", "H% c #4D473A", "I% c #3C362D", "J% c #514C43", "K% c #585146", "L% c #463F33", "M% c #3B392E", "N% c #38362D", "O% c #3A372C", "P% c #2A2823", "Q% c #212121", "R% c #353535", "S% c #4D4D4D", "T% c #6A6A6A", "U% c #848484", "V% c #9D9D9D", "W% c #C0BFC1", "X% c #B7B3B8", "Y% c #ABA7AB", "Z% c #CCCACE", "`% c #CCC3C9", " & c #C7C5C9", ".& c #C3C2C6", "+& c #A5A5A5", "@& c #737373", "#& c #6F6F6E", "$& c #7B7B7C", "%& c #828180", "&& c #605D54", "*& c #4A4638", "=& c #4D4A3C", "-& c #544F41", ";& c #5A5344", ">& c #605A49", ",& c #605A4B", "'& c #605A4A", ")& c #5E5848", "!& c #5C5648", "~& c #524C40", "{& c #40382B", "]& c #503E2B", "^& c #644D37", "/& c #725C44", "(& c #7B654B", "_& c #7F684C", ":& c #816A4F", "<& c #887254", "[& c #917859", "}& c #76634B", "|& c #6E604F", "1& c #5C5D5D", "2& c #888888", "3& c #ACACAC", "4& c #B9B6BA", "5& c #AEAAAF", "6& c #586659", "7& c #6E6075", "8& c #C6C8C5", "9& c #C6C3C8", "0& c #C3C2C5", "a& c #999998", "b& c #827F77", "c& c #77736B", "d& c #615D50", "e& c #4F4B3C", "f& c #4A4438", "g& c #4B4739", "h& c #544E41", "i& c #595444", "j& c #545042", "k& c #494538", "l& c #3F3C31", "m& c #322F26", "n& c #25231E", "o& c #383229", "p& c #54493B", "q& c #6C5D4B", "r& c #79664E", "s& c #7E664A", "t& c #957857", "u& c #A2835F", "v& c #AE8E67", "w& c #BB9971", "x& c #C6A478", "y& c #A19A91", "z& c #9F9FA0", "A& c #909090", "B& c #8E8E8E", "C& c #969696", "D& c #636363", "E& c #8F8F8F", "F& c #4C6C54", "G& c #5B5E5D", "H& c #C1CAC5", "I& c #BBC1C3", "J& c #C2C0C3", "K& c #A5A4A1", "L& c #7A776F", "M& c #4E4A41", "N& c #333029", "O& c #332F26", "P& c #312F25", "Q& c #332E25", "R& c #2C2821", "S& c #211E19", "T& c #1E1C18", "U& c #1A1915", "V& c #1D1D18", "W& c #24221D", "X& c #312F29", "Y& c #403D35", "Z& c #525047", "`& c #636157", " * c #716E63", ".* c #5F5A4F", "+* c #474335", "@* c #4A4234", "#* c #534737", "$* c #705D46", "%* c #A28664", "&* c #B79771", "** c #928F8B", "=* c #C3C3C3", "-* c #878787", ";* c #A8A8A8", ">* c #B0AAAF", ",* c #4E5557", "'* c #777070", ")* c #C2C0C5", "!* c #B9B9B9", "~* c #B2B2B2", "{* c #A7A7A7", "]* c #8B8B8A", "^* c #62615F", "/* c #403F3D", "(* c #1C1B18", "_* c #0E0D0C", ":* c #0A0907", "<* c #0D0C0A", "[* c #151412", "}* c #23221E", "|* c #2E2E28", "1* c #3F3C34", "2* c #504D43", "3* c #5F5B51", "4* c #6B685C", "5* c #6A665C", "6* c #595549", "7* c #39362B", "8* c #272620", "9* c #181716", "0* c #141414", "a* c #1B1B1B", "b* c #242424", "c* c #45403A", "d* c #5C5A56", "e* c #676767", "f* c #7F7F7F", "g* c #959595", "h* c #989898", "i* c #717171", "j* c #808080", "k* c #919191", "l* c #A4A3A6", "m* c #71615D", "n* c #CEC4CA", "o* c #C6C4C8", "p* c #BFBEBF", "q* c #6B6B6A", "r* c #59595A", "s* c #424140", "t* c #33322E", "u* c #2F2E2B", "v* c #34332E", "w* c #3A3832", "x* c #413F39", "y* c #4B4941", "z* c #4F4D45", "A* c #403E38", "B* c #252321", "C* c #171715", "D* c #171717", "E* c #202020", "F* c #272727", "G* c #313131", "H* c #585858", "I* c #646464", "J* c #8C8C8C", "K* c #818181", "L* c #787878", "M* c #A2A2A2", "N* c #A9A5A8", "O* c #CAD1D4", "P* c #C5C5C9", "Q* c #C0BEC1", "R* c #BAB9BB", "S* c #B0B0B0", "T* c #9B9A9A", "U* c #7D7D7C", "V* c #6F6E6E", "W* c #2C2C2C", "X* c #232323", "Y* c #222222", "Z* c #434343", "`* c #565656", " = c #616161", ".= c #A6A5A7", "+= c #B7B6B9", "@= c #BCBABD", "#= c #BDBBBE", "$= c #BDBCBF", "%= c #B6B3B7", "&= c #A5A2A4", "*= c #C4BECA", "== c #BEBDC0", "-= c #A4A4A4", ";= c #9A9A9A", ">= c #8E8E8D", ",= c #828181", "'= c #747373", ")= c #595959", "!= c #4E4E4E", "~= c #464646", "{= c #6F6F6F", "]= c #7E7E7E", "^= c #868686", "/= c #B0AFB2", "(= c #B9B5BA", "_= c #A1A0A4", ":= c #C4CAC0", "<= c #CAC9C0", "[= c #C0C0C6", "}= c #B9B8BB", "|= c #A1A1A1", "1= c #939393", "2= c #696969", "3= c #5B5B5B", "4= c #5A5A5A", "5= c #7B7A7B", "6= c #939294", "7= c #A5A3A6", "8= c #AAA9AB", "9= c #ADABAE", "0= c #AFADB0", "a= c #B0AFB1", "b= c #B2B1B3", "c= c #BAB6BB", "d= c #67765F", "e= c #CAC2C8", "f= c #AEADAF", "g= c #8B8B8B", "h= c #7A7A7A", "i= c #8A8A8A", "j= c #B2B0B3", "k= c #C7C5CF", "l= c #C4C2C7", "m= c #C0BFC2", "n= c #C1BFC2", "o= c #A9A7AA", "p= c #756D56", "q= c #C4C4C5", "r= c #BBB8BC", "s= c #757C80", "t= c #D5CDCC", "u= c #CCC6C4", "v= c #CBC5C4", "w= c #C5C3C9", "x= c #C1BEC2", "y= c #B3AFB3", "z= c #ACA8AD", "A= c #BABBC4", "B= c #B4BCC1", "C= c #ACAEB4", "D= c #ABABAC", "E= c #AAABAB", "F= c #AEAFB0", "G= c #B6B5B8", "H= c #BFBDC2", "I= c #C4C2C6", "J= c #C3BCC1", "K= c #BFBCC2", "L= c #C3C0C2", "M= c #B5B7BA", "N= c #B7AFB8", "O= c #B3ADB2", "P= c #BAB9B5", "Q= c #B2B3B4", "R= c #B8B4B8", "S= c #B8B4B9", "T= c #B6B2B5", "U= c #B5B2B7", "V= c #B6B2B7", "W= c #B6B3B8", "X= c #B7B3B7", "Y= c #ADAAAE", "Z= c #ADA9AD", "`= c #ABACAC", " - c #999997", ".- c #9B9E9C", "+- c #8D908F", "@- c #858887", "#- c #848885", "$- c #848984", "%- c #828684", "&- c #828782", "*- c #828783", "=- c #838884", "-- c #848985", ";- c #858986", ">- c #868B87", ",- c #888C89", "'- c #898D8A", ")- c #878B88", "!- c #868A86", "~- c #848A87", "{- c #858985", "]- c #828984", "^- c #858683", "/- c #88888A", "(- c #7F8282", "_- c #838B86", ":- c #84877F", "<- c #8E908B", "[- c #8B8685", "}- c #8E9990", "|- c #8F8D91", "1- c #8C7F85", "2- c #7B878B", "3- c #8C9883", "4- c #867F8B", "5- c #848F89", "6- c #8F918C", "7- c #889193", "8- c #7A7E75", "9- c #86858B", "0- c #6F6E79", "a- c #697668", "b- c #727074", "c- c #766471", "d- c #726F63", "e- c #4E5673", "f- c #6C6E54", "g- c #646165", "h- c #5A474B", "i- c #515057", "j- c #676357", "k- c #706067", "l- c #55605D", "m- c #4A494D", "n- c #818682", "o- c #767A76", "p- c #626B68", "q- c #505658", "r- c #424650", "s- c #484643", "t- c #4B4651", "u- c #4E3D4D", "v- c #594B60", "w- c #3E4436", "x- c #4B453A", "y- c #37483E", "z- c #53534F", "A- c #424144", "B- c #36442F", "C- c #2D242E", " + + + ", " + + + ", " + + + ", " + + . + ", " + + + + ", " + + @ # + ", " + $ % + . & * = - + ", " + ; > , ' + ) ! ~ { ] ^ / + ", " + ( _ : + + < . . . [ } | . 1 2 3 4 5 + ", " + < 6 7 8 9 +0 a a b c d e f g h i j k l m . . n o 4 p q r + ", " + ' s t u +v w x y z A B C D E F G H I J K L M N O M P Q R S T U + ", " + V W X +Y Z ` ...+.@.#.$.%.&.*.=.-.;.>.,.'.).[ !.~.{.].^./.(. _._._. + ", " :.:.<.[.<.[.}.[.|.|.|.|.|.|.|.|.1.[.1.1 +.1.1.1.1.2.[.2.[.2.[.[.[.[.[.1.3.3.3.3.3.<.[.[.[.[.[.4.3.5.4.6.a 7.8. +9.0.a.b.c.d.C e.E f.g.h.i.j.k.l.m.n.o.p.q.{.r.s.t.u.v.w.x.y.z.A.B.C. + ", " 1.2.2.5.5.5.D.E.E.E.E.E.E.E.E.E.2.2.2.2 +.2.2.2.2.2.4.2.3.2.D.2.D.5.5.E.F.E.F.5.5.G.D.D.H.H.I.J.5.G.K.L.M.N.O. +P.Q. ...R.S.T.U.F V.W.X.Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+>+>+>+,+'+)+ + ", " :.E.J.!+~+{+]+^+/+(+_+_+:+/+/+<+[+}+}+/ ++/+/+/+|+(+}+1+2+1+|+[+|+[+3+3+/+1+[+_+(+1+4+2+:+5+6+7+8+9+< 0+M.a+b+ +c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+].w+x+y+z+A+B+>+>+>+>+C+D+E+ + ", " :.5.F+G+|+|+H+|+|+|+|+|+|+|+|+I+|+|+|+| ++|+|+J+J+|+|+|+|+|+K+L+|+K+|+|+|+K+K+|+K+|+|+|+M+N+. . . < N ).O+N P+ +Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@@@%+#@$@%@&@*+*@=@*@-@;@>@,@y.>+>+B+'@'+ + ", " :.)@!@~@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+| ++|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+K+{@. . < < < N ]@^@/@(@ +_@:@<@[@}@|@(@1@2@3@4@5@6@7@8@9@0@a@b@c@c@d@e@f@g@h@|+1+i@>+>+j@k@l@ + ", " :.F.m@I+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+n +@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+K+. . o@p@q@r@a+O s@t@u@v@ +w@x@y@z@(@A@B@C@D@E@F@p G@H@I@J@K@L@M@N@O@P@Q@R@S@|+|+|+T@U@>+V@W@E+ + ", " <.X@Y@Z@|+|+K+|+|+|+|+|+n@|+|+|+n@|+|+n +@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+K+. `@ #.#+#@###$#%#(@ #&# +*#=#-#(@A@' ;#>#,#'#)#$+].x+!#~#{#]#^#/#{#(#_#:#<#|+|+|+K+[#>+}#|#1# + ", " }.2.2#|+|+|+K+|+|+|+|+|+|+|+|+|+n@|+|+n +@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+{@N 3#4#5#6#+#7#8#9#0#a#b# +c#d#e#f#g#h#i#j#k#l#m#n#o#*@p#q#r#s#t#s#u#v#+#w#|+|+|+|+|+x#>+y#z#A# + ", " :.E.B#L+n@|+|+n@|+|+n@|+n@|+|+n@n@n@|+n +@|+n@n@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+6+C#D#E#F#G#H#I#J#K#L#% h# +M#N#O#P#Q#R#S#b#(.T#U#V#W#X#Y#Z#`# $.$+$@$#$$$%$|+|+|+|+|+T@>+&$l@D+ + ", " :.5.*$=$n@|+|+n@|+|+n@|+n@|+|+|+n@|+|+n +@n@|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+N+-$;$>$p@,$'$)$!$~${$]$^$ +/$($_$:$<$[$}$|$1$2$3$4$5$p#6$7$8$9$0$a$b$c$d$1+|+|+|+|+|+e$>+>+A#f$ + ", " :.[.g$h$n@|+n@n@|+n@|+|+n@|+|+|+n@|+|+n +@|+|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+6+i$}$}$j$+#k$l$m$n$o$p$q$ +r$s$t$u$v$w$x$y$z$A$4$*+B$C$D$E$F$G$H$I$J$K$L$e$|+|+|+|+|+K+>+M$N$A# + ", " 1.3.O$P$n@|+n@n@|+n@|+|+n@|+|+|+n@|+|+n +@|+|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+M+]@Q$R$k$S$T$U$V$W$X$Y$Z$ +`$ %.%+%@%#%$%%%&%*%s.=%~#q#-%`# $F$;%>%,%.#'%1+|+|+|+|+|+K+)%!%~%{% + ", " }.D.]%^%/%n@|+n@|+n@|+|+n@|+|+|+n@|+|+n +@|+|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+K+. (%@#k$_%U$:%<%[%}%|%1% +2%3%4%5%6%7%8%].9%s.0%a%b%c%d%e%f%g%h%i%c$>#i#j%k%K+|+|+|+K+l%m%n%o% + ", " }.5.p%q%r%n@s%|+n@|+|+|+n@|+|+|+n@|+|+n +@|+|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+K+. t%u%v%D#w%x%E#y%z%A%B% +C%D%u+E%S *%F%G%++H%I%J%K%L%M%N%O%P%Q%R%S%T%U%V%a+a W%K+K+M+X%Y%o%W@ + ", " }.5.C.Z%C.|+`% &.&|+|+|+|+|+|+|+|+|+|+| ++|+|+|+|+|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+|+n@n@{@N +&@&4##&$&%&&&*&=&-& +;&>&F%,&'&)&!&~&{&]&^&/&(&_&:&<&[&}&|&'.1&,$2&[$3&5#[$o@N . 4&5&6&7& + ", " }.2.C.C.C.8&9&0&|+|+|+|+|+|+|+|+|+|+|+n +@|+|+|+|+|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+n@|+|+K+. N 5#a&b&c&d&e&f&g&e& +h&!#i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z&k#A&B&C&D&l$v%>#E&a < j@F&G& + ", " }.5.p%Z%H&I&|+|+|+|+|+|+|+|+|+|+|+|+|+| ++|+|+|+|+|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+n@|+|+|+J&< O M.K&L&M&N&O&P&Q& +R&S&T&U&V&W&X&Y&Z&`& *.*+*@*#*$*%*&***G#M.< =*E&,%!$Q$>$x%-*;*>*,*'* + ", " }.5.Z%g$Z%9&)*|+|+|+|+|+|+|+n@n@n@|+|+n +@|+|+|+n@n@n@n@|+|+|+|+|+n@n@n@|+|+n@n@n@n@n@|+|+W%' !*~*{*]*^*/*(*_* +:*<*[*}*|*1*2*3*4*5*6*7*8*9*0*a*b*c*d*e*f*g*+&h*Q$+#d$L$i*j*k*l*m*o% + ", " :.5.Z%n*q%o*|+|+|+|+|+|+|+n@|+|+n@|+|+n +@|+|+n@|+|+|+n@|+|+|+|+n@|+|+|+n@|+|+|+n@|+|+|+|+K+p*]@O+3&[$A&j*q*r* +s*t*u*v*w*x*y*z*A*B*C*0*D*a*E*F*G*}$K$H*I*@&f*J*B&K*L*j*J*M*~*N*G&G& + ", " :.5.O*C.C.P*|+|+|+|+|+|+n@|+|+|+n@|+|+n +@|+|+n@|+|+|+n@|+|+|+|+n@|+|+|+n@|+|+|+n@K+|+K+|+|+K+Q*R*S*G#T*p@U*V* +V$S%S$&#W*F*b*X*Y*Y*Y*b*F*W*@##$Z*v%`* =x%i#r@.=+=@=#=$=Q*J&%=&=o%D+ + ", " }.5.n**=C.|+|+|+|+|+|+|+n@|+I+Z@n@|+|+n +@|+|+n@|+|+|+n@|+|+|+|+n@|+K+|+n@|+|+|+n@|+|+|+|+|+|+|+|+==S*-=;=>=,= +'=I*)=!=~=S$'$}$k$}$'$S$_%K$$$d$>#e*{=q@]=^=/=|+|+|+|+|+|+|+(=_='*f$ + ", " <.G.J.:=<=[=|+|+|+|+|+|+n@|+|+|+n@|+|+n +@|+|+n@|+|+|+n@|+|+|+|+n@|+|+|+n@|+|+|+n@|+|+|+|+|+|+|+|+|+K+|+}=|=1= +r@E#i*2=D&V$3=3=4=3=>$ =4# #5=6=7=8=9=0=a=b=e$|+|+|+|+|+|+|+c=}#D+d= + ", " }.D.g$Z%Z%e=|+|+|+|+|+|+|+n@n@n@|+n@|+n +@|+|+|+n@n@n@n@|+|+|+|+|+n@n@n@|+|+|+|+n@|+|+|+|+|+|+|+|+|+|+|+|+K+e$ +f=6#g=U%f*3#i#i#L*h=E#j*U%i=j=|+|+|+|+|+|+|+|+|+|+|+|+|+|+K+(=}#7&7& + ", " :.F.8&Z%g$k=l=|+|+|+|+|+|+|+|+|+|+|+|+| ++|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+ +|+K+e$m=1+1+1+1+1+1+1+m=n=e$K+|+|+|+|+|+|+|+|+|+|+|+|+|+|+e$l%o=p={% + ", " :.5.8&C.8&r%q=)*|+|+|+|+|+|+|+|+|+|+|+| ++|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+ +|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+K+r=>+5&s=,* + ", " |.D.8&8&t=u=v=w=|+|+|+|+|+|+|+|+|+|+|+| ++|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+K+|+K+K+|+|+ +|+K+|+K+K+|+|+|+K+|+K+K+|+|+|+K+|+K+K+|+|+|+K+|+K+K+K+x=>@y=>+z=s=D+ + ", " :.5.u=Z%I&A=B=C=D=E=F=G=$=|+|+|+|+|+|+| ++|+|+|+|+|+)*K+K+K+K+K+K+K+K+K+J+K+K+J+H=T@I=J=p*K=k%L=M=N=O=).a P=a +P=Q=R=R=S=S=S=S=R=R=%=U@X%<#%=T=i@U=U@V=%=W=V=%=%=X=U@y.Y=Z=`= -B.E+ + ", " .-+-@-#-$-%-&-&-*-*-*-*-*-=-#---;->-,-' +-,-,-,-)-!-~-{-]-^-/-(-_-:-*-<-*-s=[-}-|-1-2-z#3-4-s=*-5-6-7-8-s=9-0- +)+0-a-b-c-'+s=W@'+7&d-e-f-g-o%~%6&h-,*G&i-j-o%d-l@G&z#g-'+k-0-0-l-m- + ", " *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +-*-*-*-*-*-*-*-*-*-*-*-*-n-o-p-q-G&l-E+k@6&r-k-{%m-G&|#|#s-m-E+t-{%t- +{%E+D+m-{%l-u-m-6&i-i-k@v-w-,*x-y-r-z-A-m-t-G&t-i-n%i-|#l-z-i-z-B-C- + ", " + + + ", " + + + ", " + + + "}; end-of-xpm } # end wilbur #}}}2 # END logos }}}1 # __END__ {{{1 __END__ #---+--- 1 ---+--- 2 ---+--- 3 ---+--- 4 ---+--- 5 ---+--- 6 ---+--- M # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - =head1 NAME B<qb3> =head1 DESCRIPTION This F<file> should be used as a skeleton for further perl-scripts which are to be developed. =head1 AUTHOR tos <_tosch_@yahoo.com> Copyright (c) 2003-04 Thomas Schlichting. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 VERSION $Revision: 0.68 $ =cut # __END__ }}}1
Re: "Rubics Cube" game
by zentara (Archbishop) on Mar 05, 2008 at 13:39 UTC
    It sounds pretty impressive, but when I go to download the code, it seems to be incomplete, missing the Tk stuff, and leaving xpms. Can you put it all together in one piece and put it on a website somewhere? I don't really feel like putting together these 4 parts, hoping to get it right.

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      Sorry, but the limitation to 64kb/node constrained me to part the source. But also with the 4 parts there is no principally problem. I've tested it. Concatenate the 4 parts and the md5sum should be 81b7f0a98394acd86d51132094c20835.

      of course you need Tk.pm

      I'll try to put the whole thing onto another website.


      Is simplicity best or simply the easiest Martin L. Gore

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://671890]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2024-04-18 09:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found