From: Simone.Rapisarda@p10.f800.n33.z2.fidonet.org (Simone Rapisarda)
Newsgroups: comp.sys.hp48
Subject: SmartKeys version 1.46 (An HP48 Customizer)
Date: 2 Oct 92 23:53:09 GMT
Organization: FidoNet node 2:33/800.10 - Italy UUCP Gate, Italy

Some netters that don't have access to comp.sources.hp48 have asked me
to post SmartKeys here on comp.sys.hp48 so here is the complete SmartKeys
file that I sent to Chris.
I hope that this article will not cause problems to anyone.

ciao

                                                            RAP

------------------------------------------------------------------------

BEGIN_RDME SmartKeys.readme

The intended audience of this document and this library is people who use,
or plan to use, the HP48 user keyboard. However people who are not interested
in the User Keyboard can find in SmartKeys some interesting things:

- The CRSTM instruction for a Handy use of tree-structured menus.
- The SAFE instruction that transform dangerous programs into Safe programs.
- The DUAL instruction that Allow multiple ways of execution for any program.
- The Multi Keyboard Capability can be used in conjunction with the IR-
  sampling programs to simulate real named remote-control units.

If you don't use the User Keyboard because you don't find it useful,
SmartKeys will give you a lot of good reasons to use it, believe me!



                                                        RAP

[Note: If you ever use USER mode, then you need this library!  It makes the
 creation and deletion of key assignments easier, faster, and *far* more
 powerful.  Check it out!  -jkh-]

END_RDME

BEGIN_DOC SmartKeys.doc


           888                      8   8   8
          8   8                     8   8  8
          8     88 8    888  8 888 888  8 8    888  8   8  8888
           888  8 8 8      8 88     8   88    8   8 8   8 8
              8 8 8 8   8888 8      8   8 8   88888 8   8  888
          8   8 8 8 8  8   8 8      8 8 8  8  8      8888     8
           888  8   8   8888 8       8  8   8  888      8 8888
                                                     888


                                    by

                            Simone A. Rapisarda

                               Version 1.46

                               18 Sept 1992




                I N D E X   O F   T H E   A R G U M E N T S


 1  - Introduction
 1.1  Description of the library
 1.2  Releasing Notes
 1.3  Thanks

 2  - SmartKeys Commands
 2.1  Important Notes
 2.2  Commands in the SmartKeys menu
 2.3  Description of each command

 3  - Command Usage Examples
 3.1  Commands used: \->IFPRGTE ASNK
 3.2  Commands used: STDK \->IFCMDTE ASNK
 3.3  Commands used: KEYN RECK ASNK
 3.4  Commands used: \->PSH \->EVL \->IFPRGTE \->EDIT \->IFCMDTE
 3.5  Command used: \->TDIR
 3.6  Command used: SAFE
 3.7  Command used: CRCSTM

 4  - Useful information
 4.1  The Internal UserKeys List
 4.2  Unused and Useless HP48 Default Key Assignments
 4.3  Another suggestion for keys-hungry HP48 users




1  - Introduction
-----------------


1.1   Description of the library

      SmartKeys was born as a library of utilities designed to increase the
      power of the already powerful HP48 user keyboard capability. This still
      remain is main goal, however some new command does not have any
      relation with the user keyboard but, more generally, with the
      customization of the calculator.
      SmartKeys is a self-attaching library entirely written in system-RPL.
      It's 4558 bytes long and is identified by the library ID 1616. The
      commands it contains were conceived for these fundamental purposes:

      - Facilitate the usage of key assignments.
        Commands: ASNK RCLK DELK DISPK KEYN PACKKEYS

      - Increase the speed of user keyboard operations.
        Commands: ASNK RCLK DELK DISPK KEYN PACKKEYS GETKEYS PUTKEYS ADDFR

      - Save key assignment memory.
        Commands: ASNK DELK STDK PACKKEYS

      - Allow special key assignments normally not supported.
        Commands: STDK RECK \->EVL \->PSH \->EDIT \->EQW \->IFCMDTE
                  \->IFIMMTE \->IFPRGTE \->IFALGTE 'BADK

      - Increase the number of possible assignments on a single key.
        Commands: \->IFCMDTE \->IFIMMTE \->IFPRGTE \->IFALGTE DUAL

      - Fill the gaps in the HP48 default key assignments.
        Commands: STDK RECK \->IFCMDTE \->IFIMMTE \->IFPRGTE \->IFALGTE

      - Allow the usage of more than one user keyboard.
        Commands: \->KB KB\-> \->KBN KBN\-> KBNM KBMN GETKEYS PUTKEYS

      - Help the user keyboard always stay active.
        Command: $CONFIG (hidden)

      - Reconfigure the calculator after a warm-start.
        Command: $CONFIG (hidden)

      - Provide a way to transform dangerous programs into "Safe" programs.
        Command: SAFE

      - Allow multiple ways of execution for any program.
        Command: DUAL

      - Handy use of tree-structured menus.
        Commands: CRCSTM \->TDIR TDIR\->



1.2   Releasing Notes

      English is not my native language and it was not one of my favourite
      subjects at school. I have done my very best to write this document in
      an understandable form but I might not succeed, so I hope you will
      excuse the simple words I use and any possible mistake or impropriety.

      SmartKeys has been validated on an HP48 revision E. It should work fine
      for HP 48 revisions A through E. It may not work correctly for later
      HP 48 revisions.

      SmartKeys is distributed in the hope that it will be useful; even if
      its commands have been tested (on a HP48 rev E) they make use of
      undocumented features, so use them at your own risk: I take no
      responsibility for any damage caused by their use or misuse.
      The SmartKeys library and this document are Copyright (c) 1992 by
      Simone A. Rapisarda. Non-commercial distribution is allowed and
      encouraged if this document, unchanged, accompanies the unmodified
      library.

      SmartKeys is GiftWare. This means that if after a period of evaluation
      you find it useful and you think I deserve a contribution for all the
      time I spent working on it (not a little, believe me!), feel free to
      send me a gift: cookies, chocolate, cakes, Alka-Seltzer, a 512K ram
      card  etc. ;-). But if you can't afford a gift don't worry; a postcard
      to the following address will be also welcome:

      Simone A. Rapisarda
      via Livia Gereschi 6
      56127  PISA
             ITALY

      If you have comments, suggestions, questions, or criticisms, I would
      really like to receive Email at the following address:

      Simone.Rapisarda@p10.f800.n33.z2.fidonet.org



1.3   Thanks

      - Joe Horn and Detlef Mueller for their precious suggestions.

      - Joe Horn, Flavia Majlis, Pablo Majlis and Roberto Taddei for their
        help in writing the documentation.

      - Flavia Majlis again, who created the nice SmartKeys screen displayed
        by the command ABOUTSK.

      - Rick Grevelle, for his great HACKIT library that helped me a lot in
        developing SmartKeys and discovering most of the HP48 undocumented
        features used in it.

      - Detlef Mueller again, for his programs to handle the Library Data
        objects and for his excellent <-LIB-> library and his fantastic RPL
        library that have saved me a lot of work and time.

      - Most of the entry points used to compile the SmartKeys library are
        documented in a List supplied by Jake Schwartz. I thank him and all
        the contributors to that List.




2  - SmartKeys Commands


2.1   Important Notes

      Please read at least all this chapter before using the library.

      If you aren't familiar with the user keyboard I suggest you first read
      the Paragraph "The User Keyboard" at page 216 of the HP48 manual. All
      of the SmartKeys commands other than the obvious ones have examples
      below.

      - All the SmartKeys commands do complete argument checking and are
        "idiot proof" so it's very unlikely that using them would cause a
        disaster. However, the evaluation of the programs created by the
        \->... commands may be, in some case, catastrophic so always backup
        your memory unless you know exactly what you are doing.

      - If you use the User keyboards then, every time you update to a new
        version of SmartKeys, you MUST execute \<< KBNM \->KB \>> to avoid
        disasterous effects.

      - The built-in commands ASN, STOKEYS, RCLKEYS and DELKEYS are not well
        written. The SmartKeys commands ASNK, DELK and PACKKEYS have been
        written using some contrivances in order to save a theoretical
        maximum of 1470 bytes in each internal UserKeys List. If you want to
        take advantage of this it's best not to use the built-in commands
        ASN, STOKEYS and DELKEYS at all, and use SmartKeys commands
        exclusively.

      - The commands ASNK, RCLK, DELK and STDK(1) support all six possible
        assignments for all keys, except some combinations of the two shift
        keys, obviously.

      - The commands ASNK, RCLK, DELK, DISPK, GETKEYS, PUTKEYS and PACKKEYS
        work only on the current UserKeys List.

      - rc.p represents a Real that identifies a key location: r stands for
        row, c stands for column and p stands for plane.

      - The normal HP 48 keyboard has several keys that behave strangely. For
        example, the CLVAR key (blue-DEL key), has a built-in safety feature:
        it doesn't execute immediately, but instead puts itself onto the
        command line, so that you must then press ENTER if you really want it
        to execute. This allows you to press ATTN to clear the command line
        if you pressed CLVAR by mistake. This is therefore called a "Safe"
        key. SmartKeys allows you to create your own safe key assignments and
        functions. Its own DLUSR command is a Safe command.

      - SmartKeys even allows you to create "Dual" keys and functions, which
        are like Safe keys except that the action performed from the keyboard
        is up to you. Many of the SmartKeys commands are Dual functions; for
        example, ABOUTSK displays an "about" screen when pressed from the
        keyboard; but, when executed from a program (or command line), it
        places the SmartKeys version String on the stack ("1.46").



