;ELC   
;;; Compiled by pot@pot.cnuce.cnr.it on Tue Mar 18 15:52:09 2003
;;; from file /home/pot/gnu/emacs-pretest.new/lisp/strokes.el
;;; in Emacs version 21.3
;;; with bytecomp version 2.85.4.1
;;; with all optimizations.

;;; This file uses dynamic docstrings, first added in Emacs 19.29.
(if (and (boundp 'emacs-version)
	 (< (aref emacs-version (1- (length emacs-version))) ?A)
	 (or (and (boundp 'epoch::version) epoch::version)
	     (string-lessp emacs-version "19.29")))
    (error "`strokes.el' was compiled for Emacs 19.29 or later"))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(byte-code "\303\304\305\"\210\301B\306\302B\307\303\207" [current-load-list strokes-version strokes-bug-address autoload mail-position-on-field "sendmail" "2.4-Emacs" "cadet@alum.mit.edu"] 3)
#@130 Symbol representing a stroke lift event for complex strokes.
Complex strokes are those which contain two or more simple strokes.
(defconst strokes-lift :strokes-lift (#$ . 816))
#@50 The header to all xpm buffers created by strokes
(defconst strokes-xpm-header "/* XPM */\nstatic char * stroke_xpm[] = {\n/* width height ncolors cpp [x_hot y_hot] */\n\"33 33 9 1 26 23\",\n/* colors */\n\" 	c none s none\",\n\"*	c #000000 s foreground\",\n\"R	c #FFFF00000000\",\n\"O	c #FFFF80000000\",\n\"Y	c #FFFFFFFF0000\",\n\"G	c #0000FFFF0000\",\n\"B	c #00000000FFFF\",\n\"P	c #FFFF0000FFFF\",\n\".	c #45458B8B0000\",\n/* pixels */\n" (#$ . 1000))
(custom-declare-group 'strokes nil "Control Emacs through mouse strokes" :link '(url-link "http://www.mit.edu/people/cadet/strokes-help.html") :group 'mouse)
#@75 *Modeline identification when strokes-mode is on (default is " Strokes").
(custom-declare-variable 'strokes-modeline-string '" Strokes" '(#$ . -1618) :type 'string :group 'strokes)
#@101 *Character used when drawing strokes in the strokes buffer.
(The default is `@', which works well.)
(custom-declare-variable 'strokes-character '64 '(#$ . -1806) :type 'character :group 'strokes)
#@880 *Minimum score for a stroke to be considered a possible match.
Setting this variable to 0 would require a perfectly precise match.
The default value is 1000, but it's mostly dependent on how precisely
you manage to replicate your user-defined strokes.  It also depends on
the value of `strokes-grid-resolution', since a higher grid resolution
will correspond to more sample points, and thus more distance
measurements.  Usually, this is not a problem since you first set
`strokes-grid-resolution' based on what your computer seems to be able
to handle (though the defaults are usually more than sufficent), and
then you can set `strokes-minimum-match-score' to something that works
for you.  The only purpose of this variable is to insure that if you
do a bogus stroke that really doesn't match any of the predefined
ones, then strokes should NOT pick the one that came closest.
(custom-declare-variable 'strokes-minimum-match-score '1000 '(#$ . -2009) :type 'integer :group 'strokes)
#@824 *Integer defining dimensions of the stroke grid.
The grid is a square grid, where STROKES-GRID-RESOLUTION defaults to
`9', making a 9x9 grid whose coordinates go from (0 . 0) on the top
left to ((STROKES-GRID-RESOLUTION - 1) . (STROKES-GRID-RESOLUTION - 1))
on the bottom right.  The greater the resolution, the more intricate
your strokes can be.
NOTE: This variable should be odd and MUST NOT be less than 3 and need
      not be greater than 33, which is the resolution of the pixmaps.
WARNING: Changing the value of this variable will gravely affect the
         strokes you have already programmed in.  You should try to
         figure out what it should be based on your needs and on how
         quick the particular platform(s) you're operating on, and
         only then start programming in your custom strokes.
(custom-declare-variable 'strokes-grid-resolution '9 '(#$ . -3001) :type 'integer :group 'strokes)
#@73 *File containing saved strokes for stroke-mode (default is ~/.strokes).
(custom-declare-variable 'strokes-file '(convert-standard-filename "~/.strokes") '(#$ . -3929) :type 'file :group 'strokes)
#@70 The buffer that the strokes take place in (default is ` *strokes*').
(custom-declare-variable 'strokes-buffer-name '" *strokes*" '(#$ . 4131) :type 'string :group 'strokes)
#@250 *If non-nil, the strokes buffer is used and strokes are displayed.
If nil, strokes will be read the same, however the user will not be
able to see the strokes.  This be helpful for people who don't like
the delay in switching to the strokes buffer.
(custom-declare-variable 'strokes-use-strokes-buffer 't '(#$ . -4311) :type 'boolean :group 'strokes)
#@111 *Command to execute when stroke is actually a `click' event.
This is set to `mouse-yank-at-click' by default.
(custom-declare-variable 'strokes-click-command ''mouse-yank-at-click '(#$ . -4669) :type 'function :group 'strokes)
#@141 Non-nil when `strokes' is globally enabled.
Setting this variable directly does not take effect.  Use either Customize
or M-x strokes-mode.
(custom-declare-variable 'strokes-mode 'nil '(#$ . 4903) :type 'boolean :set (lambda (symbol value) (strokes-mode (or value 0))) :initialize 'custom-initialize-default :require 'strokes :version "21.1" :group 'strokes)
#@138 The special window configuration used when entering strokes.
This is set properly in the function `strokes-update-window-configuration'.
(defvar strokes-window-configuration nil (#$ . 5269))
#@160 Last stroke entered by the user.
Its value gets set every time the function
`strokes-fill-stroke' gets called,
since that is the best time to set the variable
(defvar strokes-last-stroke nil (#$ . 5467))
#@287 Association list of strokes and their definitions.
Each entry is (STROKE . COMMAND) where STROKE is itself a list of
coordinates (X . Y) where X and Y are lists of positions on the
normalized stroke grid, with the top left at (0 . 0).  COMMAND is the
corresponding interactive function
(defvar strokes-global-map nil (#$ . 5678))
#@62 Function or functions to be called when `strokes' is loaded.
(defvar strokes-load-hook nil (#$ . 6014))
#@64 Execute FORMS without interference from the garbage collector.
(defalias 'strokes-while-inhibiting-garbage-collector '(macro . #[(&rest forms) "\301\302BB\207" [forms let ((gc-cons-threshold 134217727))] 3 (#$ . 6124)]))
#@36 Non-nil if STROKE is really click.
(defalias 'strokes-click-p #[(stroke) "G\301W\207" [stroke 2] 2 (#$ . 6352)])
(put 'strokes-click-p 'byte-optimizer 'byte-compile-inline-expand)
(defalias 'strokes-remassoc #[(key list) "\303\304	\n\"\211\203 \305\n\"\202 )\n\207" [elt key list nil assoc delete] 3])
(put 'strokes-remassoc 'byte-optimizer 'byte-compile-inline-expand)
#@56 Add STROKE to STROKE-MAP alist with given command DEF.
(defalias 'strokes-define-stroke '(macro . #[(stroke-map stroke def) "\303\304D\305\306	\307\211\nE\310	EEEF\207" [stroke stroke-map def if strokes-click-p (error "That's a click, not a stroke; see `strokes-click-command'") setq cons strokes-remassoc] 10 (#$ . 6735)]))
(defalias 'define-stroke 'strokes-define-stroke)
#@36 Returns the square of the number X
(defalias 'strokes-square #[(x) "\211_\207" [x] 2 (#$ . 7118)])
(put 'strokes-square 'byte-optimizer 'byte-compile-inline-expand)
#@104 Gets the distance (squared) between to points P1 and P2.
P1 and P2 are cons cells in the form (X . Y).
(defalias 'strokes-distance-squared #[(p1 p2) "@A	@	AZ\211\211_)\n\fZ\211\211_)\\,\207" [p1 p2 y2 x2 y1 x1 x] 5 (#$ . 7291)])
(put 'strokes-distance-squared 'byte-optimizer 'byte-compile-inline-expand)
#@276 Fix COMMAND so that it can also work with strokes.
COMMAND must take one event argument.
Example of how one might fix up a command that's bound to button2
and which is an interactive funcion of one event argument:

(strokes-fix-button2-command 'rmail-summary-mouse-goto-msg)
(defalias 'strokes-fix-button2-command '(macro . #[(command) "\301!\302\303\304\305\306\"\307\310\311\312\305\313\"!DDC\314BB\257)D\207" [command eval progn defadvice (around strokes-fix-button2 compile preactivate) format "Fix %s to work with strokes." let strokes-click-command quote intern "ad-Orig-%s" ((strokes-do-stroke (ad-get-arg 0)))] 12 (#$ . 7615)]))
(byte-code "\301B\302\301!\204\f \303\303\207" [current-load-list strokes-insinuated boundp nil] 2)
#@39 Insinuate Emacs with strokes advices.
(defalias 'strokes-insinuate #[nil "?\205\317 \301\302\303\304\305$\210\301\306\307\304\305$\210\301\310\311\304\305$\210\312\310\313\314\315B#\210\301\316\317\304\305$\210\301\320\321\304\305$\210\301\322\323\304\305$\210\301\324\325\304\305$\210\301\326\327\304\305$\210\301\330\331\304\305$\210\301\332\333\304\305$\210\301\334\335\304\305$\210\301\336\337\304\305$\210\301\340\341\304\305$\210\301\342\343\304\305$\210\301\344\345\304\305$\210\301\346\347\304\305$\210\301\350\351\304\305$\210\301\352\353\304\305$\210\301\354\355\304\305$\210\301\356\357\304\305$\210\301\360\361\304\305$\210\301\362\363\304\305$\210\301\364\365\304\305$\210\312\364\313\366\367B#\210\301\370\371\304\305$\210\312\370\313\372\373B#\210\301\374\375\304\305$\210\376\211\207" [strokes-insinuated ad-add-advice vm-mouse-button-2 (strokes-fix-button2 nil t (advice lambda nil "Fix vm-mouse-button-2 to work with strokes." (let ((strokes-click-command 'ad-Orig-vm-mouse-button-2)) (strokes-do-stroke (ad-get-arg 0))))) around nil rmail-summary-mouse-goto-msg (strokes-fix-button2 nil t (advice lambda nil "Fix rmail-summary-mouse-goto-msg to work with strokes." (let ((strokes-click-command 'ad-Orig-rmail-summary-mouse-goto-msg)) (strokes-do-stroke (ad-get-arg 0))))) Buffer-menu-mouse-select (strokes-fix-button2 nil t (advice lambda nil "Fix Buffer-menu-mouse-select to work with strokes." (let ((strokes-click-command 'ad-Orig-Buffer-menu-mouse-select)) (strokes-do-stroke (ad-get-arg 0))))) ad-set-advice-info-field cache #[(event) "\303\304\305\n!\210))\207" [ad-return-value strokes-click-command event nil ad-Orig-Buffer-menu-mouse-select strokes-do-stroke] 2 "$ad-doc: Buffer-menu-mouse-select$" "e"] (nil (strokes-fix-button2) nil function t t) w3-widget-button-click (strokes-fix-button2 nil t (advice lambda nil "Fix w3-widget-button-click to work with strokes." (let ((strokes-click-command 'ad-Orig-w3-widget-button-click)) (strokes-do-stroke (ad-get-arg 0))))) widget-image-button-press (strokes-fix-button2 nil t (advice lambda nil "Fix widget-image-button-press to work with strokes." (let ((strokes-click-command 'ad-Orig-widget-image-button-press)) (strokes-do-stroke (ad-get-arg 0))))) Info-follow-clicked-node (strokes-fix-button2 nil t (advice lambda nil "Fix Info-follow-clicked-node to work with strokes." (let ((strokes-click-command 'ad-Orig-Info-follow-clicked-node)) (strokes-do-stroke (ad-get-arg 0))))) compile-mouse-goto-error (strokes-fix-button2 nil t (advice lambda nil "Fix compile-mouse-goto-error to work with strokes." (let ((strokes-click-command 'ad-Orig-compile-mouse-goto-error)) (strokes-do-stroke (ad-get-arg 0))))) gdbsrc-select-or-yank (strokes-fix-button2 nil t (advice lambda nil "Fix gdbsrc-select-or-yank to work with strokes." (let ((strokes-click-command 'ad-Orig-gdbsrc-select-or-yank)) (strokes-do-stroke (ad-get-arg 0))))) hypropos-mouse-get-doc (strokes-fix-button2 nil t (advice lambda nil "Fix hypropos-mouse-get-doc to work with strokes." (let ((strokes-click-command 'ad-Orig-hypropos-mouse-get-doc)) (strokes-do-stroke (ad-get-arg 0))))) gnus-mouse-pick-group (strokes-fix-button2 nil t (advice lambda nil "Fix gnus-mouse-pick-group to work with strokes." (let ((strokes-click-command 'ad-Orig-gnus-mouse-pick-group)) (strokes-do-stroke (ad-get-arg 0))))) gnus-mouse-pick-article (strokes-fix-button2 nil t (advice lambda nil "Fix gnus-mouse-pick-article to work with strokes." (let ((strokes-click-command 'ad-Orig-gnus-mouse-pick-article)) (strokes-do-stroke (ad-get-arg 0))))) gnus-article-push-button (strokes-fix-button2 nil t (advice lambda nil "Fix gnus-article-push-button to work with strokes." (let ((strokes-click-command 'ad-Orig-gnus-article-push-button)) (strokes-do-stroke (ad-get-arg 0))))) dired-mouse-find-file (strokes-fix-button2 nil t (advice lambda nil "Fix dired-mouse-find-file to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-mouse-find-file)) (strokes-do-stroke (ad-get-arg 0))))) url-dired-find-file-mouse (strokes-fix-button2 nil t (advice lambda nil "Fix url-dired-find-file-mouse to work with strokes." (let ((strokes-click-command 'ad-Orig-url-dired-find-file-mouse)) (strokes-do-stroke (ad-get-arg 0))))) dired-u-r-mouse-toggle (strokes-fix-button2 nil t (advice lambda nil "Fix dired-u-r-mouse-toggle to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-u-r-mouse-toggle)) (strokes-do-stroke (ad-get-arg 0))))) dired-u-w-mouse-toggle (strokes-fix-button2 nil t (advice lambda nil "Fix dired-u-w-mouse-toggle to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-u-w-mouse-toggle)) (strokes-do-stroke (ad-get-arg 0))))) dired-u-x-mouse-toggle (strokes-fix-button2 nil t (advice lambda nil "Fix dired-u-x-mouse-toggle to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-u-x-mouse-toggle)) (strokes-do-stroke (ad-get-arg 0))))) dired-g-r-mouse-toggle (strokes-fix-button2 nil t (advice lambda nil "Fix dired-g-r-mouse-toggle to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-g-r-mouse-toggle)) (strokes-do-stroke (ad-get-arg 0))))) dired-g-w-mouse-toggle (strokes-fix-button2 nil t (advice lambda nil "Fix dired-g-w-mouse-toggle to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-g-w-mouse-toggle)) (strokes-do-stroke (ad-get-arg 0))))) dired-g-x-mouse-toggle (strokes-fix-button2 nil t (advice lambda nil "Fix dired-g-x-mouse-toggle to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-g-x-mouse-toggle)) (strokes-do-stroke (ad-get-arg 0))))) dired-o-r-mouse-toggle (strokes-fix-button2 nil t (advice lambda nil "Fix dired-o-r-mouse-toggle to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-o-r-mouse-toggle)) (strokes-do-stroke (ad-get-arg 0))))) dired-o-w-mouse-toggle (strokes-fix-button2 nil t (advice lambda nil "Fix dired-o-w-mouse-toggle to work with strokes." (let ((strokes-click-command 'ad-Orig-dired-o-w-mouse-toggle)) (strokes-do-stroke (ad-get-arg 0))))) isearch-yank-x-selection (strokes-fix-button2 nil t (advice lambda nil "Fix isearch-yank-x-selection to work with strokes." (let ((strokes-click-command 'ad-Orig-isearch-yank-x-selection)) (strokes-do-stroke (ad-get-arg 0))))) #[nil "\302\303\304\302!\210))\207" [ad-return-value strokes-click-command nil ad-Orig-isearch-yank-x-selection strokes-do-stroke] 2 "$ad-doc: isearch-yank-x-selection$" nil] (nil (strokes-fix-button2) nil function t t) occur-mode-mouse-goto (strokes-fix-button2 nil t (advice lambda nil "Fix occur-mode-mouse-goto to work with strokes." (let ((strokes-click-command 'ad-Orig-occur-mode-mouse-goto)) (strokes-do-stroke (ad-get-arg 0))))) #[(event) "\303\304\305\n!\210))\207" [ad-return-value strokes-click-command event nil ad-Orig-occur-mode-mouse-goto strokes-do-stroke] 2 "$ad-doc: occur-mode-mouse-goto$" "e"] (nil (strokes-fix-button2) nil function t t) cvs-mouse-find-file (strokes-fix-button2 nil t (advice lambda nil "Fix cvs-mouse-find-file to work with strokes." (let ((strokes-click-command 'ad-Orig-cvs-mouse-find-file)) (strokes-do-stroke (ad-get-arg 0))))) t] 5 (#$ . 8367)])
(defalias 'strokes-mouse-event-p #[(event) ":\205* @9\205* @\301=\206* \302@\303N>\206* \304@\303N>\206* \305@\303N>\207" [event mouse-movement click event-symbol-elements down drag] 3])
(put 'strokes-mouse-event-p 'byte-optimizer 'byte-compile-inline-expand)
(defalias 'strokes-button-press-event-p #[(event) ":\205 @9\205 \301@\302N>\207" [event down event-symbol-elements] 3])
(put 'strokes-button-press-event-p 'byte-optimizer 'byte-compile-inline-expand)
(defalias 'strokes-button-release-event-p #[(event) ":\205 @9\205 \301@\302N>\206 \303@\302N>\207" [event click event-symbol-elements drag] 3])
(put 'strokes-button-release-event-p 'byte-optimizer 'byte-compile-inline-expand)
#@110 Return position of start of line LINE in WINDOW.
If LINE is nil, return the last position visible in WINDOW.
(defalias 'strokes-event-closest-point-1 #[(window &optional line) "\304!\305!\203 \306\202 \307Z\n\206 	\212\310!b\210\311!U\203+ \n\204+ \312u\210`+\207" [window total line distance window-height window-minibuffer-p 0 1 window-start vertical-motion -1] 3 (#$ . 16213)])
#@167 Return the nearest position to where EVENT ended its motion.
This is computed for the window where EVENT's motion started,
or for window WINDOW if that is specified.
(defalias 'strokes-event-closest-point #[(event &optional start-window) "\204 	\306	8)\307\n8)	\310	8:\203 \310\202 \306	8)\307\n8)=\203\276 	\310	8:\2038 \310\2029 \306	8)\306\n8:\203K \306\n8@\202N \306\n8)\311=\203l \312\313	\310	8:\203d \310\202e \306	8)!A\"\207	\310	8:\203y \310\202z \306	8)\306\n8:\203\214 \306\n8@\202\217 \306\n8)\314=\203\231 \312!\207	\310	8:\203\246 \310\202\247 \306	8)\306\n8:\203\271 \306\n8@\202\274 \306\n8)\207	\310	8:\203\313 \310\202\314 \306	8)\307\n8)\315\316!A@\317!\203\353 \316!A@\202	\310	8:\203\370 \310\202\371 \306	8)\310\n8)A\320!\245\211Y\203\312!\202\321!+\207" [start-window event position end-w end-w-top w-top 1 0 2 vertical-line strokes-event-closest-point-1 posn-col-row mode-line nil window-edges windowp frame-char-height window-start] 6 (#$ . 16611)])
#@44 Return non-nil if OBJECT is a stroke-lift.
(defalias 'strokes-lift-p #[(object) "	=\207" [object strokes-lift] 2 (#$ . 17632)])
#@34 Undo the last stroke definition.
(defalias 'strokes-unset-last-stroke #[nil "\211@A)\303\304\305\n\"!\203 A\306\307!\202 \306\310!)\207" [strokes-global-map x command y-or-n-p format "really delete last stroke definition, defined to `%s'? " message "That stroke has been deleted" "Nothing done"] 5 (#$ . 17767) nil])
#@312 Interactively give STROKE the global binding as COMMAND.
Operated just like `global-set-key', except for strokes.
COMMAND is a symbol naming an interactively-callable function.  STROKE
is a list of sampled positions on the stroke grid as described in the
documentation for the `strokes-define-stroke' function.
(defalias 'strokes-global-set-stroke #[(stroke command) "\211G\306W)\203 \307\310!\207	B\n\311\312\f\"\211\203( \313\"\202 )*B\211\207" [stroke command strokes-global-map list key elt 2 error "That's a click, not a stroke; see `strokes-click-command'" nil assoc delete] 5 (#$ . 18098) (list (and (or strokes-mode (strokes-mode t)) (strokes-read-complex-stroke "Define a new stroke.  Draw with button1 (or 2).  End with button3...")) (read-command "command to map stroke to: "))])
(defalias 'global-set-stroke 'strokes-global-set-stroke)
#@335 Map POSITION to a new grid position based on its STROKE-EXTENT and GRID-RESOLUTION.
STROKE-EXTENT as a list ((XMIN . YMIN) (XMAX . YMAX)).
If POSITION is a `strokes-lift', then it is itself returned.
Optional GRID-RESOLUTION may be used in place of STROKES-GRID-RESOLUTION.
The grid is a square whose dimesion is [0,GRID-RESOLUTION).
(defalias 'strokes-get-grid-position #[(stroke-extent position &optional grid-resolution) ":\203Y 	\206\n \n@A\211@@)\211@A)\211A@)@T\211A@)AT	\n\f\306	\307\fZ!	Z\245_!\306	\307\f\nZ!\nZ\245_!.B\207\310!\205a \207" [position grid-resolution strokes-grid-resolution stroke-extent x ymax floor float strokes-lift-p xmax ymin xmin y strokes-lift] 8 (#$ . 18969)])
#@133 From a list of absolute PIXEL-POSITIONS, returns absolute spatial extent.
The return value is a list ((XMIN . YMIN) (XMAX . YMAX)).
(defalias 'strokes-get-stroke-extent #[(pixel-positions) "\205\264 \211@@)\211@@)\211@A)\211@A)A\n\203k \n@:\203d \n\211@@)\n\211@A)\211W\203G 		V\203O 	\fW\203Y V\203c *\nA\211\204( Z\fZ	\211\n	V\203\224 \f\n	Z\306\245Z\n	Z\306\245\\\202\252 	\nZ\306\245Z	\nZ\306\245\\\fB.BD\207" [pixel-positions x rest ymax ymin xmax 2 xmin y delta-y delta-x] 6 (#$ . 19703)])
#@55 Returns a list with no consecutive redundant entries.
(defalias 'strokes-eliminate-consecutive-redundancies #[(entries) "\304	:\203! 	@	\211A@)\232\204 	@\nB	A\211\202 \n\237*\207" [entries element #1=#:G97269 x nil] 3 (#$ . 20273)])
#@261 Map POSITIONS to a new grid whose dimensions are based on GRID-RESOLUTION.
POSITIONS is a list of positions and stroke-lifts.
Optional GRID-RESOLUTION may be used in place of STROKES-GRID-RESOLUTION.
The grid is a square whose dimesion is [0,GRID-RESOLUTION).
(defalias 'strokes-renormalize-to-grid #[(positions &optional grid-resolution) "\204 	\304\n!\305\306\n\")\207" [grid-resolution strokes-grid-resolution positions stroke-extent strokes-get-stroke-extent mapcar #[(pos) "\303	\n#\207" [stroke-extent pos grid-resolution strokes-get-grid-position] 4]] 3 (#$ . 20522)])
#@205 Fill in missing grid locations in the list of UNFILLED-STROKE.
If FORCE is non-nil, then fill the stroke even if it's `stroke-click'.
NOTE: This is where the global variable `strokes-last-stroke' is set.
(defalias 'strokes-fill-stroke #[(unfilled-stroke &optional force) "\211G\306W)\203 \n\204 \202k\307:\203h@\211:\211A@)\211:\2056 \205? @\205H A\205R @\205\\ A\205h Z\205t Z\205\212 \310!?\205\212 \311!\245\204\226 C\202[\204\374 \312Y\203\317 \307W\203\310 BBT\211\202\257 \237+\202[\307V\203\365 BBS\211\202\334 \237+\202[\310!\203d\312Y\2037\307W\2030BBT\211\202\237+\202[ \307! V\203]B!B!S\211\202D!\237+\202[\313!\313!Y\203\347\312V\203\257\"\307#\"W\203\250\314Z_!\\B#B#T\211\202\204#\237+\202[$\307%$V\203\340\314Z_!\\B%B%S\211\202\274%\237+\202[\312V\203&&\307'&W\203\314Z\245!\\B'B'T\211\202\373'\237+\202[(\307)(V\203W\314Z\245!\\B)B)S\211\2023)\237+.\f\237\f\244A\211\202 \f\237*\211*\207" [unfilled-stroke stroke force grid-locs #1=#:G97270 current 2 nil zerop float 0 abs round current-is-a-point-p x next next-is-a-point-p both-are-points-p x1 y1 x2 y2 delta-x delta-y slope y #2=#:G97271 #3=#:G97272 #4=#:G97273 #5=#:G97274 #6=#:G97275 #7=#:G97276 #8=#:G97277 #9=#:G97278 #10=#:G97279 #11=#:G97280 #12=#:G97281 #13=#:G97282 #14=#:G97283 #15=#:G97284 #16=#:G97285 #17=#:G97286 strokes-last-stroke] 9 (#$ . 21110)])
#@266 Rates STROKE1 with STROKE2 and returns a score based on a distance metric.
Note: the rating is an error rating, and therefore, a return of 0
represents a perfect match.  Also note that the order of stroke
arguments is order-independent for the algorithm used here.
(defalias 'strokes-rate-stroke #[(stroke1 stroke2) "\205\355	\205\355A	A@	@\211@A\n@\nA		Z\211\n\211_)\fZ\211\n\211_)\\.\f\203G\f\203G@:\203\230 \f@:\203\230 @\f@\211@A\n@\nA		Z\211\n\211_)\fZ\211\n\211_)\\.\\\fA	A\f\202G \306@!\203\265 \306\f@!\203\265 A\fA\f\202= \306\f@!\203\376 @:\203= @	@\211@A\n@\nA		Z\211\n\211_)\fZ\211\n\211_)\\.\\A\211\202\277 \306@!\203= \f@:\203= @\f@\211@A\n@\nA		Z\211\n\211_)\fZ\211\n\211_)\\.\\\fA\211\f\202\f\204\215@:\203\215@	@\211@A\n@\nA		Z\211\n\211_)\fZ\211\n\211_)\\.\\A\211\202N\204\323\f@:\203\323@\f@\211@A\n@\nA		Z\211\n\211_)\fZ\211\n\211_)\\.\\\fA\211\f\202\224\306@!\204\343\306\f@!\203\352\307\211\202\354+\207" [stroke1 stroke2 p2 p1 y2 x2 strokes-lift-p nil y1 x1 x err rest2 rest1] 8 (#$ . 22795)])
#@112 Finds the best matching command of STROKE in STROKE-MAP.
Returns the corresponding match as (COMMAND . SCORE).
(defalias 'strokes-match-stroke #[(stroke stroke-map) "\205\\ 	\205\\ \306	\211@@)\"	\211@A)	A\203T \306\211@@)\"\211\203: \203: W\204C \203M \204M \211@A)A)\202 \205[ \fB+\207" [stroke stroke-map x map command score strokes-rate-stroke newscore] 4 (#$ . 24018)])
#@353 Read a simple stroke (interactively) and return the stroke.
Optional PROMPT in minibuffer displays before and during stroke reading.
This function will display the stroke interactively as it is being
entered in the strokes buffer if the variable
`strokes-use-strokes-buffer' is non-nil.
Optional EVENT is acceptable as the starting event of the stroke
(defalias 'strokes-read-stroke #[(&optional prompt event) "\212\306\211\211\203 \307\213\210\f\203# \310\f!\210\311 \312!\204# \313\314!\210\315 \210\316\n\237!\317\320	!!,\207" [safe-to-draw-p grid-locs pix-locs strokes-use-strokes-buffer prompt event nil ((byte-code "\305!\210	\203 \306	!\210\307 \310\n!\204 \311\312!\210\313\216\314 \210)\315 \232\2033 \316ed\f\317$\210eb\210\320 \210\313\207" [strokes-window-configuration prompt event strokes-buffer-name strokes-character set-window-configuration message read-event strokes-button-press-event-p error "You must draw with the mouse" nil (lambda nil (track-mouse (byte-code "\204	 \305 \306\211:\205% @9\205% \307@\310N>\206% \311@\310N>)?\205\204 \211:\205V @9\205V @\312=\206V \307@\310N>\206V \313@\310N>\206V \311@\310N>)\203} \314!\211\203t 	\203t \nb\210\315\n\211T\316$\210\202v \306\317 A\fB)\305 \211\202\n \207" [event safe-to-draw-p point strokes-character pix-locs read-event t click event-symbol-elements drag mouse-movement down strokes-event-closest-point subst-char-in-region 32 mouse-pixel-position] 6))) buffer-name subst-char-in-region 32 bury-buffer] 5)) message read-event strokes-button-press-event-p error "You must draw with the mouse" (lambda nil (track-mouse (byte-code "\204 \302 \211:\205# @9\205# \303@\304N>\206# \305@\304N>)?\205e \211:\205T @9\205T @\306=\206T \303@\304N>\206T \307@\304N>\206T \305@\304N>)\203^ \310 A	B\302 \211\202 \207" [event pix-locs read-event click event-symbol-elements drag mouse-movement down mouse-pixel-position] 4))) strokes-renormalize-to-grid strokes-fill-stroke strokes-eliminate-consecutive-redundancies] 3 (#$ . 24431)])
#@385 Read a complex stroke (interactively) and return the stroke.
Optional PROMPT in minibuffer displays before and during stroke reading.
Note that a complex stroke allows the user to pen-up and pen-down.  This
is implemented by allowing the user to paint with button1 or button2 and
then complete the stroke with button3.
Optional EVENT is acceptable as the starting event of the stroke
(defalias 'strokes-read-complex-stroke #[(&optional prompt event) "\212\300\213)\207" [((byte-code "\305!\210\306\211\203. \f\211:\205 \f@9\205 \307\f@\310N>)\204. \311!\210\312 \211\202 \313\216\314 +\207" [strokes-window-configuration grid-locs pix-locs prompt event set-window-configuration nil down event-symbol-elements message read-event ((byte-code "\302 \232\203 \303ed	\304$\210eb\210\305 \210\302\207" [strokes-buffer-name strokes-character buffer-name subst-char-in-region 32 bury-buffer] 5)) (lambda nil (track-mouse (byte-code "\204 \306 \211:\205 @9\205 \307@\310N>)\203( @\310N@\311=\204\273 \211:\205D @9\205D \312@\310N>\206D \313@\310N>)\204\231 \211:\205t @9\205t @\314=\206t \312@\310N>\206t \307@\310N>\206t \313@\310N>)\203\222 \315!\211\203\213 	b\210\316	\211T\317\n$\210\320 AB)\306 \211\202) \fB\211:\205\260 @9\205\260 \307@\310N>)\204 \306 \211\202\236 \306 \211:\205\330 @9\205\330 \312@\310N>\206\330 \313@\310N>)\203\273 A\237\321!\322\323!!\207" [event point strokes-character pix-locs strokes-lift grid-locs read-event down event-symbol-elements mouse-3 click drag mouse-movement strokes-event-closest-point subst-char-in-region 32 mouse-pixel-position strokes-renormalize-to-grid strokes-fill-stroke strokes-eliminate-consecutive-redundancies] 6)))] 4))] 1 (#$ . 26488)])
#@242 Given STROKE, execute the command which corresponds to it.
The command will be executed provided one exists for that stroke,
based on the variable `strokes-minimum-match-score'.
If no stroke matches, nothing is done and return value is nil.
(defalias 'strokes-execute-stroke #[(stroke) "\306	\"\211@\nA\211G\307W)\203 \310\311!\210\312!\202Z \n\2035 \fX\2035 \313\314\"\210\312!\202Z 	\204U \315!\203O \316\317\320\"!\205Z \321 \202Z \322\323!\202Z \322\324!\210\325+\207" [stroke strokes-global-map match command score strokes-click-command strokes-match-stroke 2 sit-for 0 command-execute message "%s" file-exists-p y-or-n-p format "No strokes loaded.  Load `%s'? " strokes-load-user-strokes error "No strokes defined; use `global-set-stroke'" "No stroke matches; see variable `strokes-minimum-match-score'" nil strokes-minimum-match-score strokes-file] 5 (#$ . 28241)])
#@104 Read a simple stroke from the user and then exectute its command.
This must be bound to a mouse event.
(defalias 'strokes-do-stroke #[(event) "\204 \300\302!\210\303\304\305	\"!\207" [strokes-mode event t strokes-execute-stroke strokes-read-stroke nil] 4 (#$ . 29137) "e"])
#@105 Read a complex stroke from the user and then exectute its command.
This must be bound to a mouse event.
(defalias 'strokes-do-complex-stroke #[(event) "\204 \300\302!\210\303\304\305	\"!\207" [strokes-mode event t strokes-execute-stroke strokes-read-complex-stroke nil] 4 (#$ . 29420) "e"])
#@74 Displays the command which STROKE maps to, reading STROKE interactively.
(defalias 'strokes-describe-stroke #[(stroke) "\306	\"\211G\307W)\203 \206 \n@\nA\n\203$ X\2042 \211G\307W)\203: \203: \310\311\f\"\210\202> \310\312!\210\313\314!+\207" [stroke strokes-global-map match strokes-click-command command score strokes-match-stroke 2 message "That stroke maps to `%s'" "That stroke is undefined" sleep-for 1 strokes-minimum-match-score] 4 (#$ . 29719) (list (strokes-read-complex-stroke "Enter stroke to describe; end with button3..."))])
(defalias 'describe-stroke 'strokes-describe-stroke)
#@56 Get instructional help on using the `strokes' package.
(defalias 'strokes-help #[nil "\302\220\303\304\220\305!\210	q\210\306 \221\210\307 )\221\207" [helpdoc standard-output "*Help with Strokes*" "This is help for the strokes package.\n\nIf you find something wrong with strokes, or feel that it can be\nimproved in some way, then please feel free to email me:\n\nDavid Bakhash <cadet@mit.edu>\n\nor just do\n\nM-x strokes-report-bug\n\n------------------------------------------------------------\n\n** Strokes...\n\nThe strokes package allows you to define strokes, made with\nthe mouse or other pointer device, that Emacs can interpret as\ncorresponding to commands, and then executes the commands.  It does\ncharacter recognition, so you don't have to worry about getting it\nright every time.\n\nStrokes also allows you to compose documents graphically.  You can\nfully edit documents in Chinese, Japanese, etc. based on XEmacs\nstrokes.  Once you've done so, you can ascii compress-and-encode them\nand then safely save them for later use, send letters to friends\n(using Emacs, of course).  Strokes will later decode these documents,\nextracting the strokes for editing use once again, so the editing\ncycle can continue.\n\nStrokes are easy to program and fun to use.  To start strokes going,\nyou'll want to put the following line in your .emacs file as mentioned\nin the commentary to strokes.el.\n\nThis will load strokes when and only when you start Emacs on a window\nsystem, with a mouse or other pointer device defined.\n\nTo toggle strokes-mode, you just do\n\n> M-x strokes-mode\n\n** Strokes for controlling the behavior of Emacs...\n\nWhen you're ready to start defining strokes, just use the command\n\n> M-x global-set-stroke\n\nYou will see a ` *strokes*' buffer which is waiting for you to enter in\nyour stroke.  When you enter in the stroke, you draw with button1 or\nbutton2, and then end with button3.  Next, you enter in the command\nwhich will be executed when that stroke is invoked.  Simple as that.\nFor now, try to define a stroke to copy a region.  This is a popular\nedit command, so type\n\n> M-x global-set-stroke\n\nThen, in the ` *strokes*' buffer, draw the letter `C' (for `copy')\nand then, when it asks you to enter the command to map that to, type\n\n> copy-region-as-kill\n\nThat's about as hard as it gets.\nRemember: paint with button1 or button2 and then end with button3.\n\nIf ever you want to know what a certain strokes maps to, then do\n\n> M-x describe-stroke\n\nand you can enter in any arbitrary stroke.  Remember: The strokes\npackage lets you program in simple and complex (multi-lift) strokes.\nThe only difference is how you *invoke* the two.  You will most likely\nuse simple strokes, as complex strokes were developed for\nChinese/Japanese/Korean.  So the middle mouse button (mouse-2) will\ninvoke the command `strokes-do-stroke' in buffers where button2 doesn't\nalready have a meaning other than its original, which is `mouse-yank'.\nBut don't worry: `mouse-yank' will still work with strokes.  See the\nvariable `strokes-click-command'.\n\nIf ever you define a stroke which you don't like, then you can unset\nit with the command\n\n> M-x strokes-unset-last-stroke\n\nYou can always get an idea of what your current strokes look like with\nthe command\n\n> M-x strokes-list-strokes\n\nYour strokes will be displayed in alphabetical order (based on command\nnames) and the beginning of each simple stroke will be marked by a\ncolor dot.  Since you may have several simple strokes in a complex\nstroke, the dot colors are arranged in the rainbow color sequence,\n`ROYGBIV'.  If you want a listing of your strokes from most recent\ndown, then use a prefix argument:\n\n> C-u M-x strokes-list-strokes\n\nYour strokes are stored as you enter them.  They get saved in a file\ncalled ~/.strokes, along with other strokes configuration variables.\nYou can change this location by setting the variable `strokes-file'.\nYou will be prompted to save them when you exit Emacs, or you can save\nthem with\n\n> M-x save-strokes\n\nYour strokes get loaded automatically when you enable `strokes-mode'.\nYou can also load in your user-defined strokes with\n\n> M-x load-user-strokes\n\n** Strokes for pictographic editing...\n\nIf you'd like to create graphical files with strokes, you'll have to\nbe running a version of Emacs with XPM support.  You use the\nbinding C-mouse-2 to start drawing your strokes.  These are just\ncomplex strokes, and thus you continue drawing with mouse-1 or mouse-2 and\nend with mouse-3-3.  Then the stroke image gets inserted into the\nbuffer.  You treat it like any other character, which you can copy,\npaste, delete, move, etc.  The command which is bound to C-mouse-2 is\ncalled `strokes-compose-complex-stroke'.  When all is done, you may\nwant to send the file, or save it.  This is done with\n\n> M-x strokes-encode-buffer\n\nLikewise, to decode the strokes from a strokes-encoded buffer you do\n\n> M-x strokes-decode-buffer\n\n** A few more important things...\n\no The command `strokes-do-complex-stroke' is invoked with M-mouse-2,\n  so that you can execute complex strokes (i.e. with more than one lift)\n  if preferred.\n\no Strokes are a bit computer-dependent in that they depend somewhat on\n  the speed of the computer you're working on.  This means that you\n  may have to tweak some variables.  You can read about them in the\n  commentary of `strokes.el'.  Better to just use apropos and read their\n  docstrings.  All variables/functions start with `strokes'.  The one\n  variable which many people wanted to see was\n  `strokes-use-strokes-buffer' which allows the user to use strokes\n  silently--without displaying the strokes.  All variables can be set\n  by customizing the group named `strokes' via the customization package:\n\n  > M-x customize" "*Help" princ help-mode print-help-return-message] 4 (#$ . 30333) nil])
#@34 Submit a bug report for strokes.
(defalias 'strokes-report-bug #[nil "\304\305	\306\307\310\311\312\313\314\315\316#)\317\"\"\320C\244B\321$)\207" [reporter-prompt-for-summary-p strokes-bug-address completion-ignore-case obarray t reporter-submit-bug-report "Strokes" strokes-version mapcar intern sort nil all-completions "strokes-" user-variable-p string-lessp reporter-version #[nil "\212\301\302!\210\303 \210\304\305w\210\306\307!\205 \310\225b\210\311\312!\210\313\314\261)\207" [strokes-version mail-position-on-field "subject" beginning-of-line "^:\n" nil looking-at ": Strokes;" 0 delete-char -1 " " " bug:"] 3]] 11 (#$ . 36271) nil])
#@71 Erase the contents of the current buffer and fill it with whitespace.
(defalias 'strokes-fill-current-buffer-with-whitespace #[nil "\301 \210\302 S\211\303Y\203 \304\305\306 S\"\210\307 \210\202 )eb\207" [#1=#:G97287 erase-buffer frame-height 0 insert-char 32 frame-width newline] 3 (#$ . 36927)])
(put 'strokes-fill-current-buffer-with-whitespace 'byte-optimizer 'byte-compile-inline-expand)
#@151 Non-nil if the `strokes-window-configuration' frame properties changed.
This is based on the last time the `strokes-window-configuration was updated.
(defalias 'strokes-window-configuration-changed-p #[nil "\301\302 \"\207" [strokes-window-configuration compare-window-configurations current-window-configuration] 3 (#$ . 37332)])
#@59 Ensure that `strokes-window-configuration' is up-to-date.
(defalias 'strokes-update-window-configuration #[nil "\303 \304!\204 \305!\203 \306\2023 t\204# \307\310	!!\203# \n\204* \212\311\213)\2023 \312 \2053 \212\313\213))\207" [current-window strokes-buffer-name strokes-window-configuration selected-window window-minibuffer-p window-dedicated-p nil buffer-live-p get-buffer ((byte-code "\305!\210\306	\"\210\307 \210\310 \210\311\312!\210\313\314!\203 \315\312!\210\316\312!\210\317p!\210\320\321 \210\322 S\211\312Y\203C \323\324\325 S\"\210\326 \210\202- )eb\210\327 \330 \207" [strokes-buffer-name current-window truncate-lines #1=#:G97287 strokes-window-configuration get-buffer-create set-window-buffer delete-other-windows fundamental-mode auto-save-mode 0 featurep font-lock font-lock-mode abbrev-mode buffer-disable-undo nil erase-buffer frame-height insert-char 32 frame-width newline current-window-configuration bury-buffer] 3)) strokes-window-configuration-changed-p ((byte-code "\304	\"\210\305 \210\306 \210\307 \nS\211\310Y\203$ \311\312\313 S\"\210\314 \210\202 )eb\210\315 \316 \207" [current-window strokes-buffer-name #1# strokes-window-configuration set-window-buffer delete-other-windows erase-buffer frame-height 0 insert-char 32 frame-width newline current-window-configuration bury-buffer] 3))] 3 (#$ . 37670) nil])
#@62 Load user-defined strokes from file named by `strokes-file'.
(defalias 'strokes-load-user-strokes #[nil "\301!\203 \302!\203 \303!\207t\203 \304\305!\207\306\307!\207" [strokes-file file-exists-p file-readable-p load-file error "Trouble loading user-defined strokes; nothing done" message "No user-defined strokes, sorry"] 2 (#$ . 39038) nil])
(defalias 'load-user-strokes 'strokes-load-user-strokes)
#@60 Save user-defined strokes to file named by `strokes-file'.
(defalias 'strokes-prompt-user-save-strokes #[nil "\212\303\216\304\305 \210	\232\204d t\204 \306\307!\203d \310\311!\210\312\313\n\"\210\314\315!\210\315q\210\316 \210\317 \210eb\210\320\321!\210\320\322\323\324 \325\326\304\"#!\210\312\313\n\"\210\320\322\327\311	!\"!\210\312\313\n\"\210\330ed\304#\210\331ed\n#\202g \312\332!+\207" [strokes-global-map current strokes-file ((byte-code "\302\303!\203\f \304\302\303!!\210\302\207" [current strokes-global-map get-buffer "*saved-strokes*" kill-buffer] 3)) nil strokes-load-user-strokes yes-or-no-p "save your strokes? " require pp message "Saving strokes in %s..." get-buffer-create "*saved-strokes*" erase-buffer emacs-lisp-mode insert-string ";;   -*- Syntax: Emacs-Lisp; Mode: emacs-lisp -*-\n" format ";;; saved strokes for %s, as of %s\n\n" user-full-name format-time-string "%B %e, %Y" "(setq strokes-global-map '%s)" indent-region write-region "(no changes need to be saved)"] 7 (#$ . 39451) nil])
(defalias 'save-strokes 'strokes-prompt-user-save-strokes)
#@220 Toggle the use of the strokes buffer.
In other words, toggle the variabe `strokes-use-strokes-buffer'.
With ARG, use strokes buffer if and only if ARG is positive or true.
Returns value of `strokes-use-strokes-buffer'.
(defalias 'strokes-toggle-strokes-buffer #[(&optional arg) "\203\f \302!\303V\202 	?\211\207" [arg strokes-use-strokes-buffer prefix-numeric-value 0] 2 (#$ . 40540) "P"])
#@462 Create an xpm pixmap for the given STROKE in buffer ` *strokes-xpm*'.
If STROKE is not supplied, then `strokes-last-stroke' will be used.
Optional BUFNAME to name something else.
The pixmap will contain time information via rainbow dot colors
where each individual strokes begins.
Optional B/W-ONLY non-nil will create a mono pixmap, not intended
for trying to figure out the order of strokes, but rather for reading
the stroke as a character in some language.
(defalias 'strokes-xpm-for-stroke #[(&optional stroke bufname b/w-only) "\212\306\206 \307!\310\311\312	\206 \n\313\"!!\314\315\316\317\320\321\322\257\211q\210\323 \2100c\210\32411S\2111\325Y\203J \326c\210\327\330\324\"\210\331c\210\332 \210\202. \333y\210\334\210\335c\210)	2\3343\3344\33452:\203\377 2@\2113\24243\24353:\203\355 \f\203\325 6\204\325 @\206\211 \3367\3258\325\337X\203\313 \3259\325\337X\203\301 \34085\\\341\\!\21094\\\342\\u\210\343\342!\2107c\2109T\2119\202\230 )8T\2118\202\217 )A\334)\202\366 \3405\344\\!\2104\337\\u\210\345``T\330\346$\210\202\366 \3473!\203\366 \3142A\2112\202b ,t\205\350\307!\210eb\210\351\352\353 \354\314\355\356%\357 \"-\207" [bufname stroke strokes-last-stroke rainbow-chars lift-flag buf get-buffer-create " *strokes-xpm*" strokes-eliminate-consecutive-redundancies strokes-fill-stroke strokes-renormalize-to-grid 31 t 82 79 89 71 66 80 erase-buffer 33 0 34 insert-char 32 "\"," newline -1 nil "}\n" 46 2 goto-line 16 1 delete-char 17 subst-char-in-region 42 strokes-lift-p pop-to-buffer put-image create-image buffer-string xpm :ascent 100 line-end-position strokes-xpm-header #1=#:G97288 #2=#:G97289 point x y b/w-only char i j] 10 (#$ . 40941) nil])
#@251 Pop up a buffer containing an alphabetical listing of strokes in STROKES-MAP.
With CHRONOLOGICAL prefix arg (\[universal-argument]) list strokes
chronologically by command name.
If STROKES-MAP is not given, `strokes-global-map' will be used instead.
(defalias 'strokes-list-strokes #[(&optional chronological strokes-map) "\206\f 	\206\f \306 \210	\n\204 \307\310!\311\"\312 \313\314!q\210\315\316 \210\317\320\261\210\315*:\203u @\211*@\321*A!+,\322,\323\"\210\324\325!\210\326\327\330\"\210\331 \210+c\210\331 \210\330u\210\332\333r\323q\210\334 )\335\336#!\210*A\211\2020 \337`Td\"\210*\340\314\336\"\210\341\342!\343\"!-\344-\345\346\315\347\350\351D\257#\210-)L\210eb)\207" [strokes-map strokes-global-map chronological config buffer-read-only #1=#:G97290 strokes-load-user-strokes sort copy-sequence strokes-alphabetic-lessp current-window-configuration get-buffer-create "*Strokes List*" nil erase-buffer "Command                                     Stroke\n" "-------                                     ------" symbol-name strokes-xpm-for-stroke " *strokes-xpm*" newline 2 insert-char 32 45 beginning-of-line insert-image create-image buffer-string xpm t kill-region view-buffer make-local-variable view-mode-map copy-keymap define-key "q" lambda (interactive) (View-quit) set-window-configuration def command-name stroke map] 10 (#$ . 42662) "P"])
#@79 T iff command name for STROKE1 is less than STROKE2's in lexicographic order.
(defalias 'strokes-alphabetic-lessp #[(stroke1 stroke2) "\304A!\304	A!\211\n\231*\207" [stroke1 stroke2 command-name-2 command-name-1 symbol-name] 4 (#$ . 44053)])
#@522 Toggle strokes being enabled.
With ARG, turn strokes on if and only if ARG is positive or true.
Note that `strokes-mode' is a global mode.  Think of it as a minor
mode in all buffers when activated.
By default, strokes are invoked with mouse button-2.  You can define
new strokes with

> M-x global-set-stroke

To use strokes for pictographic editing, such as Chinese/Japanese, use
S-mouse-2, which draws strokes and inserts them.  Encode/decode your
strokes with

> M-x strokes-encode-buffer
> M-x strokes-decode-buffer
(defalias 'strokes-mode #[(&optional arg) "\203\f \306!\307V\202 	?\310 \204 \311\312!\210\202\232 \n\203Q \313 \210\314!\203/ \f\204/ \315 \210\316\317\320\"\210\316\321\322\"\210\322 \210\323\324\325#\210\323\326\327#\210\330\331!\210\332\202\232 \333+!\203_ \334\333+!!\210\335\321\322\"\210\336\331\337\340\341!!\"\203v \323\342,#\210\336\331\337\340\343!!\"\203\205 \344\345!\210\336\331\337\340\346!!\"\203\224 \344\347!\210\350\331!\210\351)\352 \207" [arg strokes-mode on-p strokes-file strokes-global-map global-map prefix-numeric-value 0 display-mouse-p error "Can't use strokes without a mouse" strokes-insinuate file-exists-p strokes-load-user-strokes add-hook kill-emacs-query-functions strokes-prompt-user-save-strokes select-frame-hook strokes-update-window-configuration define-key [(down-mouse-2)] strokes-do-stroke [(meta down-mouse-2)] strokes-do-complex-stroke ad-activate-regexp "^strokes-" t get-buffer kill-buffer remove-hook string-match symbol-name key-binding [(down-mouse-2)] [(down-mouse-2)] [(meta down-mouse-2)] global-unset-key [(meta down-mouse-2)] [(control down-mouse-2)] [(control down-mouse-2)] ad-deactivate-regexp nil force-mode-line-update strokes-buffer-name strokes-click-command] 5 (#$ . 44305) "P"])
(byte-code "\300\301\302\303\304\305\306\307&\210\310\307\311\312#\207" [custom-declare-face strokes-char-face ((t (:background "lightgray"))) "Face for strokes characters." :version "21.1" :group strokes put char-table-extra-slots 0] 8)
#@55 The table which stores values for the character keys.
(defconst strokes-char-table (make-char-table 'strokes) (#$ . 46328))
(byte-code "\301\302I\210\303\304I\210\305\306I\210\307\310I\210\311\312I\210\313\314I\210\315\316I\210\317\320I\210\321\322I\210\323\324I\210\325\326I\210\327\330I\210\331\332I\210\333\334I\210\335\336I\210\337\340I\210\341\342I\210\343\344I\210\345\346I\210\347\350I\210\351\352I\210\353\354I\210\355\356I\210\357\360I\210\361\362I\210\363\364I\210\365\366I\210\367\370I\210\371\372I\210\373\374I\210\375\376I\210\377\201@ I\210\201A \201B I\210\201C \201D I\210\201E \201F I\210\201G \201H I\210\201I \201J I\210\201K \201L I\210\201M \201N I\210\201O \201P I\210\201Q \201R I\210\201S \201T I\210\201U \201V I\210\201W \201X I\210\201Y \201Z I\210\201[ \201\\ I\210\201] \201^ I\210\201_ \201` I\210\201a \301I\210\201b \303I\210\201c \305I\210\201d \307I\210\201e \311I\210\201f \313I\210\201g \315I\210\201h \317I\210\201i \321I\210\201j \323I\210\201k \201l I\210\201m \201n I\210\201o \201p I\210\201q \201r I\207" [strokes-char-table 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 56 8 57 9 97 10 98 11 99 12 100 13 101 14 102 15 103 16 104 17 105 18 106 19 107 20 108 21 109 22 110 23 111 24 112 25 113 26 114 27 115 28 116 29 117 30 118 31 119 32 120 33 121 34 122 35 65 36 66 37 67 38 68 39 69 40 70 41 71 42 72 43 73 44 74 45 75 46 76 47 77 78 79 80 81 82 83 84 85 86 87 58 88 59 89 60 90 61] 3)
#@76 Character vector for fast lookup of base-64 encoding of numbers in [0,61].
(defconst strokes-base64-chars (byte-code "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376&>\207" [vector "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "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" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"] 63) (#$ . 47822))
#@52 Non-nil if CHAR represents an `on' bit in the xpm.
(defalias 'strokes-xpm-char-on-p #[(char) "\301=\207" [char 42] 2 (#$ . 48481)])
(put 'strokes-xpm-char-on-p 'byte-optimizer 'byte-compile-inline-expand)
#@61 Non-nil if CHAR represents an `on' or `off' bit in the xpm.
(defalias 'strokes-xpm-char-bit-p #[(char) "\301=\206	 \302=\207" [char 32 42] 2 (#$ . 48693)])
(put 'strokes-xpm-char-bit-p 'byte-optimizer 'byte-compile-inline-expand)
#@63 Given some LENGTH in [0,62) do a fast lookup of its encoding.
(defalias 'strokes-xpm-encode-length-as-string #[(length) "	H\207" [strokes-base64-chars length] 2 (#$ . 48931)])
(put 'strokes-xpm-encode-length-as-string 'byte-optimizer 'byte-compile-inline-expand)
#@78 Given a CHARACTER, do a fast lookup to find its corresponding integer value.
(defalias 'strokes-xpm-decode-char #[(character) "	H\207" [strokes-char-table character] 2 (#$ . 49201)])
(put 'strokes-xpm-decode-char 'byte-optimizer 'byte-compile-inline-expand)
#@150 Convert the xpm in XPM-BUFFER into a compressed string representing the stroke.
XPM-BUFFER is an optional argument, and defaults to `*strokes-xpm*'.
(defalias 'strokes-xpm-to-compressed-string #[(&optional xpm-buffer) "\212\206 \306\211q\210eb\210\307\310!\210\311u\210\312\313\314\315\211f	\316=\204\276 \317\f!\203H 	\211\320=\2068 \321=)\203B \322	\321=\322u\210\202\267 \f\323U\203p \n=\205^ \313H)\323H)Q\n\313\202\267 	\211\320=\206} \321=)\203\264 \n	\321==\203\222 \fT\322u\210\202\267 \n=\205\242 \313H)\fH)Q\313\n\202\267 \322u\210\315f\211\202  \f\313V\205\336 \n=\205\324 \313H)\fH)P\324Q.\207" [xpm-buffer char-at-point current-char-is-on-p last-char-was-on-p count compressed-string "*strokes-xpm*" search-forward "/* pixels */" 2 "+/" 0 t nil 125 zerop 32 42 1 61 "/" char length strokes-base64-chars] 6 (#$ . 49467)])
#@187 Decode stroke strings in BUFFER and display their corresponding glyphs.
Optional BUFFER defaults to the current buffer.
Optional FORCE non-nil will ignore the buffer's read-only status.
(defalias 'strokes-decode-buffer #[(&optional buffer force) "\212\306\206 p!\211q\210	\203! \n\204! \204! \307\310\311\"!\205x \312\313\314\"\210eb\210\315\211\211 rq\210\316\317\315\312\315$\205L \320\321!\322\225b\210\323\324!\210\312)\203r \325\326\"\210\327r\326q\210\330 )\331\312#\332\f\333\324\334\335\211\f\336&\"\210\2022 +\313\337\"))\207" [buffer buffer-read-only force inhibit-read-only image string get-buffer y-or-n-p format "Buffer %s is read-only.  Strokify anyway? " t message "Strokifying %s..." nil re-search-forward "\\+/\\(\\w+\\)/" match-string 1 0 replace-match " " strokes-xpm-for-compressed-string " *strokes-xpm*" create-image buffer-string xpm insert-image propertize type stroke-glyph data "Strokifying %s...done" ext] 10 (#$ . 50377) nil])
#@184 Convert the glyphs in BUFFER to thier base-64 ASCII representations.
Optional BUFFER defaults to the current buffer.
Optional FORCE non-nil will ignore the buffer's read-only status.
(defalias 'strokes-encode-buffer #[(&optional buffer force) "\212\206 p\211q\210	\203 \n\204 \204 \306\307\310\"!\205v \311\312\"\210\313\314\211o\2035 \315`\316\"\204> \317`\316\"\211\203q \315`\316\"\320=\203* b\210\321 \315\322\"\323\315`\324\"\325\261\210\326\327!\210\330`\316\331\332\333\320\f\322\314\257#\210\202* \311\334\"+)\207" [buffer buffer-read-only force inhibit-read-only glyph start y-or-n-p format "Buffer %s is read-only.  Encode anyway? " message "Encoding strokes in %s..." t nil get-text-property type next-single-property-change stroke-glyph point-marker display "+/" data 47 delete-char 1 add-text-properties stroke-string face strokes-char-face "Encoding strokes in %s...done"] 11 (#$ . 51356) nil])
#@135 Convert the stroke represented by COMPRESSED-STRING into an xpm.
Store xpm in buffer BUFNAME if supplied (default is `*strokes-xpm*')
(defalias 'strokes-xpm-for-compressed-string #[(compressed-string &optional bufname) "\212\204 \306\307!q\210\310 \210	c\210eb\210\311m\2048 \312\n\203$ \313\202% \314\311f\fH)\"\210\315\316!\210\n?\202 eb\210\317S\211\320Y\203R \321c\210\317u\210\322c\210\202= )eb\210c*\207" [bufname compressed-string current-char-is-on-p character strokes-char-table #1=#:G97291 "*strokes-xpm*" get-buffer-create erase-buffer nil insert-char 42 32 delete-char 1 33 0 34 "\",\n" strokes-xpm-header] 4 (#$ . 52293)])
#@69 Read a complex stroke and insert its glyph into the current buffer.
(defalias 'strokes-compose-complex-stroke #[nil "\301\302 \210\303\304\305\306#\210\307\305!c\210\310 \210\304u)\207" [strokes-grid-resolution 33 strokes-read-complex-stroke strokes-xpm-for-stroke nil " *strokes-xpm*" t strokes-xpm-to-compressed-string strokes-decode-buffer] 4 (#$ . 52949) "*"])
(byte-code "\302\236\204\f \302	DB\303\304!\210\305\306!\207" [minor-mode-alist strokes-modeline-string strokes-mode provide strokes run-hooks strokes-load-hook] 2)