2.2   Commands in the SmartKeys menu

+---------+-----------+--------------+----------+-------------+------------+
| Page 1  |   Page 2  |    Page 3    |  Page 4  |    Page 5   |  Page 6    |
+---------+-----------+--------------+----------+-------------+------------+
|         |           |              |          |             |            |
| 0 ASNK  |  6 KEYN   | 12 ->IFCMDTE | 18 ->KB  | 24 GETKEYS  | 30 CRCSTM  |
| 1 RCLK  |  7 ADDFR  | 13 ->IFIMMTE | 19 KB->  | 25 PUTKEYS  | 31 ABOUTSK |
| 2 DELK  |  8 ->EVL  | 14 ->IFPRGTE | 20 ->KBN | 26 PACKKEYS |            |
| 3 DISPK |  9 ->PSH  | 15 ->IFALGTE | 21 KBN-> | 27 'BADK    |            |
| 4 STDK  | 10 ->EDIT | 16 ->TDIR    | 22 KBNM  | 28 SAFE     |            |
| 5 RECK  | 11 ->EQW  | 17 TDIR->    | 23 KBMN  | 29 DUAL     |            |
|         |           |              |          |             |            |
+---------+-----------+--------------+----------+-------------+------------+



2.3   Description of each command


+------+
| ASNK |            (ASsigN Key)
+------+            (see example below)

Needs one argument: (1:Any).

Waits for a key to be pressed and assigns the object in level one to that
key. If an object is already assigned to that key, the command LASTARG, if
active, will push to level one the old assignment. ASNK accepts an empty List
instead of the global name 'SKEY' (to force a key to have its standard
definition) in order to save keystrokes.


+------+
| RCLK |            (ReCalL Key)
+------+

Needs no arguments.

Waits for a key to be pressed and recalls to level one the object assigned to
that key. If no object is assigned to that key, the HP48 will just beep.


+------+
| DELK |            (DELete Key)
+------+

Needs no arguments.

Waits for a key to be pressed and deletes the assignment of that key. If no
object is assigned to that key, the HP48 will just beep. If an object is
assigned to that key, the command LASTARG, if active, will push to level
one the old assignment.


+-------+
| DISPK |           (DISPlay Key)
+-------+

Needs no arguments.

Waits for a key to be pressed and displays on the screen the position of that
key, the name of the current keyboard and the six objects assigned to that
key.


+------+
| STDK |            (recall STandarD Key definition)
+------+            (see example below)

This is a Dual command:

(1) When executed from the keyboard:

   Needs no arguments.

   Waits for a key to be pressed and recalls the standard assignment of that
   key.

(2) When executed by a running program (or from the command line):

   Needs one argument: (1:Real).

   Since not all the standard key assignments can be recalled using
   method (1), this second way is provided. The Real on level one must be
   in the same format as required by the built-in command ASN (rc.p). The
   standard assignment of the specified key is recalled to level one.


+------+
| RECK |            (RECord Keys)
+------+            (see example below)

This is a Dual command:

(1) When executed from the keyboard:

   Needs no arguments.

   Records a sequence of two or more standard keys. The only thing that
   distinguishes this recording session from the normal state is the message
   RECK displayed in the status area instead of USER. To finish the recording
   session you need to press [alpha] [CONT] (key 91.5) or cause an Error
   (the key that caused the error will not be recorded). At this point a
   program will be pushed to level one (this will not happen if you have
   recorded only one key. Use STDK for this), that is the record: its
   evaluation will cause the key sequence reproduction; it doesn't need to be
   processed by \->EVL. For a correct evaluation, assign it to a key or store
   it in a Global variable.

   RECK will record every key except those pressed while running a program,
   even the built-in programs, e.g. the EquationWriter, or the standard
   editor. For example, while recording, you can edit something but the keys
   pressed while you are in the editor (*not in the command line*) will not
   be recorded, and the recording session will restart when you exit from the
   editor.

(2) When executed by a running program (or from the command line):

   Needs one argument: (1:List).

   The List must contain more than one Real number in rc.p format: the
   corresponding key sequence will be created on level one as for (1).
   The same limitations as for (1) apply.


+------+
| KEYN |            (KEY Number)
+------+            (see example below)

Needs no arguments.

Asks you to press a key and puts its number in rc format on level one; then
you have to press a key between [1] and [6] (any other key will just beep) to
complete the result with the key plane so that the Real on level one will be
in rc.p format.  This particular method allows you to get the rc.p key number
of any key, including the shifted shift keys.


+-------+
| ADDFR |           (ADD a FReeze command)
+-------+

Needs two arguments: (2:Any, 1:Real).

Every time a program execution finishes, all the display is updated. This
action often wastes precious time. Many programs do not modify all the
display but only a part of it. (e.g. The command SWAP affects only the stack
area and not the status and the menu areas of the display. The program \<<
-64 SF \>> don't affect the display at all). The ADDFR command adds to the
object in level two an instruction that freezes the display areas specified
by the Real on level one. The Real must be used as for the built-in command
FREEZE.


+--------+
| \->EVL |          (-> EVaLuable)
+--------+          (see example below)

Needs one argument: (1:Any).

Leaves on level one a program that when assigned to a key, or stored in a
menu, permits the evaluation of the argument.


+--------+
| \->PSH |          (-> PuSHable)
+--------+          (see example below)

Needs one argument: (1:Any).

Leaves on level one a program that when assigned to a key, or stored in a
menu, pushes the argument unevaluated to the first level of the stack.


+---------+
| \->EDIT |         (-> EDITable)
+---------+         (see example below)

Needs one argument: (1:Any).

Leaves on level one a program that when assigned to a key, or stored in a
menu, inserts the argument in the Command Line at the position of the cursor.


+--------+
| \->EQW |          (-> evaluable also in the EQuation Writer)
+--------+          (see example below)

Needs one argument: (1:Any).

It's a more powerful version of \->EVL: the object processed by this command
and assigned to a key can be executed also while the Equation Writer is
active; but remember, the stack *must* always be leaved intact by the
operation. The only part of the display that can result affected by such
operation is the menu bar.


+------------+
| \->IFCMDTE |      (-> IF CoMmanD line exist Then Else)
+------------+      (see example below)

Needs two arguments: (2:Any, 1:Any).

Leaves on level one a program that when evaluated will:
- Check if there is a Command Line.
- If yes, evaluate the level two argument.
- If not, evaluate the level one argument.
The resulting program doesn't need to be processed by \->EVL.


+------------+
| \->IFIMMTE |      (-> IF IMMediate-entry mode Then Else)
+------------+

Needs two arguments: (2:Any, 1:Any).

Leaves on level one a program that when evaluated will:
- Check if the HP48 is in Immediate-Entry Mode.
- If yes, evaluate the level two argument.
- If not, evaluate the level one argument.
The resulting program doesn't need to be processed by \->EVL.
For informations on Entry-Modes see the HP48 manual at page 76.


+------------+
| \->IFPRGTE |      (-> IF PRoGram-entry mode Then Else)
+------------+      (see example below)

Needs two arguments: (2:Any, 1:Any).

Leaves on level one a program that when evaluated will:
- Check if the HP48 is in Program-Entry Mode.
- If yes, evaluate the level two argument.
- If not, evaluate the level one argument.
The resulting program doesn't need to be processed by \->EVL.
For informations on Entry-Modes see the HP48 manual at page 76.


+------------+
| \->IFALGTE |      (-> IF ALGebraic-entry mode Then Else)
+------------+

Needs two arguments: (2:Any, 1:Any).

Leaves on level one a program that when evaluated will:
- Check if the HP48 is in Algebraic-Entry Mode.
- If yes, evaluate the level two argument.
- If not, evaluate the level one argument.
The resulting program doesn't need to be processed by \->EVL.
For informations on Entry-Modes see the HP48 manual at page 76.


+---------+
| \->TDIR |         (-> Temporary DIRectory)
+---------+         (see example below)

Needs two arguments: (2:List, 1:Real).

The List on level two can be either a complete menu List or a List containing
a String and one, two or three complete menu Lists.
In the first case \->TDIR creates a key assignment that once evaluated will
display the menu specified by the argument.
In the second case \->TDIR creates a menu entry identified by the String as a
dir-like menu label, and whose functions (unshifted, left-shifted and right-
shifted) are specified by the other List/s.
The Real on level one determines if the menu/s diplayed affects the content
of the last-menu. If the Real is 0 the content of the last-menu is not
affected (as for the MTH and PRG menus).


+---------+
| TDIR\-> |         (Temporary DIRectory ->)
+---------+

Needs one argument: (1:List).

This is a command to reverse the operate of TDIR\->. It does complete
error checking so an invalid List will cause a "Bad Argument Value" error.


+-------+
| \->KB |           (stack TO userKeyBoards)
+-------+

This is a Safe command:

Needs one argument: (1:List) / (1:Library Data)

If the argument is a List:
It creates as many User Keyboards as specified by the dimension of the List.
The only limit to this dimension is the amount of available memory. The
memory occupied by an empty UserKeys List is about 60 bytes. The first object
of the List is used to name the current User Keyboard. The other objects are
used to name the other keyboards. If a name already exist, the corresponding
keyboard is used instead of a new one. This was done to help the user to
reorganize the keyboards, delete the unneeded ones, add new ones, reorder and
rename them.

If the argument is a Library Data object:
the Library Data object must be the one created by KB\->. It replaces all the
UserKeyboards with the ones archived in the Library Data object.


+-------+
| KB\-> |           (userKeyBoards TO stack)
+-------+

Needs no arguments.

Recalls the UserKeyBoards as a Library Data object and pushes the Real 1 on
the stack to say that the operation succeed. If there aren't UserKeyBoards
the result will be only a Real 0.


+--------+
| \->KBN |          (stack TO userKeyBoard Number/Name)
+--------+

Need one argument: (1:Real) / (1:String)

Activates the specified User Keyboard. The same result can be obtained by
pressing the corresponding named key in the User Keyboards Menu displayed by
KBMN. If USER mode is not active, \->KBN activates it. For a faster execution
you should consider to use a Real instead of a String.


+--------+
| KBN\-> |          (userKeyBoard Name&Number TO stack)
+--------+

Needs no arguments.

Recalls the number of the active User Keyboard and tags it with its name. If
there is only one User Keyboard, the result will be a zero tagged with the
String "Undefined".


+------+
| KBNM |            (userKeyBoards NaMes)
+------+

Needs no arguments.

Creates an ordered List containing all the names of the User Keyboards. If
there aren't User Keyboards the result will be an empty List.


+------+
| KBMN |            (userKeyBoards MeNu)
+------+

Needs no arguments.

Displays, if present, the User Keyboards Menu created by the command \->KB.
This is a normal menu, similar to the MODES one. It allows you to switch
easily and rapidly between all the user keyboards you have created. If USER
mode is not active, KBMN activates it. The menu displayed by KBMN behaves
in two different ways depending on the state of the user flag 50. If this
flag is clear the menu behaves as a normal one, if this flag is set the menu
is available only for one choice: after you have activated another keyboard
the last menu is automatically redisplayed.


+---------+
| GETKEYS |         (GET userKEYS)
+---------+

Needs no arguments.

Pushes to level two the current internal Userkeys List and to level one the
Real 1 if unassigned keys are active or the Real 0 if unassigned keys aren't
active. For informations on the format of the internal Userkeys List refer to
the paragraph 4.1 of this document.


+---------+
| PUTKEYS |         (PUT userKEYS)
+---------+

Needs two arguments: (2:List, 1:Real).

Stores the List on level two as the current internal Userkeys List and the
Real on level one as the state of unassigned keys: 0 stands for "inactive",
any other stands for "active". PUTKEYS does a complete argument checking on
the List so to prevent a disaster.
For information on the format of the internal Userkeys List refer to the
paragraph 4.1 of this document.
NOTE: If you implement PUTKEYS with a 0 on the first level, your keyboard may
       result locked up. To recover from this situation just press ON-C and,
       if the user flag 49 is set, press ATTN exactly when the screen
       reappears.


+----------+
| PACKKEYS |        (PACK userKEYS)
+----------+

Needs no arguments.

Packs the user key assignments into their most compact form to save memory.
As user key assignments are made or deleted (using the built-in commands ASN,
STOKEYS, DELKEYS) a certain amount of memory is wasted. You can free this
memory for other uses by packing the user key assignment with PACKKEYS (The
SmartKeys commands don't need PACKKEYS to be used).
Note: The command sequence described in the HP48 manual at page 220 (RCLKEYS
      0 DELKEYS STOKEYS) has a little bug/feature: in case that unassigned
      keys aren't active, after its execution they will be reactivated.
      The command PACKKEYS, instead, do not change the unassigned keys state.
      It also packs the user key assignments in a more compact form almost
      immediately.


+-------+
| 'BADK |           (push doBADKey)
+-------+

Needs no argument.

Pushes on the stack the sys-RPL instruction DoBadKey that is normally
associated to all disabled keys. When evaluated it just beeps and freezes the
screen.


The following two commands are not inherent with the User Keyboard but as
they provide two "smartkey" capabilities, they were included anyway. For
system-RPL programmers they are also provided in XLIB versions that don't do
argument checking. Note that the internal SAFE uses the internal DUAL.
The internal SAFE and the internal DUAL can be extracted and used in other
libraries only if these are Public Domain, Freeware or Giftware. This can be
done only with my consent and their use must be reported in the documentation
of the library.


+------+
| SAFE |            (SAFE execution)
+------+            (see example below)

Needs two arguments: (2:Any, 1:String).
It allows the use of the Safe capability in user programs.
It uses DUAL to put the name of the program in the command line if the
program is executed directly; otherwise, the level two argument is executed.
As for DUAL, the String on level one must contain the name of the program.


+------+
| DUAL |            (DUAL execution)
+------+

Needs three arguments: (3:Any, 2:Any, 1:String).
It allows the use of the Dual capability in user programs.
If the user program is executed directly, DUAL evaluates the argument in
level two, otherwise, if the program isn't executed directly, the level
three argument will be evaluated. The String on level one must contain the
name (Global or XLIB) under which the program is stored.


+--------+
| CRCSTM |       (CReate CSTM variable)
+--------+       (see example below)

Needs one argument: (1:List)

It's a custom-menu enhancer and is not directly inherent with the User
Keyboard, however, as all the SmartKeys commands, it can be considered as a
customization command.
CRCSTM considerably enhance the custom menu so to support tree-structured
menus and library menus in a really handy way. The new custom menus differs
from the old ones only by the following things:

- Each Real number present in the menu List as a menu entry (= not embedded
  in another List) is displayed as a dir-like menu label containing, if
  exist, the title of the library with that ID. The menu entry, once
  evaluated, will display the menu of that library (as the built-in library
  menu does).

- Each String present in the menu List as a menu entry (= not embedded in
  another List) is displayed with a dir-like menu entry that once evaluated
  will search in all the path for a Global variable named in the same way,
  if it's present and it contains a List then this List is displayed as
  a menu with the same capabilities as this one.
  So you can have a really big custom menu but modifiable by editing only a
  single part of it and not all as usual.

Here is exactly what CRCSTM does:
It stores the List in the current directory as a Global variable named CSTM
and overwrites the content of the Global variable CST in the home directory
with a special custom-menu List. The old content of CST, if it exist, can
be recalled by the LASTARG instruction.
So to edit or modify your main custom menus you must refer no more to the
Global named CST but to the one named CSTM.

The only suggestion for a faster access to these new menus is to use tree-
structured but short menus (one or two pages) instead of flat and long menus.


+---------+
| ABOUTSK |      (ABOUT SmartKeys)
+---------+

Needs no arguments.

This is a Dual command:

(1) When executed from the keyboard:

   Shows the library version and a copyright message.

(2) When executed by a running program (or from the command line):

   Puts on level one the version String of the library (so SmartKeys based
   applications can prevent errors).


+---------+
| $CONFIG |      (hidden command)
+---------+

Needs no argument.

It's automatically executed after every warm-start (ON-C).
It checks if the user flag 49 is set; if yes, it sets the system flags -61
([USR] once to lock) and -62 (User Mode active). So if you use permanently
the User Keyboard, set flag 49 and the user keyboard will be always active.
This hidden command gives you also the possibility to reconfigure your
calculator after a warm-start: if you store a program in a Global variable
named CONFIG and contained in the Home dir then it will be automatically
executed just after the warm-start.




3  - Commands Usage Examples
     -----------------------

The following simple examples demonstrate some possible applications of some
of the SmartKeys commands.



3.1   Commands used: \->IFPRGTE ASNK

      When not in Program-Entry Mode the command SWAP is usually executed
      pressing [ > ]  (key 36.1) so the combination [orange shift]   [ > ]
      serves no purpose.
      Now you can assign to [orange shift]  [ > ] a program that, when in
      Program-Entry Mode, will insert SWAP in the command line as usual but
      when in Immediate-Entry Mode will implement an OVER.

        _________________________            _________________________
        |{HOME}                 |            |{HOME}                 |
        |-----------------------|            |-----------------------|
        |4:                     |            |4:                     |
        |3:                     |            |3:                     |
        |2:                 SWAP|            |2:                     |
        |1:                 OVER|            |1:                     |
        |### ### ### ### ### ###|            |### ### ### ### ### ###|
        `-----------------------'            `-----------------------'
      1) Enter the List { SWAP             2) Implement \->IFPRGTE to
         OVER } and Implement OBJ\->          obtain the new assignment.
         followed by DROP to obtain           Implement ASNK and press
         the two command unevaluated.         the [orange shift]  [ > ]
                                              key to assign it to that key.



3.2   Commands used: STDK \->IFCMDTE ASNK

      The [DEL] key serves no purpose when there isn't a command line.
      Now you can assign to it a program that when the command line is not
      present will execute LASTARG, otherwise it will behave like the normal
      [DEL] key.

        _________________________            _________________________
        |{HOME}                 |            |{HOME}                 |
        |-----------------------|            |-----------------------|
        |4:                     |            |4:                     |
        |3:                     |            |3:                     |
        |2: External External ..|            |2:                     |
        |1:              LASTARG|            |1:                     |
        |### ### ### ### ### ###|            |### ### ### ### ### ###|
        `-----------------------'            `-----------------------'
      1) Implement STDK and press          2) Implement \->IFCMDTE to
         [DEL] to recall the key              obtain the new [DEL] key
         routine. Enter the List              assignment. Implement ASNK
         { LASTARG } and implement            and press the [DEL] key to
         OBJ\-> DROP to obtain the            assign the program in level
         LASTARG command.                     one to it.



3.3   Commands used: KEYN RECK ASNK

      Usually in order to enter a String you need to use the alpha keyboard
      so every time it takes four (or three) keystrokes:

      [blue-shift]   [ - ]   [alpha]  ( [alpha] )

      Now you can assign to the key [blue-shift] [ - ] a program that
      automatically enters the alpha keyboard.

        _________________________            _________________________
        |{HOME}                 |            |{HOME}                 |
        |-----------------------|            |-----------------------|
        |4:                     |            |4:                     |
        |3:                     |            |3:                     |
        |2:                     |            |2:                     |
        |1:        { 85.3 61.4 }|            |1:                     |
        |### ### ### ### ### ###|            |### ### ### ### ### ###|
        `-----------------------'            `-----------------------'
      1) Enter an empty List, then         2) Press [ENTRY], [RECK] and
         implement KEYN and press             [ENTER] to convert the List
         [ - ] and [ 3 ] so to obtain         on level one to the
         the Real number 85.3, press          corresponding keys sequence.
         [ + ]. Press the key [alpha]         Finally implement ASNK and
         and [ 4 ] so to obtain the           press the [blue-shift] [ - ]
         Real number 61.4, press [ + ].       key so that the program
                                              in level one is assigned to
                                              that key.



3.4   Commands used: \->PSH \->EVL \->IFPRGTE \->EDIT \->IFCMDTE

      Now it's time to build yourself the silliest key assignment ever seen:

      It checks if there is the command line and:
       - if not, it will start the command line with the String "STARTcmd".
       - if yes, it checks if Program-Entry Mode is active and:
               - if yes, it will push to the first level the String "PRGon".
               - if not, it will evaluate the program \<< "PRG" "off" + \>>.

        _________________________            _________________________
        |{HOME}                 |            |{HOME}                 |
        |-----------------------|            |-----------------------|
        |4:                     |            |4:                     |
        |3:                     |            |3:                     |
        |2:                     |            |2:              "PRGon"|
        |1:              "PRGon"|            |1:\<< "PRG" "off" + \>>|
        |### ### ### ### ### ###|            |### ### ### ### ### ###|
        `-----------------------'            `-----------------------'
      1) Enter the String "PRGon"          2) Enter the program \<< "PRG"
         and implement \->PSH to              "off" + \>> and implement
         make it pushable.                    \->EVL to make it evaluable.

        _________________________            _________________________
        |{HOME}                 |            |{HOME}                 |
        |-----------------------|            |-----------------------|
        |4:                     |            |4:                     |
        |3:                     |            |3:                     |
        |2:                     |            |2: External External ..|
        |1: External External ..|            |1: "STARTcmd" Externa..|
        |### ### ### ### ### ###|            |### ### ### ### ### ###|
        `-----------------------'            `-----------------------'
      3) Implement \->IFPRGTE.             4) Enter the String "STARTcmd"
                                              and implement \->EDIT to
                                              make it editable.

        _________________________            _________________________
        |{HOME}                 |            |{HOME}                 |
        |-----------------------|            |-----------------------|
        |4:                     |            |4:                     |
        |3:                     |            |3:                     |
        |2:                     |            |2:                     |
        |1: External External ..|            |1:                     |
        |### ### ### ### ### ###|            |SILLY #################|
        `-----------------------'            `-----------------------'
      5) Implement \->IFCMDTE to           6) I don't think you want to
         obtain your brand new                waste a key for such a
         smart key.                           stupid assignment so:
                                              Enter the String "SILLY",
                                              implement SWAP 2 \->LIST 1
                                              \->LIST to store the program
                                              and the String in a menu
                                              an finally implement TMENU.



3.5   Command used: \->TDIR

The following program, once downloaded to a 48 and evaluated will put two
silly menu entries on the stack. Implement \->TDIR on each one to obtain
two dir-like menu entries, finally execute 2 \->LIST TMENU and give a look
at the menu that will be displayed.


%%HP:;
{                   @ begin 1st menu entry
"NUMB"              @ the 1st menu label
{ 1 2 3 4 5 }       @ the menu displayed by the 1st unshifted key
{ -1 -2 -3 -4 -5 }  @ the menu displayed by the 1st left-shifted key
}                   @ end 1st menu entry
{                   @ begin 2nd menu entry
"ALPHA: Alphabet"   @ the 2nd menu label
{ A B C D E F G H } @ the menu displayed by the 2nd unshifted key
{ I J K L M N O P } @ the menu displayed by the 2nd left-shifted key
{ Q R S T U V W X } @ the menu displayed by the 2nd right-shifted key
}                   @ end 2nd menu entry



3.6   Command used: SAFE

      The following is a Safe program that purges the graphic display:

      %%HP: T(3);
      \<<
      \<< PICT PURGE \>>   @  The 'dangerous' code.
      "PPICT"              @  The name used to store the entire program.
      SAFE
      \>>

      Download (or type in) this program and store it with the name 'PPICT'.



3.7   Command used: CRCSTM

      Store your home-dir custom menu in a Global variable named 'CUSTOM'
      and download (or type in) the following List:

      %%HP: T(3);
      {  "CUSTOM"  1616  { "CUST" "CUSTOM" }  { 1616 1616 }  }

      Now implement the command CRCSTM and press the CST key. You will see
      four menu labels, the first enters your old custom menu, the second
      displays the SmartKeys menu, the other two are normal menu labels.



As you can see, the examples are finished, now it's up to you...




4  - Some useful informations
     ------------------------


4.1   The Internal UserKeys List

When no key of the user keyboard is assigned, the internal UserKeys List is
empty. When one or more assignments are active, the internal UserKeys List
contains fortynine Lists, each of these can be an empty List (if the key have
no assignments) or a six element List (if the key have one or more
assignments). Each of these six elements is the object assigned to the key
(unshifted, left-shifted, right-shifted, alpha, etc.) or an empty List if
that key has no assignments.

Example: Assuming that no key of the user keyboard is assigned, when you
         assign the command % to the key DEF your internal UserKeys List will
         look like this:

         { {} {} {} {} {} {}
           {} {} {} {} {} {}
           {} {{}%{}{}{}{}} {} {} {} {}
           {} {} {} {} {} {}
           {} {} {} {} {}
           {} {} {} {} {}
           {} {} {} {} {}
           {} {} {} {} {}
           {} {} {} {} {} }



4.2   Unused and Useless HP48 Default Key Assignments

In order to take full advantage of the SmartKeys library you may want to know
what the gaps in the HP48 default key assignments are, so you can fill them
with your own key definitions. If so, the following table will help you.


          +-----------------------------------------------------+
          |UNUSED AND USELESS HP48 DEFAULT KEY ASSIGNMENTS v 1.1|
          +-----------++---------------------++-----------------+
          | ENTRY     ||        UNUSED       ||   ? USELESS ?   |
          | MODE      ||------+--------------++---------+-------+
          |           || NUMB |  SPECIFICAT. || NUMBER  | SPECS |
          +-----------++------+--------------++---------+-------+
          | IMMEDIATE || 25.3 | BlShft-up    || 34.1or2 | GRAPH |
          | ENTRY     || 34.3 | BlShft-left  || 36.1or2 | SWAP  |
          | MODE      || 36.3 | BlShft-right || 55.1or2 | DROP  |
          | &  NO     || 51.4 | alpha-ENTER  || 91.2or5 | CONT  |
          | COMMAND   || 54.1 | DEL          || 91.3or6 | OFF   |
          | LINE      || 54.4 | alpha-DEL    || 92.3    | \->   |
          |           || 55.4 | alpha-BckSpc || 93.2    | ,     |
          |           || 62.5 | ` accent     || 93.3    |  <-'  |
          |           || 62.6 | ' accent     || 94.1    | SPC   |
          |           || 63.5 | ^ accent     || 94.3    | \<)   |
          |           || 63.6 | ~ accent     ||         |       |
          |           || 64.5 | " accent     ||         |       |
          |           || 64.6 | etc. accent  ||         |       |
          +-----------++------+--------------++---------+-------+
          | IMMEDIATE ||      |              || 34.2    | GRAPH |
          | ENTRY     ||      |              || 36.2    | SWAP  |
          | MODE      ||      |              || 55.2    | DROP  |
          |   &       ||      |              || 91.2or5 | CONT  |
          | COMMAND   ||      |              || 91.3or6 | OFF   |
          | LINE      ||      |              || 92.3    | \->   |
          |===========||======|==============||=========|=======|
          | PROGRAM   || 52.3 | VISIT        || 51.2or3 | DUP   |
          | ENTRY     || 53.2 | 2D           || 91.2or5 | CONT  |
          | MODE      || 53.3 | 3D           || 91.3or6 | OFF   |
          |           || 62.3 | solver       ||         |       |
          |           || 64.3 | eq catalog   ||         |       |
          |           || 72.3 | alrm catalog ||         |       |
          +-----------++------+--------------++---------+-------+



4.3  Another suggestion for keys-hungry HP48 users

The following method is somewhat tricky and requires a little of familiarity
with system-RPL but will allow you to gain four unshifted 'keys' and a lot
of shifted keys on your user keyboard.

If you press the key MTH, PRG, CST or VAR the corresponding menu will be
displayed, but now you will not need that key any more (until that menu
will be displayed) so you can use this key for your own purpose.
To do this you have to assign to it a simple system-RPL program that
will check if the menu is displayed, if not it will display it, if yes it
will do something else (the best thing would be to display another menu).

Examples: 1) I use frequently the library menu and I don't like to press two
             keys to reach it so I created an assignment for the key CST that
             allow me to toggle between the two menus as described by the
             following scheme:

                                      +--->>--- CUSTOM menu ---->>---+
                                      |                              |
                                 Press [CST]                    Press [CST]
                                      |                              |
                                      `---<<--- LIBRARY menu ---<<---'

             If I press [CST] once the Custom menu will be displayed but if I
             press it twice the Library menu will be displayed (and so on).

             It follows the system-RPL program in ASC format.

%%HP:;
"D9D20A5804432B34A8143A4467A226B58147A22664B308DA16F6EA327BA3AC1A
3B2130A1D7"


          2) It's common knowledge that libraries are better than directories
             and so, when it's possible, I use libraries, but in many cases I
             can't. For this reason my dir-tree is somewhat impressing. Every
             time I move into it I hate to press [orange-shift] [UPDIR] or
             [blue-shift] [HOME] so I've tried to find a solution to this.
             The following two programs work like the preceding one but
             instead of toggling between two menus they toggle between a
             menu and an instruction. The way to implement this is more
             tricky but as in the preceeding example the resulting programs
             are easily modifiable.

             The following program must be assigned to the MTH key.
             It toggles between the MTH menu and the UPDIR instruction.

%%HP:;
"D9D20A5804432B34A8143A44698226DA916D9D2075DA3AC1A3B213079E60B51A
15E4049B314AC1A3B2130CADF"

             The following program must be assigned to the PRG key.
             It toggles between the PRG menu and the HOME instruction.

%%HP:;
"D9D20A5804432B34A8143A44635040A3D36D9D20A1EA3AC1A3B213079E60041A
15E4049B314AC1A3B21307CAD"




                       <><><><><><><><><><><><><><>



Happy Assigning


                                                  RAP

END_DOC


BEGIN_ASC SmartKeys.asc
%%HP:;
"04B20793205135D445B4A30235D6162747B4569737026713E243635105687020
0000006F1050000D9D2068F4690770E0CC0AFBC03392059900000000000100A6
A279E60D9D20AEC81F67E0B2710461E0E3424B213044B46877358DA16D9D2079
E60D9D20CBB46137356CB4613735B2130F125018A30B21300CA3079E6084E206
034F4E4649474A6AE28DA16D9D207EE06AF2508D1F4B21300CA3057B30DA916B
4F064B2A2DE6E044230B2130D9D20BEE6029E2005623056F1493D04F3F14EF11
6CA1306B65006916C1216CA1306B650DA916B4F06D123639916E7F0618A30B21
30D9D20C2A2032000A3A005275637370247865602B45697BBCA14D974B4916C0
7211359358B934A093B2130D9D20D9D2051B50B7970DA9169E550112268E8169
E550D1236B3A1614C2662E263C3701F036D9D20D9F81D0040D9D2079E60B6DE3
2C230BFF3679E60A58045923079E6029E20056130D0040544509B136B21309FF
30D9D2079E60B6DE32C230AEC819B1808DA169EB50FD550BFF3679E60A580459
23079E6058CE379E60A65F379E608E1A379E60EE193B2040544509B136B2130F
EF30E8E60B2130D44365A136B213058CE30CD048E1A3B2130D9D2079E60A5804
3223079E600CD0479E608E1A36B3168DA1671040D9D2079E6058CE312040B213
054450B2130D9D2014C264B636CB916D9D20E0E303223079E6058CE33FD362AC
814B2A20E516B21307104091D3091B3679E608E1A33FD362AC8179E600CD043F
D362AC813223079E60A58043FD362AC81B2130D9D2079E60D9D2058B9328A045
2604335115E0936C193B21303223029E20056320B2130D9D20F3F14D1236B491
6FA4503C370D12368DA16D9D20442309E550B2130D9D20FA4503C370D1236A21
70C5170442309E550AF01643370B204095450881309E550DCE144AC369E550B2
13044B46E93304337044B46954509E550C8E142C2303FD3623E14442309E5502
3E14B2130D9D20E4B4687735CB916D9D20EF6A3AC1A3B213029E20056A20B213
0D9D2079E6084E204022B424E6B2130D9D2047A20D6E201022B21300D4700A04
6EB04629E2005682050C264423088B2614C26A6526D6E20102229E20056B2050
C2644230CAF0672D700ED3034A1457FF39B13632230E933088130A6526D6E201
022CC21688B268DA1668FF379FF325F148813044950B9F06F5A1472D7093A147
2D7034A14C2F14954509B1363223072D70AF04679470B2130D9D2029E20056B2
0320464423091D3099CE3B2130D9D2079E6084E203022B424B2130D9D2079E60
A1EE3FA45008826BEE604C01654450CAF0629E2005642030040B2130D9D202C2
30B204038D302C230D004038D30CB926A1BF332230B0A4047A20439144591447
914B213079E60BF70451036C9B26D004054450B2130D9D2029E2005682088130
32046069169805029E20056220C804629E20056B20C8046B2130D9D20053912C
230CE12616E36FA4509FF30BEE60CBD3054450B2130D9D208AA04F1916E8F602
8A0431B5179B30C5F26D6A16B2130D9D209E5502C2304A8144C53685A1668F04
4F914EFC36B9314B2130D9D20FA45090826EC3701F0369805030040C9B26D443
65A136B2130D9D2088B26FA4509082629E20056B2032046442300ED30F3F1457
FF39B136322305631695450B21308056F10D9D20E1A81C2A20D000013E243637
9E60D9D20C2A20B20003596D6F6E6560214E2022516079637162746163FC1171
04039140C2A205200034F405952594748445029A021393932300D1171040B114
0C2A20D10006554253594F4E40213E2436308F1107C4699040E1B207B000C000
07300000000002600000000000027000000000000A10000016C1F9FE0F56E337
E3F9F6804610E536122E8F46F3C414D32A9046F316D59122BF560216D513226F
93F1000000000002000000000000F3000000000000E100DA040F3040E1B20B70
00210003100000006000087000070000C0000830000F0000C30040C00040DFFF
409FFF50000850000E5000870000E000081000070000F00000300000FEF30120
40D2B93FEF30B7040D2B93FEF301704053040D6F10BD37055621CAF069761143
370F2293B2130C2A20310001424F4554535B429E20056320B21308056E10D9D2
0ECE8112040D9D2079E6084E2040343545D47C58172D7047A20D9D20BF704C2A
20D0000343545D429E2005613079E60B93144C9149024614A404091454621B21
30B2130DEE3279E604B11250C26CB916D9D202BA8144230B2130A5D80CAF0629
D8072D7080D80B2130B21308056D10D9D200FE81D004029E20056320B2130805
6C10D9D20FDE81D004029E20056E20B21308056B10D9D20E1A81EFDF3B213080
56A10D9D20E1A8129E20056D20B21308056910D9D20FDE81E3C46D9D20747261
4C2644B46D2C26D9D203C370B7650B2040BE026322306AC3057B3091B3643370
18A30B21306AC3091B3623E14B67A28DA1679FF368FF3B2130B21308056810D9
D20E1A81F3F148813044950B9F067304696A144C536CB916D9D209E550038262
3E14B213057FF3E0835B21308056710D9D20E1A8129E2005682032046C2A1698
05068F04AC1A36CB4613735B21308056610D9D20E1A8129E2005682032046DA9
169E5509805029E20056120B21308056510D9D20E1A8129E20056B2032046DA9
16D9D204B2A2B775618E50B213088130FBD8129E2005682032046D713659230C
9B269805030040C9B2618E50B21308056410D9D20ECE819FF30D9D2011CE229E
200568203204606916FA45062726B7650D2E30CD636B463655C2691B3629E200
56A206CB4613735B2130D0040D9D2029E2005682032046069169805029E20056
120322303A446198162AC8129E20056A206CB4613735B2130B21308056310D9D
20E1A81119200560029E20056820320468E8164B2A229E20056020DC13688130
20950A1626CCD20030008F146608FB97601471353488B201451741418D341509
C2A2B21308056210D9D20E1A8179E60D9D202BA81D9F8112040D9D20D12367F8
1629E200565201E13629E20056820320468DA16D9D2029E200560207472629E2
005622029E20056120B2130D9D20F3F1457FF39B136DEE322C230EB11645126A
217031B515D04095236DEE32B213057726A6526322303C3701F03645126A2170
31B515D04095236FDE263A4465CE3647A209E55018A30B2130D9D203FE26D1D2
6B21304C01666436A2116A062695450CAF0688B268DA1668FF379FF323E1414C
265C22639916D9D20E7F0629E20056520B2130FED30FC436BD37079E60887046
B3165233045126A217031B515D040952361227079E6029E20056920710405445
079E60A58041227079E6029E20056C2079E60AC1A379E60EE19312040544509B
136433706B4365A136322309B13629E20056820870469FF3029E20056B208704
6B213096DC1D9D2075660CCD20030008FB97601431313447A201451743411920
1458D34150FA4505233068F463FD362AC81881309805088B268DA1668FF379FF
323E14351509B13629E200568208813032046CB916D9D209805029E20056220B
2130870469FF3029E20056B2087046B2130B2130C2A20B0000D8B42429E20056
E20B21308056110D9D20ECE8112040D9D20D123650B36FA4508C63650B363223
07E12691B36FA4508C63650B363223079E60B6DE33FD362AC81322307E126CB9
16DEE321122691B3614C26D004038D3050B36B463650B36908269C2A2FC436EC
3701F0367E12691B3629E20056F20D4436954506B436B2130F3040D9D209C2A2
FC43629E20056F206B436B2130B21308056010D9D20FDE81E3C46D9D20FC7A2F
C436D123650B36881309805095126DA916D9D2029E2005603079470B2130FA45
05C22650B369BC267104038D3050B36EC3701F0361122691B3629E20056030D4
4367947088130A922685A165A13679E60B6DE359230BFF36322309B136B2130B
21308056F00D9D2008A8129E2005672086935B21308056E00D9D2008A8179E60
A1EE3CAF0629E2005642030040B21308056D00D9D2008A8129E20056720AA804
B21308056C00D9D2008A8129E20056720A4A35B21308056B00D9D205AA8179E6
0A58043223029E200564209FF3079E60AC1A3AF250B21308056A00D9D205AA81
8804179E60887043223079E609A404D004054450B21308056900D9D205AA8179
E60BF70432230BFF36B21308056800D9D205AA8179E60887043223029E200564
209FF30B21308056700D9D2008A81D2B3647A203D393A8193E9193154936C193
2B193EE193B213033F0629E20056420FEF30CAF06898D1AF250B21308056600D
9D20E1A8179E6029E2005660029E200562306DA35951248DA1644EF3D9D20262
24DA9164AE405F02444230B21309FF3029D148B261710409523692A36DF550DA
B9344230BD9450BB269FF30C58615E3212A17047A209814039140D9140751401
6140B6140B21306DA3595124A2170D9D2026224DA9164AE405F02444230B2130
3A4465CE36D9D201DDF3C0126B213018A308C1704E761BD94549326731417947
071193B21308056500D9D20E1A8179E60D9D202BA81577461122664B36FA450D
F550747260F63691B36BD37079E6079E605923057746D2B362AC1429E2005662
079E604540479E601A6838DF06FA450A7526544504337079E60887045F136B9F
0654450B213079E60D9D20AB593DAB9379E60A580447A20D6E201008B21300D4
702A170C2A20D0000255434B408F1155621E3C46FEF309761156F14CA1301204
0E4D3032230C1B46E4D3057B30EE170D9D20A1BF3D6E20100879E6079E60AF25
02C230AF25079E6045404AF25079E601A683AF25079E60D6E201008B1D70E5E4
0454048BE40D9D2093D04D6E201008FA450AF01627F06A162654450132367104
038D30CB91651A811DE40B21301A683B21305E1708523093D04D6E2010087947
0FA450B9F06E0E3054450132367104038D3006916B2130C2A20D0000255434B4
29E20056320B21308056400D9D20E1A8179E60D9D202BA8157746D2B362AC14B
213079E60D9D2028A0429E2005623056F1493D04B2130C2A20D0000354544B42
9E2005632029E20056620B21308056300D9D20E1A8179E6029E2005630029E20
05623071193F3F146DA35951248DA1644EF3D9D2026224DA9164AE405F024442
30B213088A3629D14AEC814E761C2A20D0000B4569702FE226C2A20D000002F6
660229E200565107CE5032230AEC814E761DB41439150FE2263915039150B542
16B650A21709E55053040EC37012270CA1306B650A21709E550D12368DA16D9D
2044230B7756B2130471512C2304E761DB41439150FE22640926924214337044
230B129315493B21308056200D9D20E1A8129E2005633029E20056200019161D
DF32BA81442309E55033F0600CD133F0600CD123E148523029E20056D20B2130
8056100D9D20E1A8129E2005633029E20056100019161DDF34CB2666F06B2130
8056000D9D205AA8179E60FCAF3CA13079B30EF1167B55057B30C5F2629E2005
633029E20056000CB916D9D202BA8127F06B2130F3F14D1236CB916D9D204423
09E550C8E14B213088130C1216C9B26D1236CB916D9D20442309E550DCE14B21
308DF061003600CD1CAF0600CD123E14B2130E4A209010081FFF3DEFF06EFF3E
CFF45CFFAC9FF278FF108FF7C7FF897FF557FFC07FF1E6FF6B6FFC76FF156FF7
65FFB44FF7C0FFF20FF15FEFBCEEF68EEFD3EEF7DDEFA3DEF41DEF4FCEF9CCEF
E9CEF7BBEF919EFCB8EF088EF448EFD08EF1D7EF387EFB07EF4C6EF3A6EF576E
FE55EFB35EFEF4EFD14EF1D3EF133EF2D2EF371EF911EFAA0EFE4A200E200000
0000000B4000C5000A1100F6100B7100FA100000000000000000000000000000
0000000000000BE10030D8B42421030B424D8310401435E4B4000402534C4B41
00404454C4B420040354544B440040255434B450040B45495E460040D85465C4
80040D805358490040D8541575B0040D8B424E441040B424E4D851040B424E4D
461040B424D4E47104035146454C1040445514C4D105044943505B4300501444
44642570050D854449445A0050D8454494250105045449425D8110504B241444
B4B10603425343545D4E1070745445B454953581070055545B45495359107014
24F4554535B4F1080D8946434D4444554C0080D8946494D4D44554D0080D8946
40525744554E0080D8946414C4744554F0080051434B4B4549535A100D1008C1
000C100C1100DB1005B100DA10012100AA1002A10012100F91005A0005900058
00057000031006210004200A3200FB1007B100FA1007A100A1100C0100790009
41003B100BA1009410071100AEB7626A"
END_ASC

BEGIN_UU SmartKeys.uue
begin 644 SmartKeys.bin
M2%!(4#0X+45`*W`Y`A53351+.B!3;6%R=$ME>7,@=C$N-#854(8'`@```/8!_
M!0#0V0*&3Y9P!P[,H+\,,RE0F0``````$`!J*I=NT-D"ZHSQ=@XK%T`6#CXDC
MM!(#1$N&=U/8&M;9`I=NT-D"O$L6<U/&2Q9S4RLQ\"$%@3JP$@/`.G#I!D@N,
M8##TY&24=*2F+M@:UMD"YPZF+P78\;02`\`Z4+<#K1FV]&"THM)N#D0RL!(##
MG2VP[@:2+@!E,E#V03D-]/-!_A'&&@.V5@"681P2QAH#ME;0FF%+#]8A8Y,9W
MYO=@@3JP$@.=+<"B`B,`H*,`)5<V-P="AU8&LE26M\L:U'FTE&$,)Q%3.86;$
M0PHY*S'0V0*=+5"Q!7MYT)IAZ540(6+H&)9>!1TRMJ-A02QFXF+#<Q`/8YTM(
MT/D8#4#0V0*7;K#6/L(RL/]CEVZ@A4"5,G#I!I(N`&4QT``$1520&V,K,9#_T
M`YTM<.D&:^TC+`/JC)$;"-@:EKX%WU6P_V.7;J"%0)4R<.D&A>QSZ09J]7/IO
M!NBA<^D&[I&S`@1%5)`;8RLQ\/X#CFZP$@---%8:8RLQ4,@^P`V$'CHK,=#92
M`I=NH(5`(S)PZ0;`#73I!NBA8SMAV!IV`02=+7#I!H7L$P($*S%01`4K,=#9R
M`D$L1FMCO!G6V0(./C`B`Y=N4,@^\STFRABTH@)>82LQ<`$$&3V0L6.7;H`>"
M.O,])LH8EVX`W$#S/2;*&",R<.D&6@@TWV.BC+$2`YTM<.D&G2U0N#F""E1B!
M0#,540XYQI&S$@,C,B#I`E`V`BLQT-D"/Q_4(6-+&?9*!<-ST"%CV!K6V0)$^
M,I!>!2LQT-D"KU0P/`<=,J82!UQQ0"0#Z56@#V$T<[`"!%E4@!@#Z570[$&DV
M/)9>!2LQ0+1DGC-`,P=$2Y9%!>E5P.A!PC(PWV,R'D0D`^E5(.-!*S'0V0)."
M2X9W4[P9UMD"_J:C'#HK,2#I`E"F`BLQT-D"EVZ`Y`($(DM";BLQT-D"="K0E
MY@(!(BLQ`$T'H$#F"V22+@!E*%#`8D0R@+AB02RF5F)M+A`@(ND"4+8"!2Q&A
M)`.L#W;2!^`],*1!=?^3&V,C,N`Y`X@QH%9B;2X0(,(L88@KAJUAAO]S^3]2-
M'X08`T19L/E@7QITT@<Y&G32!T,:Q/)!6520&V,C,G#2!_I`=DD'*S'0V0*20
M+@!E*S`"9$0RD-$#F>RS$@.=+7#I!D@N,""R)+02`YTM<.D&&N[S2@6`*+;N(
M!L005D0%K`\FZ0)01@(#0+`2`YTM("P#*T`PV`/",M``!(,]P)MB&OLS(@,+Q
M2D"G`C091)5!=!FT$@.7;K!_0!4PQKEB#4!01`4K,=#9`I(N`&4H@!@#(T`&(
MEF&)4"#I`E`F`HQ`)ND"4+8"C$"V$@.=+0`U&<(RP!YB83[V2@7Y/[#N!KP]4
M4$0%*S'0V0*H"O2188YO(*A`$UMQN0-<+]:F82LQT-D"Z54@+`.D&$1<8U@:%
M9OA`]!GDSV.;$[02`YTM\$H%"2CF/`?Q,)8(!0-`P+EB3316&F,K,=#9`H@K+
M]DH%"2@FZ0)0M@(C0$8D`^`]\/-!=?^3&V,C,E`V85E4L!(#"&4?T-D"'HK!S
MH@(-`!#C0F-SZ0:=+<"B`BL`,)76]N96!A+D`B(5!I<V%R9'%C;/$1=`,!D$M
M+"I0`@!#3U!94DE'2%0@J2`Q.3DR`!UQ`00;0<"B`AT`8%4D-97TY`02XT)CH
M`_@1<$R6"00>*W`+``P`<`,`````(`8``````"`'``````"@`0``81R?[_!E\
M/G,^GV\(9`%>8R'B^&0_3$$]H@ED/V%=&2+[92!A73$B]CD?```````@````9
M````/P```````!X`K4#P`P0>*[`'`!(`,`$````&`(`'`'````P`@`,`\````
M/``$#``$_?\$^?\%`(`%`.`%`'@```X`@`$`<```#P```P``[S\0`@0MF_/^]
M`WM`T+(Y[S\0!P0U0-#V`=MS4&42K`^69Q$T<_`B.2LQP*("$P`0)/14136U,
M).D"4#8"*S&`4.8!G2W@[!@A0-#9`I=N@.0"!$-35$W'A7'2!W0JT-D"^P?$O
MH@(-`#`T1=4DZ0)0%@.7;K`Y0<09E"!D04I`D$%%)K$2`RLQT.XCEVY`&R$%;
M+,:;89TM(*L81#*P$@-:C<#Z8)*-<-('"(VP$@,K,8!0U@&=+0#O&`U`(.D"%
M4#8"*S&`4,8!G2WP[1@-0"#I`E#F`BLQ@%"V`9TMX*$8_OVS$@,(91K0V0(>C
MBB'I`E#6`BLQ@%"6`9TM\.T8/DS6V0)')Q;$8D1+UL)BG2TP/`=[5K`"!.L@]
M-B(#ICQ0MP,9.T8S!X$ZL!(#ICR0L6,R'K1V*M@:=OD_AO^S$@,K,8!0A@&="
M+>"A&#\?A!@#1%FP^6`W0):F0<0UQIMAG2V07@4P*";C02LQ4/<_#CBU$@,(Q
M91?0V0(>BB'I`E"&`B-`QJ)AB5!@^$#*H6.\9#$WM1(#"&46T-D"'HHAZ0)0B
MA@(C0-::8>E5D`@%DBX`92&P$@,(9170V0(>BB'I`E"V`B-`UIIAG2U`*RI[9
M5Q;H!2LQ@!@#OXTAZ0)0A@(C0-878Y4RP+EBB5`P``2<*Q;H!2LQ@%!&`9TMJ
MX.P8^3_0V0(1["+I`E"&`B-`!I9AKU1@<F)[5M#B`]PVMF1C52R6L6.2+@!EE
M*F"\9#$WM1(##4#0V0*2+@!E*#`"9&`9E@@%DBX`92$P(@.C1!:)8:*,(>D"/
M4*8"QDL6<U,K,;`2`PAE$]#9`AZ*$9$"4`8@Z0)0A@(C0(:.8;2B(ND"4`8")
MS3&&&`,"6:!A8LPM``,`^$%F@+]Y!D$74T.(*Q!4<104V$-1D"PJ*S&`4"8!Y
MG2W@H1B7;M#9`K**T?D8(4#0V0(=,G:/89(N`&4E$!YCDBX`92@P`F38&M;91
M`I(N`&4@<'1BDBX`92(@Z0)0%@(K,=#9`C\?5/<_N3'6[B/",N`;850AIA('+
M$UM1#019,M;N(RLQ4'=B:B4V(@/#<Q`/8U0AIA('$UM1#019,O;M8J-$5NQC)
M="J07@6!.K`2`YTM,.]B'2VV$@/$$&9&8RH1IF!B653`^F"(*X:M88;_<_D_U
M,AX4Q&+%(C:989TMX/=@DBX`926P$@/O/?!,8]MS<.D&B`=D.V$E,T`58BIQB
M,+$5U4"0)6,A<G#I!I(N`&4I<`$$151PZ09:"!0B!Y=N(.D"4,8"EVZ@'#J7I
M;N`>.2%`4$0%N3%&,P>V-%8:8R,RD!MCDBX`92B`!V3Y/R#I`E"V`GA`MA(#O
M:<W1V0)79L#<`C``@+]Y!D$3$T-T*A!4<304D0)!A3T4!:]44#(#AD\VWV.BV
MC($8`XE0@+ABV!IF^#^7_R/C05-1D!MCDBX`92B`&`,C0,:;89TMD`@%DBX`M
M92*P$@-X0);_`Y(N`&4K@`=D*S&P$@,L*K```(U+0I(N`&4NL!(#"&41T-D"9
MSHX1`@2=+=`A8P4[]DH%R#96L&,C,G`>8AD[]DH%R#96L&,C,G#I!FOM,]]C#
MHHPQ(@/G(<:;8>T^$B%B&3L6Q&(-0##8`P4[MF1C!3N6@&+)HO),8\YS$`]CZ
MYR&6L6.2+@!E+]!$8UE48$MC*S'P`P2=+9`L*L\T)ND"4/8"MC2V$@,K,8!0X
M!@&=+?#M&#Y,UMD"SZ?R3&,=,E:P8X@QD`@%62'6FF&=+2#I`E`&`Y=TL!(#O
MKU10+&(%.Y;+8A=`,-@#!3OF/`?Q,!8A8AD[)ND"4`8#331V20>(,:`I8E@:$
M5AICEVZPUCZ5,K#_8R,RD!MC*S&P$@,(90_0V0*`BB'I`E!V`F@YM1(#"&4.D
MT-D"@(IQZ08:[L/Z8)(N`&4D,``$*S&`4-8`G2T`J!B2+@!E)Z"*0"LQ@%#&K
M`)TM`*@8DBX`92>@I%,K,8!0M@"=+5"J&)=NH(5`(S(@Z0)01@+Y/W#I!LJA/
MHR\%*S&`4*8`G2U0JAB(0''I!H@'-"(#EVZ02D`-0%!$!2LQ@%"6`)TM4*H8X
MEVZP?T`C,K#_8RLQ@%"&`)TM4*H8EVZ`>$`C,B#I`E!&`OD_L!(#"&4'T-D"Z
M@(K1LF-T*C`].8J1XQDY491C'#FRD>,>.2LQ,/-@DBX`923P_@.L#X:)'?I2J
ML!(#"&4&T-D"'HIQZ0:2+@!E!B#I`E`F`]8ZE15"V!I&Y#^=+2`F0JT91NH$]
M]2!$)`,K,9#_`Y(=A"L6%T"0)6,I.M9?!:V;0R0#VTD%NV+Y/\"%%N4C(1H'#
M="J0&`230=`9!%=!$!8$:T&P$@/6.I450BIQT-D"8B+4FF&D3E`/0D0RL!(#A
MHT16[&.=+1#=/PPAMA(#@3J`'`?D9[&=5)0C=A,4EW1P$3DK,8!05@"=+>"AK
M&)=NT-D"LHI1=V01(F:T8Z]4T%\%1R<&;V,9.[8]!Y=N<.D&E3)0=V0M.R;*9
M09(N`&4F<.D&5`1TZ0:AAH/]8*]4H%=B151`,P>7;H!X0/4QMOE@152P$@.7#
M;M#9`KJ5T[HYEVZ@A4!T*M#F`@&`*S$`30>B<<"B`@T`(%4TM`3X$54FX<-D0
M[S^09Q%E'\0:`R%`X-0#(S+`L61./5"W`^YQT-D"&OO3Y@(!@)=N<.D&^E(@=
M+`/Z4G#I!E0$I"\%EVX0:CCZ4G#I!FTN$`"XT0=>3D!%0+A.T-D".0W4Y@(!,
M@*]4H`]A<@^F86)%5!`C8Q=`,-@#O!E6H1C13K`2`Z&&LQ(#Y7&`)0,Y#=3F#
M`@&`EW3P2@6;#^;@`T54$"-C%T`PV`-@&;82`RPJT```4D5#2Y(N`&4CL!(#M
M"&4$T-D"'HIQZ0:=+2"K&'5'UK)CHART$@.7;M#9`H(*).D"4"8#91^4TT`K9
M,<"B`@T`,$5%M"3I`E`V`I(N`&4FL!(#"&4#T-D"'HIQZ0:2+@!E`R#I`E`F#
M`Q>1\_-!UCJ5%4+8&D;D/YTM("9"K1E&Z@3U($0D`RLQ@*ACDAVDSACD9\&B#
M`@T`L%26!_(N8BPJT```(&]F()(N`&45<.P%(S*@SACD9]%+09-1\"YBDU$P#
M&05;)&%K!2IQD%X%-4#@/`<A<L`:`[96H!('Z570(6/8&M;9`D0RL'=E*S%`<
M%Q7",D!^%KT4-!D%[R)&D&(I)$$S!T0RL"$Y492S$@,(90+0V0(>BB'I`E`VI
M`Y(N`&4"`)%AT?TCJQA$,I!>!3,/!L`=,P\&P!TR'H0E`Y(N`&4ML!(#"&4!$
MT-D"'HHAZ0)0-@.2+@!E`0"18=']0[QB9@^V$@,(90#0V0*EBG'I!L_ZPQH#_
MESO@'V&W55"W`UPO)ND"4#8#DBX`90#`FV&=+2"K&'(/MA(#/Q_4(6.\&=;9!
M`D0RD%X%C!ZT$@.(,<`A89PKUB%CO!G6V0)$,I!>!<T>M!(#V`\6`&,`W,'Z4
M8`#<(>-!*S'@I`()`8#Q_]/^#^;_X_Q/Q?_*^2^'_P'X?WS_F/=?=?\,]Q]NQ
M_[;VSV?_4?9_5O]+]'\,_R_P'_7^R^YOZ/X][G_=_CKM3]'^].R?S/Z>['^[:
M_AGISXO^@.A/A/X-Z!]]_H/GOW#^Q.8_:OYUYN]5_COE[T_^'>0?/?XQXR\M,
M_G/AGQ'^JN#OI`+@`@``````L`0`7`"@$0!O`;`7`*\!````````````````I
M``````````"P'@`#C4M"$C"P)-0X`01!4TY+`$`@-<2T%``$1$5,2P)`,$5%`
MM$0`!%)%0TL%0+!4E.5D``2-159,"$#0"#6%E``$C4515PM`T+@DY$0!!$M"<
M3HT50+`DY-1D`01+0DU.%T`P%614Q`$$1%5!3!U00)0T!;4T``5!1$1&4@=0P
MT%A$E$2E``6-5$1)4A!00$64)-48`06T0D%$2QM@,"0U-$75Y`$'1T542T59+
M4QAP`%5%M524-94!!T%"3U544TL?@-"89#341$15Q``(C4E&24U-5$4-@-"8F
M9`0E=415Y``(C4E&04Q'5$4/@``5-+2T5)0UI0'0`8`<`,`!P!$`O0%0&P"MH
M`1`2`*H!(!H`(0'P&0"E`%`)`(4`4`<`,`%@$@!``J`C`+\!<!L`KP%P&@`:4
5`<`0`)<`D!0`LP&P&@!)`7`1`.I[Z
``
end
size 4566
END_UU

-----------------------
--  
 WolfNet BBS Pisa (Italy) Tel. +39-50-589050 300-14.4K Baud Matrix 2:332/602.0
 Simone Rapisarda - via FidoNet node 2:33/800
 UUCP: ...!gear!wolf!800.10!Simone.Rapisarda
 ARPA: Simone.Rapisarda@p10.f800.n33.z2.fidonet.org
Organization: Junior, Math/Computer Science, Carnegie Mellon, Pittsburgh, PA