#
#######################################################################
#######
######             TISii - The Irritating Script II  v0.14d
#####				    
####                          by Juggler/BTL
###
##
#
# NOTE: This script uses serial numbers 00, 70..90 and -70..-90 for hooks.
#       To find the sections that use serial number 00, search for "#00".
#
# WARNING:  Until the script reaches version 1.0 you can assume that it
#           is NOT finished, and WILL have bugs/unimplemented features.
#
@ s.TIS_VERSION = [The Irritating Script II v0.14d]

##############################################################################
###
##  CHANGELOG
#
#
#  0.14d - 12.07.2001:
#
#    Replaced old email and FTP addresses with current information.
#
#  0.14c - 11.07.2001: 
#
#    Fixed problems with s.wxecho, so messages etc. will go to the 
#    proper windows again.  Added code for printing the time/date every 
#    10 minutes when away (useful in logs).  Started maintaing this
#    changelog.
#

##############################################################################
###
##  CONFIGURATION!!  Its not a bad idea to edit the following lines...
#
 
###  This tells the script where to store its data files!
##
#   The script checks if this is valid, if it does not exist it tries to 
#   create it - and if all fails it uses the current directory.
#
#   Default:  @ s.TIS_HOME = [$(HOME)/.tisii]
#
eval if ([$HOME]!=[]) {
	# Use the home directory..
	#
	@ s.TIS_HOME = [$(HOME)/.tisii]
} {
	# Default to current dir if $HOME is not set..
	#
	@ s.TIS_HOME = [$W]
}

###
##  Some misc. commands/scripts/binds that I like 
#	(and don't conflict with TISii)
#
^bind ^I next_window
^bind ^B self_insert
^bind ^V self_insert
^bind ^_ self_insert
^bind ^N switch_channels
load cursor
load edit
load imap
eval echo [!] Bound: ^I (TAB) switches windows, ^N switches channels.
eval echo [!] imap, edit, cursor loaded.  Try $(K)edit  and $(K)initmap
^eval $(K)$(K)mode $N +i
^set verbose_ctcp on

##############################################################################
###
##  The following are DEFAULT values for the script loading feature.
#     These can be changed with /i config load..

###
##  Modules:
#
@ s.cfg.load.MISC_HELP.d         = [Miscellanious help for the script.  1..load]
@ s.cfg.load.REFORMAT_CHANNELS.d = [Change the way channels look?  0..no, 1..yes]
@ s.cfg.load.REFORMAT_MESSAGES.d = [Change the way private messages look?  0..no, 1..yes]
@ s.cfg.load.REFORMAT_STATBAR.d  = [Change the status bar?  0..no, 1..yes]
@ s.cfg.load.MSG_HISTORY.d       = [Message history code.  1..load+enable, 2..load]
@ s.cfg.load.FLOOD_PROT.d        = [Flood protection code.  1..load+enable, 2..load]
@ s.cfg.load.QUIET_DESYNCH.d     = [Desynched channel code.  1..load+enable, 2..load]
@ s.cfg.load.QUIET_SPLIT.d       = [Netsplit signoff/join filter.  1..load+enable, 2..load]
@ s.cfg.load.CHANNEL_CODE.d      = [Commands for chanops.  1..load]
@ s.cfg.load.NOTIFY_STUFF.d      = [$(K)Notify code.  1..load+enable, 2..load]
@ s.cfg.load.AWAY_STUFF.d        = [$(K)Away related code.  1..load+enable, 2..load]
@ s.cfg.load.LOADED_BLURB.d      = ["Script loaded" message: 0..none, 1..normal, 2..brief]
@ s.cfg.load.MISC_HELP           = 1
@ s.cfg.load.REFORMAT_CHANNELS   = 1
@ s.cfg.load.REFORMAT_MESSAGES   = 1
@ s.cfg.load.REFORMAT_STATBAR    = 1
@ s.cfg.load.MSG_HISTORY         = 2
@ s.cfg.load.FLOOD_PROT          = 2
@ s.cfg.load.QUIET_DESYNCH       = 2
@ s.cfg.load.QUIET_SPLIT         = 2
@ s.cfg.load.CHANNEL_CODE        = 1
@ s.cfg.load.NOTIFY_STUFF        = 2
@ s.cfg.load.AWAY_STUFF          = 2
@ s.cfg.load.LOADED_BLURB        = 1
###
##  Emulations:
#
@ s.cfg.load.EMULATE_TABKEY.d  = [Emulate the TABKEY script (msg hist uses TAB instead of ^R)]
@ s.cfg.load.EMULATE_TABKEY    = 0

# Default toggle values:
#
@ s.cfg.load.CHANNEL_CODE.auto_rejoin     = 1
@ s.cfg.load.CHANNEL_CODE.nick_cache      = 1
@ s.cfg.load.CHANNEL_CODE.no_server_modes = 0


## End of configuration - stop editing now.

eval load $(s.TIS_HOME)/tis2.ini


##############################################################################
###[ MISC ALIASES ... ]#######################################################
##############################################################################

@ s.help.new.a     = [A brief history of new/changed features.  To read]
@ s.help.new.b     = [each about change type: $(s.C.UNDERL)/i help ]
@ s.help.new.c     = [ ]
@ s.help.new.v011b = [  v0.11b .. nicklist, flood, messages]
@ s.help.new.v012b = [  v0.12b .. config, rebind, set, save]
@ s.help.new.v013b = [  v0.13b .. config, save, wordcmd, topic, messages, ban]
@ s.help.new.v014b = [  v0.14b .. help, flood, unban, nickcache]

alias m msg
alias d dmsg
alias ig ignore
alias wi whois
alias whosi wi
alias whios wi
alias unig {ignore $0 NONE}
alias rs parsekey refresh_screen
alias dk dcc close
alias umode {$(K)$(K)mode $N $0-}
alias k {kick * $0-}
alias back {away;comment}
alias hold win hold_mode on
alias nhold win  hold_mode off

## TISii enhancements:
#
alias n i.names
alias l i.leave
alias j i.join
alias w i.who
alias t i.topic
alias names i.names
alias leave i.leave
alias join i.join
alias who i.who
alias list i.list
alias topic i.topic
alias mode i.mode
alias op {i.mode * +ooo $0-}
alias dop {i.mode * -ooo $0-}
alias vop {i.mode * +vvv $0-}
alias dvop {i.mode * -vvv $0-}
alias msay {i msay $0-}
alias query {i query $0-}
alias version {i version}

@ s.help.aliases.a     = [This is a quick list of the shorthand aliases - the ones you will]
@ s.help.aliases.a0000 = [probably use the most.  This includes any "emulation" aliases.]
@ s.help.aliases.a0001 = [ ]
@ s.help.aliases.ppl0  = [People:     m=msg, d=dmsg, ig=ignore, unig, wh=whois]
@ s.help.aliases.lists = [Lists:      n=names, w=who, list]
@ s.help.aliases.misc  = [Misc:       rs=refresh screen, dk=dcc close, umode, version]
@ s.help.aliases.ch0   = [Channels:   msay, l=leave, j=join, k=kick, t=topic]
@ s.help.aliases.ch1   = [            op, vop, dop, dvop]


##############################################################################
###[ CORE ROUTINES ... ]######################################################
##############################################################################

###
##  Some settings to make things work better..
#
^set input_aliases off 
^set novice off
^set max_recursions 50
^set exec_protection off
^set hide_private_channels off
^set show_channel_names on
^eval set load_path .:$LOAD_PATH
^set lastlog 100
^set lastlog_level PUBLIC MSGS NOTICES ACTIONS DCC CTCP CRAP USERLOG1 
^set indent on
^set -continued_line
^set tab on
^set tab_width 8
^set clock on
^set flood_warn off
###
##  Some more for EPIC..
#
eval if (rmatch(x$J *EPIC*)) {
	^set MODE_STRIPPER off
	^set C_LIKE_PARSING off
}

if (s.cfg.load.REFORMAT_STATBAR) {
	^set status_format %Z %A%T %*%@%N%#%Q%C%+%S%F%H%B %W%>%M %U%X%Y
	^set status_user  [Try /I HELP or /HELP]
	^set status_user3 i
	^set status_query  [/msg %Q]
	^set status_mail  mail(%M)
	^set status_notify  act(%F)
	^set status_away [AWAY]
	^set status_hold  -M0RE-
	^set status_hold_lines %B-
	^set -status_overwrite
	^set -status_insert
}

# What were these for?
#timer 0 ^window name TIS
#timer 0 ^window level NONE

###
##  Misc internal ASSIGNs.. 
#
@ s.NONNUMERICS = [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`~!@#\$%^&()-_=+\\|{};:'"<>,./?\]\[]
@ s.NONASSIGN   = [`~!@#\$%^&()-=+\\|{};:'"<>,./?\]\[]

@ s.REF.HELP = [880001 10]

@ s.save.file.CFG   = [tis2.cfg configuration]
@ s.save.vars.CFG   = [Settings: s.set]
@ s.save.file.LISTS = [tis2.sav lists]
@ s.save.vars.LISTS = [Lists: s.list]
@ s.save.file.LOAD  = [tis2.ini load]
@ s.save.vars.LOAD  = [Modules/Emulations: s.cfg.load]
@ s.save.file.MISC  = [tis2.dat miscellania]
@ s.save.vars.MISC  = [Noises: s.misc]

###
##  These aliases are updated as the script loads, and end up containing a
#    list of commands to execute when /i config xx has completed, if anything
#      was altered.  Allows me to keep hooks as small and fast as possible,
#          without losing flexibility.  Eats memory though.. ah well.
#
@ s.rehashcmds.MISC  = [comment]
@ s.rehashcmds.LISTS = [comment]
@ s.rehashcmds.LOAD  = [s.echo NOTE: Changes will take effect NEXT time you load the script.]
@ s.rehashcmds.CFG   = [comment]

@ s.cfg.lastcmds = [comment]

@ s.C.SPACE    = [ ]
@ s.C.BEEP     = []
@ s.C.REVERSE  = []
@ s.C.BOLD     = []
@ s.C.UNDERL   = []
@ s.C.CTCP     = []
@ s.C.CTRLC    = []
@ s.C.JUNK     = [$(s.C.BOLD)$(s.C.BOLD)]
@ s.C.PHIGH    = [$(s.C.BOLD)]
@ s.C.CHIGH    = []

@ s.X = [\[$(s.C.BOLD)i$(s.C.BOLD)\]]
@ s.H = [\[$(s.C.BOLD)h$(s.C.BOLD)\]]

if (s.cfg.load.MISC_HELP) {

@ s.help.usage.a   = [For each command there is a syntax description like this:]
@ s.help.usage.b   = [ ]
@ s.help.usage.c   = [     Usage: $(s.C.UNDERL)$(K)i COMMAND  \[optional\]]
@ s.help.usage.d   = [ ]
@ s.help.usage.e   = [In these descriptions the "|" character stands for "or".]

@ s.help.author.a  = [The Irritating Script II (TISii) is written by Juggler/BTL.]
@ s.help.author.b  = [Please send bug reports, comments or suggestions to bre@klaki.net.]
@ s.help.author.c  = [This script is released to the public domain.]
@ s.help.author.e  = []
@ s.help.author.f  = [See also: $(s.C.UNDERL)/i help updates$(s.C.UNDERL) and $(s.C.UNDERL)/i help register$(s.C.UNDERL)]

@ s.help.updates.a = [The newest revision of TISii can be found at:]
@ s.help.updates.b = [$(s.C.UNDERL)http://bre.klaki.net/programs/irc/tis2.irc]

# misc help..
}

if (s.cfg.load.EMULATE_TABKEY) {

@ s.help.emulation.a = [...]

# emulation help..
}

###
##  Misc internal ALIASes.. 
#
@ s.misc.reformatted.d = [Prefix for reformatted messages.]
@ s.misc.reformatted   = [***]
alias s.rehash.rxecho {
	eval ^alias S.rxecho \{xecho -LEVEL $$0 $(s.misc.reformatted) $$1-\}
}
@ s.rehashcmds.MISC = s.rehashcmds.MISC ## [\;s.rehash.rxecho]

eval alias S.echo \{xecho -LEVEL USERLOG1 $(s.X) $$0-\}
eval alias S.xecho \{xecho -LEVEL $$0 $(s.X) $$1-\}
eval alias S.hecho \{xecho -LEVEL USERLOG2 $(s.h) $$0-\}
alias S.wxecho {
	if ([$s.lastecho]!=[$2-]) {
		xecho -WINDOW $1 -LEVEL $0 $(s.C.JUNK)$2-
		@ s.lastecho = [$2-]
	} {
		@ s.silent = 0
	}
}

alias S.nickonly {
	@ function_return = [$left($index(! $0) $0)]
}
alias S.uhostonly {
	@ function_return = [$strip(~ $mid(${index(! $0) + 1} -1 $0))]
}
alias S.ruhostonly {
	@ function_return = [$mid(${index(! $0) + 1} -1 $0)]
}
alias S.Wordfrom {
	# INCLUSIVE - from, and including word N
	#
	@ function_return = [$(${[$0] + 1}-)]
}
alias S.Wordto {
	# EXCLUSIVE - to, but not including word N
	# .. This means that if WordFrom and WortTo are used together, then
	# .. the string is returned in full.  As it should be. :-)
	@ function_return = [$(1-$(0))]
}
alias S.NotWord {
	# Arg $0 means the same thing here as for $word()
	# Idea ripped from TABKEY - but mine *much* is smaller!  :-)
	#
	if ([$0]) {
		@ function_return = [$(1-$(0)) $(${[$0] + 2}-)]
	} {
		@ function_return = [$2-]
	}
}
alias S.c2s {
	# Char to Space.
	#
	@ s.c2s1 = [$1-]
	@ s.c2s2 = index($0 $s.c2s1)
	while (s.c2s2 != -1) {
		@ s.c2s1 = [$left($s.c2s2 $s.c2s1)$(s.C.SPACE)$mid(${s.c2s2 + 1} -1 $s.c2s1)]
		@ s.c2s2 = index($0 $s.c2s1)
	}
	@ function_return = s.c2s1
}
alias S.s2c {
	# Space to Char.
	#
	@ s.sc2c = [$2-]
	@ s.sc2r = [$1]
	while ([$#s.sc2c] > 0) {
		@ s.sc2r = [$(s.sc2r)$(0)$word(0 $s.sc2c)]
		@ s.sc2c = [$s.wordfrom(1 $s.sc2c)]
	}
	@ function_return = [$s.sc2r]
}
alias S.c2c {
	# Char to Char.
	#
	@ s.c2s1 = [$2-]
	@ s.c2s2 = index($0 $s.c2s1)
	while (s.c2s2 != -1) {
		@ s.c2s1 = [$left($s.c2s2 $s.c2s1)$(1)$mid(${s.c2s2 + 1} -1 $s.c2s1)]
		@ s.c2s2 = index($0 $s.c2s1)
	}
        @ function_return = [$s.c2s1]
}
alias S.cXc {
	# Char eXchanged with Char.
	#
	@ s.c2s1 = [$2-]
	@ s.c2s2 = index($0$1 $2-)
	@ s.c2s3 = []
	while (s.c2s2 != -1) {
		if (mid($s.c2s2 1 $s.c2s1) == [$0]) {
			@ s.c2s3 = s.c2s3 ## [$left($s.c2s2 $s.c2s1)$1]
		} {
			@ s.c2s3 = s.c2s3 ## [$left($s.c2s2 $s.c2s1)$0]
		}
		@ s.c2s1 = mid(${s.c2s2 + 1} -1 $s.c2s1) 
		@ s.c2s2 = index($0$1 $s.c2s1)
	}
	@ function_return = s.c2s3 ## s.c2s1
}
alias S.Rotate {
	#
	#  Rotates the words in a variable forward or backwards..
	#
	if ([$1]!=[-1]) {
		@ $0 = [$S.WordFrom(1 $($0)) $word(0 $($0))]
	} {
		@ s.rot2 = [$($0)]
		@ s.rot = [$word(${#s.rot2 - 1} $($0))]
		@ $0 = [$(s.rot) $S.WordTo(${#s.rot2 - 1} $($0))]
	}
	@ function_return = [$($0)]
}
alias S.user2banmask {
	# Thanks to ChadF for this, and the following routine I borrowed
	# them (with permission :) from his cftk.functions script.
	#
	if ([$index(? $0)] != [-1]) {
		@ function_return = [*\\?*]
	} {
		if ([$index(* $0)] != [-1]) {
			@ function_return = [*\\**]
		} {
			if ([$[1]0] == [~]) {
				@ function_return = [*$mid(1 -1 $0)]
			} {
				@ function_return = [*$0]
			}
		}
	}
}
alias S.host2banmask {
	if ([$index(1234567890 $[1]0)] != [-1]) {
		@ function_return = [$left(${rindex(. $0) + 1} $0)*]
	} {
		@ s.h2bm.hd = index(. $0)
		if (s.h2bm.hd == rindex(. $0)) {
			@ function_return = [*$0]
		} {
			@ function_return = [*$mid($s.h2bm.hd -1 $0)]
		}
	}
	#
	# End of Chad's code..
}
alias S.WildUHost {
	@ function_return = [$0!$S.user2banmask($1)@$S.host2banmask($2)]
}
alias S.UnAssign {
	foreach $0 s.UA$(0) {
		S.UnAssign $(0).$(s.UA$(0))
	}
	^assign -s.UA$(0)
	^assign -$(0)
}
alias S.CopyAtoB {
	if ([$($0)]!=[]) {
		@ $1 = [$($0)]
	}
	foreach $0 s.Ca2b$0 {
		S.CopyAtoB $0.$(s.Ca2b$0) $1.$(s.Ca2b$0)
	}
	^assign -s.Ca2b$0
}
alias S.Sub {
	# Args:  
	#
	@ $0 = [$($0)] - [$1]
	if ([$($0)] < 1) {
		^assign -$0
	}
}
alias S.Channel {
	@ s.0 = 0
	if ([$0]==[*]) {
		@ s.0 = 1
		@ s.tmpc = [$C]
	} {
		if (ischannel($0)) {
			@ s.0 = 1
			@ s.tmpc = [$0]
		} {
			@ s.tmpc = [$C]
		} 
	}
	if (!s.tmpc) {@ s.tmpc = [&heimskt&]}
	@ function_return = [$s.tmpc]
}
alias S.MassCheck {
	# Check for mass-anythings.
	# Args:     
	#
	@ $0 = [0$($0)] + [0$1]
	if ([$($0)] > [$2]) {
		$4-
		^assign -$(0)
	} {
		eval timer $3 S.Sub $(0) 0$1
	}
}
alias S.Bindings.hook {
	if (match($0 $2_$3_$4_$5_$6_$7_$8_$9)) {
		if (!match(%- $1)) {
			@ s.binds = [$s.binds $1]
		} {
			@ s.binds = [$s.binds $1^´]
		}
	}
}
alias S.Bindings {
	# Returns a list of keys bound to command $0
	# Spaces should represented with '_' or a wildchar.
	#
	@ s.binds = []
	^stack push on WINDOW
	^eval on #^window 00 "% * is bound to *" \{s.Bindings.hook $1 $$2 $$6-\}
	rbind $0
	^on window -
	^stack pop on WINDOW
	@ function_return = [$s.binds]
	^assign -s.binds
}
@ s.ctrlName.chars = [^L    ^I  ^M   ]
@ s.ctrlName.names = [ENTER TAB ENTER]
alias S.CtrlName {
	@ s.cnn = [$match($0 $s.ctrlname.chars)]
	if (s.cnn) {
		@ function_return = [$word(${s.cnn -1} $s.ctrlname.names)]
	} {
		@ function_return = [$0]
	}
}
alias S.KeyName {
	@ s.cn = 0
	@ s.cnr = []
	while ([$($s.cn)]!=[]) {
		@ s.cnc = [$($s.cn)]
		if (match(META?-% $($s.cn))) {
			@ s.cnr = [$s.cnr $s.CtrlName($word(0 $s.bindings($left(5 $s.cnc) *)))-]
			@ s.cnc = [$mid(6 -1 $s.cnc)]
		}
		@ s.cnr = [$(s.cnr)$s.CtrlName($s.cnc) ]
		@ s.cn = s.cn + 1
	}
	@ function_return = [$s.cnr]
}
alias S.getBind {
	# Returns the binding for key $0
	#
	@ s.binds = []
	^stack push on WINDOW
	^eval on #^window 00 "% % $0 is bound to *" \{@ s.binds = \[$$6-\]\}
	bind $0
	^on window -
	^stack pop on WINDOW
	@ function_return = [$s.binds]
	^assign -s.binds
}
alias S.getVariable {
	# Returns a list of $0's (alias or assign) that match $1*
	#
	@ s.alist = []
	^stack push on WINDOW
	^on #^window 00 "% % Aliases:" #
	^on #^window 00 "% % Assigns:" #
	if ([$2] != [allow_structs]) {
		^on #^window 00 "% % *$1**" #
	}
	^on #^window 00 "% % *$1*" {
       	  	@ s.alist = s.alist ## [$mid(1 $index(	 $mid(1 -1 $2)) $2) ]
	}
	$0 $1
	^on window -
	^stack pop on WINDOW
	if (match($1 $s.alist)) {@ s.alist = [$1]}
	@ function_return = s.alist
	^assign -s.alist
}
alias S.LoopMode {
	@ s.lmargs = [$2-5]
	$(K)$(K)quote MODE $0 $left(1 $1)$left($#s.lmargs $strip(+- $1$1$1$1)) $2-5
	if ([$6]!=[]) {
		S.LoopMode $0 $1 $6-
	}
}

alias S.Save.Var {
	if ([$($0)] != []) {
		^msg %save assign $0 $($0)
	}
	^foreach $0 s.sve.$(0) {
	      # if (([$($(0).$(s.sve.$(0)))] != []) && ([$(s.sve.$0)]!=[d])) {
		if ([$($(0).$(s.sve.$(0)))] != []) {
			S.Save.Var $(0).$(s.sve.$(0))
		}
	}
	^assign -s.sve.$(0) 
	if ([$1]!=[]) {S.Save.Var $1-}
}
alias S.Save.Com {
	^msg %save ###
	^msg %save ##  $0-
	^msg %save #
}
alias S.Save {
	# s.save   [ ] [...]
	#
	^exec -name save cat > $(s.TIS_HOME)/$(0)
	^msg %save #### ## #
	^msg %save ##### The $1 file for $(s.TIS_VERSION)
	^msg %save ######## ## ##  #  ## #   #
	^msg %save @ s.loaded.$1 = 1
	@ s.sve = 2
	while ([$($s.sve)]!=[]) {
		S.Save.Com $s.c2s(_ $($s.sve))
		S.Save.Var $(${s.sve + 1})
		@ s.sve = s.sve + 2
	}
	^exec -close %save
	wait
}
alias s.nfilt {
	# s.nfilt 
	# Strips users own nick from list, returns op-noop ordered list.
	# Sets s.nlist to a list of users without ops.
	# Sets s.chops to a list of users with ops.
	#
	@ s.nlist = [$0-]
	@ s.nlt = [$match($N $strip(@+ $s.nlist))]
	if (s.nlt) {@ s.nlist = [$s.notword(${s.nlt - 1} $s.nlist)]}

	@ s.chops = []
	@ s.nlt = [$match(*@* $s.nlist)]
	while (s.nlt) {
		@ s.chops = [$word(${s.nlt - 1} $s.nlist) $s.chops]
		@ s.nlist = [$s.notword(${s.nlt - 1} $s.nlist)]
		@ s.nlt = [$match(*@* $s.nlist)]
	}

	@ function_return = [$s.chops $s.nlist]
}

alias s.DeathScroll {
	# Override for commands like /list, /who and /names - which
	# create way too much output.  (DeathScroll (tm) :-)
	#
	if ([$1]!=[]) {
		$(K)$(K)$0 $1-
	} {	if ([$C] != 0) {
			$(K)$(K)$0 *
		} {	S.echo Type $(s.C.UNDERL)$(K)$(K)$0$(s.C.UNDERL) if you are ABSOLUTELY sure about that..
		}
	}
}

###
##  Misc external ALIASes 
#    Enhanced to for alias completion..
#
alias I {
	if ([$0]!=[]) {
		@ s.tmp = [$s.getVariable(alias I.$0)]
	} {
		@ s.tmp = [I.]
	}
	if ([$#s.tmp] < 2) {
		@ s.tmp = [$word(0 $mid(2 -1 $s.tmp))]
		if ([$(s.parms.$(s.tmp))]!=[]) {
			if ([$($(s.parms.$(s.tmp)))] != []) {
				I.$(s.tmp) $1-
			} {
				S.hecho $(s.help.$(s.tmp).a)
			}
		} {
			S.hecho Try $(s.C.UNDERL)$(K)i help$(s.C.UNDERL) for a list of commands.
		}
	} {
		s.echo Commands: $s.c2s(. $s.s2c(, $s.tmp))
		xtype -LITERAL $(K)i $0
	}
}

## Set up screen width var for help listing..
#	
if ([$COLUMNS]!=[]) {
	@ s.h.lw = [${COLUMNS - (14 + [$@s.H])}]
} {
	@ s.h.lw = 61 
}
@ s.parms.help = 0
@ s.help.help.a = [Usage: $(s.C.UNDERL)$(K)i help \[command|?\]]
@ s.help.help.d = [ ]
@ s.help.help.e = [Displays help for \[command\], or a list of commands if none is]
@ s.help.help.f = [specified.  See $(s.C.UNDERL)$(K)i help usage$(s.C.UNDERL) for more info.]
alias I.help {
	#
	#  Big.. possibly too complicated, but I like it.  It even acts
	#  reasonably if you start a funny sized IRC window, like 40x40 or
	#  something.  If the $COLUMNS environment variable is set, that is.
	#  If the COLUMNS variable isn't set it assumes 80 columns.
	#
	#  "Now featuring help topic name completion" ... whee :)
	#
	@ s.hlp.t = []
	if ([$0]!=[]) {
		@ s.hlp.t = [$s.getvariable(assign s.help.$0 allow_structs)]
	}
	if ([$#s.hlp.t] > 0) {
		if ([$#s.hlp.t] == 1) {
			@ s.hlp.t = [$word(0 $s.hlp.t)] ;
			S.hecho $(s.C.BOLD)$toupper($mid(${rindex(. $s.hlp.t) + 1} -1 $s.hlp.t))
			foreach $(s.hlp.t) s.ii {
				S.hecho   $($(s.hlp.t).$(s.ii))
			}
		} {     S.hecho Ambiguous topic: $toupper($0)
		}
	} {
		@ s.hlp.stick = !s.hlp.llist
		if ((([$0]==[]) && (!s.hlp.llist)) || ([$0]==[?])) {
			S.hecho $(s.C.BOLD)COMMANDS/topics$(s.C.BOLD)	\($s.TIS_VERSION\)
			S.hecho
			@ s.tmp = []
			foreach s.help s.ii {
				if ([$(s.parms.$(s.ii))]!=[]) {
					@ s.tmp = [$s.tmp $[12]s.ii]
				} {
					@ s.tmp = [$s.tmp $tolower($[12]s.ii)]
				}
				if ([$@s.tmp] > s.h.lw) {
					S.hecho $s.tmp
					@ s.tmp = []
				}
			}
			if ([$s.tmp] != []) {
				S.hecho $s.tmp
			}
			S.hecho
			@ s.hlp.llist = 1
			@ s.hlp.stick = 1
		} {	if (!s.hlp.llist) {
				S.hecho Sorry, try $(s.C.UNDERL)$(K)i help$(s.C.UNDERL) for a list of topics or $(s.C.UNDERL)$(K)help $0-
				@ s.hlp.stick = 0
			} {
				@ s.hlp.stick = ([$0]!=[])
			}
		}
	}
	if (s.hlp.stick) {
		xtype -LITERAL $(K)i help !
		parsekey backspace
		^timer -delete $word(0 $s.REF.HELP)
		^timer -refnum $s.REF.HELP @ s.hlp.llist = 0
	} {
		@ s.hlp.llist = 0
	}
}

@ s.parms.register = 0
@ s.help.register.a = [Usage: $(s.C.UNDERL)$(K)i register now]
@ s.help.register.d = [Sends your 'registration' to me (the author).  This is your way]
@ s.help.register.e = [of saying "thank you".  This is of course optional.]
@ s.help.register.f = [ ]
@ s.help.register.g = [$(s.C.BOLD)NOTE$(s.C.BOLD): If you do this I will have a copy of your return email]
@ s.help.register.h = [      address.  If you do not like this don't register.]
alias I.register {
	if ([$0]==[now]) {
		s.echo Executing: $(K)exec echo I use $s.TIS_VERSION |mail bre@klaki.net
		s.echo Thank you for registering!
		exec echo I use $s.TIS_VERSION |mail bre@klaki.net
	} {
		I.help register
	}
}

@ s.parms.version = 0
@ s.help.version.a = [Usage: $(s.C.UNDERL)$(K)i version]
@ s.help.version.d = [Displays the script, client and server version information.]
alias I.version {
	s.rxecho CRAP Script: $s.TIS_VERSION by Juggler/BTL
	$(K)$(K)version
}

@ s.parms.set = 0
@ s.help.set.a = [Usage: $(s.C.UNDERL)$(K)i set \[variable \[ON|OFF|\]\]]
@ s.help.set.d = [Alters or displays the configuration for TISii.  Specify a]
@ s.help.set.e = [variable to display its current setting and some info on it.]
@ s.help.set.f = [See also: $(s.C.UNDERL)/i help save$(s.C.UNDERL) or $(s.C.UNDERL)/i help lists]
alias I.set {
	if (([$0]!=[]) && ([$(s.set.$0)]!=[])) {
		if (match($1 ON OFF)) {
			@ s.set.$0 = ([$1]==[ON])
		} {
			if ([$1]!=[]) {@ s.set.$0 = [$1-]}
			while (match(0?* $(s.set.$0))) {@ s.set.$0 = [$mid(1 -1 $(s.set.$0))]}
		}
		S.set.$0
		S.Echo $(s.C.BOLD)$toupper($0)$(s.C.BOLD) : $(s.set.$(0).d)
		S.Echo $word(${![$(s.set.$0)]} (ON) (OFF)) = [$(s.set.$0)]
	} {
		S.Echo $(s.C.BOLD)Settings:$(s.C.BOLD)
		foreach s.set s.ii {
			S.Echo $[-16]s.ii = [$left(5 $word(${![$(s.set.$(s.ii))]} (ON) (OFF)) ) $(s.set.$(s.ii))]
		}
	}
}

@ s.parms.lists = 0
@ s.help.lists.a = [Usage: $(s.C.UNDERL)$(K)i lists \[list\] \[edit|set|delete  \[data\]\]]
@ s.help.lists.c = [ ]
@ s.help.lists.d = [Alter/display (one of) the TISii lists.  (e.g. auto_op, ok_flood..)]
@ s.help.lists.e = [See also: $(s.C.UNDERL)/i help save$(s.C.UNDERL) or $(s.C.UNDERL)/i help set]
alias I.lists.edit {
	^parsekey erase_line
	^xtype -LITERAL $(K)i lists set $0 $(s.list.$0) $1-
}
alias I.lists.set {
	@ s.list.$0 = [$1-]
	I.lists $0
}
alias I.lists.delete {
	^assign -s.list.$(0)
	^assign -s.list.$(0).d
	s.echo Deleted list $0
}
alias I.lists {
	if ([$(s.list.$(0).d)]!=[]) {
		s.echo $(s.C.BOLD)$toupper($0)$(s.C.BOLD) : $(s.list.$(0).d)
		s.echo > $(s.list.$0)
	} {
		if ((match($0  edit set delete)) && ([$(s.list.$(1).d)]!=[])) {
			I.lists.$0 $1-
		} {
			s.echo $(s.C.BOLD)List descriptions:
			foreach s.list s.ii {
			    if ([$(s.list.$(s.ii).d)] != []) {
				s.echo $[-10]s.ii : $(s.list.$(s.ii).d)
			    }
			}
		}
	}
}

@ s.parms.save = 1
@ s.help.save.a = [Usage: $(s.C.UNDERL)$(K)i save [ALL] [lists] [cfg] [load] [misc]]
@ s.help.save.c = [ ]
@ s.help.save.d = [Saves TISii data to a file.]
alias I.save {
	if ([$(s.save.file.$0)]!=[]) {
		S.Save $(s.save.file.$0) $(s.save.vars.$0)
		S.echo Saved $word(1 $(s.save.file.$0)) to file $(s.TIS_HOME)/$word(0 $(s.save.file.$0))
		if ([$1]!=[]) {
			I.save $1-
		}
	} {
		if ([$0]!=[ALL]) {
			S.hecho $s.help.save.a
			S.echo No such save file: $0
		} {
			I.Save lists cfg load misc
		}
	}
}

@ s.parms.repeat = 2
@ s.help.repeat.a = [Usage: $(s.C.UNDERL)$(K)i repeat  ]
@ s.help.repeat.d = [Repeats a command N times.]
@ s.repcount = 0
alias I.Repeat {
    if (s.repcount == 0) {
	while (s.repcount < [0$strip($s.NONNUMERICS $0)]) {
		@ s.repcount = s.repcount + 1
		$1-
	}
	@ s.repcount = 0
    } {
	s.echo $(s.C.BOLD)ERROR$(s.C.BOLD) I.Repeat was called recursively!
    }
}

@ s.parms.mctcp = 3
@ s.help.mctcp.a = [Usage: $(s.C.UNDERL)$(K)i multictcp   ]
@ s.help.mctcp.d = [Sends N CTCP requests in one line.]
alias I.MCTCP {
	@ s.tmp = [$2]
	while ([$#s.tmp] < [0$strip(s.NONNUMERICS $0)]) {
		@ s.tmp = [$(s.tmp) $(s.C.CTCP)$(s.C.CTCP)$2]
	}
	quote PRIVMSG $1 :$(s.C.CTCP)$toupper($s.tmp)$(s.C.CTCP)
}

@ s.parms.ctcpreply = 2
@ s.help.ctcpreply.a = [Usage: $(s.C.UNDERL)$(K)i CTCPreply   \[text..\]]
@ s.help.ctcpreply.d = [Sends a (fake) CTCP REPLY to a nick/channel.]
alias I.CTCPreply {
	quote NOTICE $0 :$(s.C.CTCP)$toupper($1) $2-$(s.C.CTCP)
	if ([$VERBOSE_CTCP] == [ON]) {
		S.xecho CTCP CTCP $toupper($1) reply to $(0): $2-
	}
}

@ s.parms.notify = 0
@ s.help.notify.d = [Delayed-for-aliases notify.  See $(s.C.UNDERL)$(K)help notify]
@ s.help.notify.a = [Usage: $(s.C.UNDERL)$(K)i notify <\[-\]nicks..>]
alias I.Notify {
	if ([$0] == []) {
		$(K)$(K)notify
	} {
		if (!match(*=* $0-)) {
			@ s.inNL = [$s.inNL $0-]
			^timer -refnum 20202 10 eval ^notify $$s.inNL\;^assign -s.inNL
		}
	}
}

@ s.parms.tmpignore = 2
@ s.help.tmpignore.d = [Ignore someone for N seconds.  See $(s.C.UNDERL)$(K)help ignore]
@ s.help.tmpignore.a = [Usage: $(s.C.UNDERL)$(K)i tmpignore   \[what\]]
alias I.TmpIgnore {
	S.echo Ignoring $0 for 0$strip($s.NONNUMERICS $1) seconds.
	if ([$2] != []) {
		^ignore $0 $2-
	} {
		^ignore $0 ALL
	}
	^timer 0$strip($s.NONNUMERICS $1) eval ^ignore $0 NONE\;S.echo Unignoring $0
}

@ s.parms.seeraw = 0
@ s.help.seeraw.d = [Toggle display of unformatted server output (in a window).]
@ s.help.seeraw.a = [Usage: $(s.C.UNDERL)$(K)i seeraw]
alias I.SeeRaw {
	if ([$s.SEERAW] == []) {
		^window new name SeeRaw level USERLOG4 shrink 32 shrink 16 shrink 8 shrink 4 shrink 2 shrink 1 grow 1 back
		^on #-window_kill 90 "SeeRaw" {i.seeraw}
		^on #-raw_irc 90 "*" {xecho -LEVEL USERLOG4 $0-}
		@ s.SEERAW = [ON]
	} {
		^on #-window_kill 90 -"SeeRaw"
		^on #-raw_irc 90 -"*"
		^window refnum SeeRaw kill
 		^assign -s.SEERAW
	}
}

@ s.parms.rebind = 3
@ s.help.rebind.a = [Usage: $(s.C.UNDERL)$(K)i rebind   [-Q(uiet)] ]
@ s.help.rebind.d = [Re-binds all keys bound to  matching  to ]
@ s.help.rebind.e = [Use -Q for quiet.. \(see $(s.C.UNDERL)$(K)help bind ?$(s.C.UNDERL) for a list\).]
alias I.reBind {
	@ s.binds2 = [$s.bindings($0 $1)]
	while ([$#s.binds2] > 0) {
		if (match(%Q% $2)) {
			^bind $word(0 $s.binds2) $3-
		} {
			bind $word(0 $s.binds2) $2-
		}
		@ s.binds2 = [$s.wordFrom(1 $s.binds2)]
	}
}

@ s.parms.msay = 1
@ s.help.msay.a = [Usage: $(s.C.UNDERL)$(K)i msay ]
@ s.help.msay.d = [Send something to ALL channels you are on.]
alias I.msay {
	if ([$mychannels()]!=[]) {
		msg $s.s2c(, $mychannels()) $0-
	} {
		S.echo You aren't on any channels!
	}
}

alias I.wordcmd._hset {
	^on #-$0 90 $2-
	if (match(-% $2)) {
		^assign -s.wordcmd._$encode($tolower($1)).$0
	} {
		@ s.wordcmd._$encode($tolower($1)).$0 = [1]
	}
}
alias I.wordcmd.PUBLIC {I.wordcmd._hset PUBLIC $1 $0 % % $1" \{$2 $$0-\}}
alias I.wordcmd.ACTION {I.wordcmd._hset ACTION $1 $0 % % $1" \{$2 $$0-\}}
alias I.wordcmd.TOPIC {I.wordcmd._hset TOPIC $1 $0 % % $1" \{$2 $$0-\}}
alias I.wordcmd.MODE {I.wordcmd._hset MODE $1 $0 % % $1" \{$2 $$0-\}}
alias I.wordcmd.MSG {I.wordcmd._hset MSG $1 $0 % $1" \{$2 $$0 &$$N $$1-\}}
alias I.wordcmd.NOTICE {I.wordcmd._hset NOTICE $1 $0 % $1" \{$2 $$0 &$$N $$1-\}}
@ s.parms.wordcmd = 0
@ s.help.wordcmd.a = [Usage: $(s.C.UNDERL)$(K)i wordcmd \[\[<+|->\]  \]]
@ s.help.wordcmd.b = [ ]
@ s.help.wordcmd.c = [Where X can be PUBLIC, ACTION, TOPIC, MODE, MSG or NOTICE.]
@ s.help.wordcmd.d = [This creates a hook, activated whenever something matching]
@ s.help.wordcmd.e = ["pattern" is seen.  The ircII command is then executed, passing]
@ s.help.wordcmd.f = [the nick, channel and text as arguments.  Examples:]
@ s.help.wordcmd.g = [ ]
@ s.help.wordcmd.h = [Wordkick:  /i wordcmd +pub,action,topic *word* //kick $$1 $$0 bye]
@ s.help.wordcmd.i = [PervertIg: /i wordcmd +msg *are*you*Fe* /ig $$0 ALL\;echo Ignoring $$0]
@ s.help.wordcmd.j = [ ]
@ s.help.wordcmd.k = [If no parameters are given, a list of hooks is displayed.]
@ s.help.wordcmd.l = [Note:  Only one action can be associated with each pattern.]
alias I.wordcmd {
	@ s.wct = ["]
	if (rmatch($0 +% -%)) {
		^alias i.wordcmd._set \{eval I.wordcmd.$s.c2c(, $$(s.C.SPACE)$$$$0-\\\;I.wordcmd. $mid(1 -1 $0)) $$$$0-\}
		if ([$left(1 $0)]==[-]) {
			@ s.wct = [-"]
			@ s.wca = []
		} {
			@ s.wca = [ \{$2- \;#\}]
		}
		@ s.wcw = [$1]
	} {
		^alias i.wordcmd._set \{I.wordcmd.PUBLIC $$0-\}
		@ s.wcw = [$0]
		@ s.wca = [ \{$1- \;#\}]
	}
	if (([$s.wcw]!=[]) && (!match($s.wca {}))) {
		@ s.wcl = [$strip(" $s.wct)s.wordcmd._$encode($tolower($s.wcw))]
		^alias $(s.wcl)$(s.wca)
		^assign $(s.wcl)$(s.wca)
		i.wordcmd._set $s.wct $s.wcw $s.wcl
	} {
		@ s.wcc = [s.echo $(s.C.BOLD)Words:\;@ s.wcc = [#]]
		foreach s.wordcmd s.XX {
			@ s.wct = []
			foreach s.wordcmd.$(s.XX) s.YY {
				@ s.wct = s.wct ## [,$s.YY]
			}
			eval $s.wcc
			s.echo $[-14]decode($mid(1 -1 $s.XX)) \($mid(1 -1 $s.wct)\): $(s.wordcmd.$(s.XX))
		}
		if ([$s.wcc]!=[#]) {
			s.echo No word-activated commands have been set.  Try $(s.C.UNDERL)/i help wordcmd
		}
	}
}

###
##  Overrides to keep people from flooding themselves (by accident),
#    or just to make life a bit easier..
#
@ s.parms.query = 0
@ s.help.query.a = [Slightly enhanced $(s.C.UNDERL)$(K)query$(s.C.UNDERL) command, see $(s.C.UNDERL)$(K)help query]
@ s.help.query.b = [+ Sets window name so message styling works with queries.]
alias i.query {
	if ([$0]==[]) {
		$(K)$(K)query
		^window name $rand(9)$rand(9)$rand(9)
	} {
		$(K)$(K)query $0
		^window name $strip(= $0)
	}
}
@ s.parms.mode = 0
@ s.help.mode.a = [Slightly enhanced $(s.C.UNDERL)$(K)mode$(s.C.UNDERL) command, see $(s.C.UNDERL)$(K)help mode]
@ s.help.mode.b = [+ Defaults to current channel if none specified.]
alias i.mode {
	if ([$N]!=[$0]) {
		@ s.tch = [$s.channel($0)]
		$(K)$(K)quote MODE $s.tch $($(s.0)-)
	} {
		$(K)$(K)mode $0-
	}
}
@ s.parms.join = 0
@ s.help.join.a = [Slightly enhanced $(s.C.UNDERL)$(K)join$(s.C.UNDERL) command, see $(s.C.UNDERL)$(K)help join]
@ s.help.join.b = [+ Prefixes # character to incomplete channel names.]
alias i.join {
	if ([$0]!=[]) {
		if ((ischannel($0)) || (match(-I% $0))) {
			$(K)$(K)join $0 $1-
		} {
			$(K)$(K)join #$0 $1-
		}
	} {
		$(K)$(K)join
	}
}
@ s.parms.leave = 0
@ s.help.leave.a = [Slightly enhanced $(s.C.UNDERL)$(K)leave$(s.C.UNDERL) command, see $(s.C.UNDERL)$(K)help leave]
@ s.help.leave.b = [+ Default is to leave current channel.]
alias i.leave {
	if ([$0]!=[]) {
		if (ischannel($0)) {
			$(K)$(K)leave $0
		} {
			$(K)$(K)leave #$0
		}
	} {
		$(K)$(K)leave *
	}
}
@ s.parms.topic = 0
@ s.help.topic.a = [Slightly enhanced $(s.C.UNDERL)$(K)topic$(s.C.UNDERL) command, see $(s.C.UNDERL)$(K)help topic]
alias i.topic {
	if ([$0]!=[]) {
		if (ischannel($0)) {
			$(K)$(K)topic $0 $1-
		} {
			$(K)$(K)topic $C $0-
		}
	} {
		$(K)$(K)topic $C
	}
}
@ s.parms.names = 0
@ s.help.names.a = [Slightly enhanced $(s.C.UNDERL)$(K)names$(s.C.UNDERL) command, see $(s.C.UNDERL)$(K)help names]
@ s.help.names.b = [+ Less likely to flood you, default is list for current channel.]
alias i.names {
	s.DeathScroll names $0-
}
@ s.parms.list = 0
@ s.help.list.a = [Slightly enhanced $(s.C.UNDERL)$(K)list$(s.C.UNDERL) command, see $(s.C.UNDERL)$(K)help list]
@ s.help.list.b = [+ Less likely to flood you, default is list for current channel.]
alias i.list {
	s.DeathScroll list $0-
}
@ s.parms.who = 0
@ s.help.who.a = [Slightly enhanced $(s.C.UNDERL)$(K)who$(s.C.UNDERL) command, see $(s.C.UNDERL)$(K)help who]
@ s.help.who.b = [+ Less likely to flood you, default is list for current channel.]
alias i.who {
	s.DeathScroll who $0-
}

## End of core external aliases.


##############################################################################
###[ INTERACTIVE CONFIGURATION ]##############################################
##############################################################################
##
##  No hooks.  Just some very coooooooooooooooool scripting.
##  (I'm proud of this one.  Idea and code by ME, Juggler :)
##
##  And I did this BEFORE SrFrog did!  SO THERE! :)
##

###
##  Internal aliases..
#
alias s.iset.set {
	s.echo $1 = [$2-]
	@ $0.$1 = [$2-]
}
alias s.iset.show {
 	@ s.iset.tmp = [$word(0 $s.iset.list)]
	^parsekey erase_line
	^set STATUS_FORMAT  $s.iset.tmp %> $($(s.iset.pre).$(s.iset.tmp).d)
	TIMER 0 ^xtype -LITERAL $($(s.iset.pre).$(s.iset.tmp))
}
alias s.iset.send {
	@ s.iset.setted = 1
	s.iset.cmd $word(0 $s.iset.list) $L
	s.rotate s.iset.list 1
	s.iset.show
}
alias s.iset.done {
	^parsekey erase_line
	if (!s.iset.submenu) {
		^set STATUS_FORMAT $s.iset.kf
		if ([$s.iset.ip]!=[]) {
			^set INPUT_PROMPT $s.iset.ip
		} { 	^set -INPUT_PROMPT
		}
		i.rebind PARSE_COM *S.ISET*-1* -Q BACKWARD_HISTORY
		i.rebind PARSE_COM *S.ISET.*1* -Q FORWARD_HISTORY
		i.rebind PARSE_COM *ISET.DONE* -Q NEXT_WINDOW
		i.rebind PARSE_COM *ISET.SEND* -Q SEND_LINE
		^bind ^I $s.iset.oldtab
		^bind ^C $s.iset.oldqui
		s.echo No longer in edit mode...
	}
	if (([$s.iset.svf]!=[-]) && (s.iset.setted)) {
		input "Save the changes to file?  [YES/no] " if (!match(n% $0)) \{i.save $s.iset.svf\}
		eval $(s.rehashcmds.$(s.iset.svf))
	}
}
alias s.iset.setvar {
	@ s.iset.setted = 0
	@ s.iset.list = []
	@ s.iset.svf = [$0]
	@ s.iset.pre = [$1]
	^alias s.iset.cmd \{$2-\}
	foreach $1 XX {
		@ s.iset.list = [$s.iset.list $(XX)]
	}
}
## s.iset  
#
alias s.iset {
	if (!s.iset.submenu) {
		s.echo Entering edit mode..
		@ s.iset.oldtab = [$s.getbind(^I)]
		@ s.iset.oldqui = [$s.getbind(^C)]
		^bind ^I parse_command s.iset.done
		^bind ^C parse_command s.iset.done
		i.rebind FORWARD_HISTORY * -Q parse_command s.rotate s.iset.list 1\;s.iset.show
		i.rebind BACKWARD_HISTORY * -Q parse_command s.rotate s.iset.list -1\;s.iset.show
		i.rebind SEND_LINE * -Q parse_command s.iset.send
		@ s.iset.kf = [$STATUS_FORMAT]
		@ s.iset.ip = [$INPUT_PROMPT]
		s.echo Press $(s.C.BOLD)TAB$(s.C.BOLD) (^I) when you are finished.
	}
	s.iset.setvar $0-

	^set INPUT_PROMPT = $()
	s.iset.show
}

@ s.iset.l.CFG        = [SETTINGS .. Customize the script's settings.]
@ s.iset.l.cfg.d      = [$s.TIS_VERSION]
@ s.iset.l.cfg.cmd    = [s.iset.setvar cfg s.set i set]

@ s.iset.l.LISTS      = [LISTS ..... Edit the internal lists.]
@ s.iset.l.lists.d    = [$s.TIS_VERSION]
@ s.iset.l.lists.cmd  = [s.iset.setvar lists s.list i lists set]

@ s.iset.l.LOAD       = [LOAD ...... What parts of the script are loaded.]
@ s.iset.l.load.d     = [$s.TIS_VERSION]
@ s.iset.l.load.cmd   = [s.iset.setvar load s.cfg.load s.iset.set s.cfg.load]

@ s.iset.l.MISC       = [MISC ...... Noises, messages, technical stuff.]
@ s.iset.l.misc.d     = [$s.TIS_VERSION]
@ s.iset.l.misc.cmd   = [s.iset.setvar misc s.misc s.iset.set s.misc]

@ s.iset.l.HELP       = [HELP ...... Help on edit mode.]
@ s.iset.l.help.d     = [$s.TIS_VERSION]
@ s.iset.l.help.cmd   = [i help config]

alias s.iset.choose {
	@ s.iset.submenu = 0
	$(s.iset.l.$(0).cmd)
}

@ s.parms.config = 0
@ s.help.config.a = [Usage: $(s.C.UNDERL)$(K)i config \[lists|cfg|load|misc\]]
@ s.help.config.b = [ ]
@ s.help.config.c = [Activates edit mode, a comfortable way to configure TISii's behavior.]
@ s.help.config.d = [The status bar shows a short description of what you are editing.]
@ s.help.config.e = [Press TAB or ^I to leave edit mode when you are finished.]
@ s.help.config.f = [ ]
@ s.help.config.g = [You can select different variables the same way you would scroll]
@ s.help.config.h = [through the command history \(usually ^P or the cursor keys), and]
@ s.help.config.i = [accept changes with the ENTER key.  To cancel a change switch to]
@ s.help.config.j = [a different variable without pressing ENTER.]
@ s.help.config.k = [ ]
@ s.help.config.l = [$(s.C.BOLD)Note:$(s.C.BOLD)  0 means OFF, anything else (1 is good) means ON.]
alias I.config {
	@ s.iset.submenu = 0 
	if (match($0 lists cfg load misc)) {
		s.iset $s.wordfrom(1 $(s.iset.l.$(0).cmd))
	} {	s.iset - s.iset.l s.iset.choose
	}
}
@ s.help.set.zzzz = [+ For interactive configuration, type $(s.C.UNDERL)/i config]
@ s.help.lists.zz = [+ For interactive configuration, type $(s.C.UNDERL)/i config]


##############################################################################
###[ REFORMAT OUTPUT ]########################################################
##############################################################################
##
##  Level #00 hooks:	join msg send_msg dcc_chat send_dcc_chat window
##			notice send_notice public public_other public_msg
##
##  To silence a reformatted message, use a negative serial number
##  and set "s.silent" to 1.  (Note: done automatically by s.wxecho)
##  If things aren't reformatted, you cannot silence them.
##

if (s.cfg.load.REFORMAT_CHANNELS) {

^set show_channel_names off

@ s.misc.public.d       = [How to display public (channel) traffic.]
@ s.misc.public_other.d = [How to display channels with no window.]
@ s.misc.public_msg.d   = [How to display messages sent to channels.]
@ s.misc.join.d         = [How to show you who just joined your channel.]
@ s.misc.public       = [<$(s.C.CHIGH)$$(0)$(s.C.CHIGH)>]
@ s.misc.public_other = [$$1 <$(s.C.CHIGH)$$(0)$(s.C.CHIGH)>]
@ s.misc.public_msg   = [$$1 <$(s.C.CHIGH)$$(0)$(s.C.CHIGH)>]
@ s.misc.join         = [Joined $$(1): $$[9]0 \\\($$userhost()\\\)]

alias s.rehash.public {
	^on #^join 00 * \{if (!s.silent) \{s.rxecho CRAP $s.misc.join\;if ([$0]==[$N]) {names $1}\}\{@ s.silent = 0\}\}
	^on #^public_other 00 * \{s.wxecho PUBLIC # $s.misc.public_other $$2-\}
	^on #^public       00 * \{s.wxecho PUBLIC # $s.misc.public $$2-\}
	^on #^public_msg   00 * \{s.wxecho PUBLIC # $s.misc.public_msg $$2-\}
}
@ s.rehashcmds.MISC = s.rehashcmds.MISC ## [\;s.rehash.public]

} ## End of channel reformatting.

if (s.cfg.load.REFORMAT_MESSAGES) {

@ s.misc.msg.d      = [How to display messages.]
@ s.misc.send_msg.d = [How to display sent messages.]
@ s.misc.msg        = [*$(s.C.PHIGH)$$(0)$(s.C.PHIGH)*]
@ s.misc.send_msg   = [*> *$(s.C.PHIGH)$$(0)$(s.C.PHIGH)*]

@ s.misc.dcc_chat.d      = [How to display DCC messages.]
@ s.misc.send_dcc_chat.d = [How to display sent DCC messages.]
@ s.misc.dcc_chat        = [=$(s.C.PHIGH)$$(0)$(s.C.PHIGH)=]
@ s.misc.send_dcc_chat   = [=> =$(s.C.PHIGH)$$(0)$(s.C.PHIGH)=]

@ s.misc.notice.d      = [How to display notices.]
@ s.misc.send_notice.d = [How to display sent notices.]
@ s.misc.notice        = [-$(s.C.PHIGH)$$(0)$(s.C.PHIGH)-]
@ s.misc.send_notice   = [-> -$(s.C.PHIGH)$$(0)$(s.C.PHIGH)-]

alias s.rehash.messages {
	^alias s.ShowMsg \{s.wxecho MSGS $$0 $s.misc.msg $$1-\}
	^on #^msg      00 * \{s.wxecho MSGS $$0 $s.misc.msg $$1-\}
	^on #^send_msg 00 * \{s.wxecho MSGS $$0 $s.misc.send_msg $$1-\}

	^alias s.ShowDMsg \{eval s.wxecho MSGS $$0 $s.misc.dmsg $$1-\}
	^on #^dcc_chat      00 * \{s.wxecho MSGS $$0 $s.misc.dcc_chat $$1-\}
	^on #^send_dcc_chat 00 * \{s.wxecho MSGS $$0 $s.misc.send_dcc_chat $$1-\}

	^alias s.ShowNotice \{s.wxecho NOTICES $$0 $s.misc.notice $$1-\}
	^on #^notice      00 * \{s.wxecho NOTICES $$0 $s.misc.notice $$1-\}
	^on #^send_notice 00 * \{s.wxecho NOTICES $$0 $s.misc.send_notice $$1-\}
}
@ s.rehashcmds.MISC = s.rehashcmds.MISC ## [\;s.rehash.messages]

#### ELSE
} {

alias s.ShowMsg {xecho -LEVEL MSGS *$(0)* $1-}
alias s.ShowDMsg {xecho -LEVEL MSGS =$(0)= $1-}
alias s.ShowNotice {xecho -LEVEL NOTICES $(s.C.JUNK)-$(0)- $1-}

} ## End of message reformatting. 

alias s.reformat_window {
       	@ s.c2s1 = [$1-]
       	@ s.c2s2 = index($(s.C.CTRLC) $1-)
       	@ s.c2s3 = []
  	while (s.c2s2 != -1) {
		if ([$mid($s.c2s2 1 $s.c2s1)] == [$(s.C.CTRLC)]) {
	       		@ s.c2s3 = s.c2s3 ## [$left($s.c2s2 $s.c2s1)$(s.C.REVERSE)]
	       	} {
	       		@ s.c2s3 = s.c2s3 ## [$left($s.c2s2 $s.c2s1)$(s.C.CTRLC)]
	       	}
	       	while (match($mid(${s.c2s2 + 1} 1 $s.c2s1) 0 1 2 3 4 5 6 7 8 9 ,)) {
	       		@ s.c2s2 = s.c2s2 + 1
	       	}
	       	@ s.c2s1 = mid(${s.c2s2 + 1} -1 $s.c2s1) 
       		@ s.c2s2 = index($(s.C.CTRLC) $s.c2s1)
	}
	xecho -WINDOW $0 $s.c2s3$s.c2s1
}
alias s.set.reformat_window {
	if (s.set.reformat_window) {
		eval ^on #^window 00 "% *$(s.C.CTRLC)*" {s.reformat_window $0-}
	} {	eval ^on #^window 00 -"% *($s.C.CTRLC)*"
	}
}
@ s.set.reformat_window.d = [Clean up mIRC color codes 'n stuff.  0..OFF, 1..ON]
@ s.set.reformat_window = 0
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.reformat_window]

# Send an irritating ircII warning to /dev/null.  Just about everything
# I do sets this off. :-)  But while the client doesn't crash....
#
^on #^window 00 "% --- Recursive call to irc_io() - careful" #



##############################################################################
###[ MSG HISTORY ]############################################################
##############################################################################
##
##  Hooks:	msg, send_msg, dcc_chat, send_dcc_chat, public, send_public 
##		notice, send_notice (#70)
##
if (s.cfg.load.MSG_HISTORY || s.cfg.load.EMULATE_TABKEY) {

###
##  Assigns   (default is 12 history slots, raise value for more :)
#
@ s.list.mhist.d    = [Message history buffer]
@ s.list.mhist      = []
@ s.list.complete.d = [Commands completed by the message history hotkey.]
@ s.list.complete   = [msg dmsg describe whois notice ctcp ping ignore query]
@ s.misc.maxnicks.d = [Maximum number of nicks in nick history buffer.]
@ s.misc.maxnicks   = 12

###
##  Key Bindings
#
# The following is binding the ircII default, so I don't feel too bad
# about enabling it..
#
^bind ^X META2_CHARACTER
#
if (s.cfg.load.EMULATE_TABKEY) {
	^bind ^I parse_command eval I.nicklist.ng\;S.rotate s.list.mhist 1
	^bind ^R parse_command eval I.nicklist.ng\;S.rotate s.list.mhist -1
	^alias nicklist I.nicklist
	^alias addnick I.nicklist.na
	@ s.help.emulation.0tk = [TABKEY     See $(s.C.UNDERL)/help load tabkey$(s.C.UNDERL) and $(s.C.UNDERL)/i help nicklist]
	@ s.help.aliases.tk    = [tabkey:     nicklist, addnick]
	@ s.help.nicklist.k1   = [Keys:  ^R / TAB  Get last/current nick and rotate list.]
} {
	^bind ^R parse_command I.nicklist.ng
	^bind ^P parse_command eval S.rotate s.list.mhist 1\;I.nicklist.ng
	^bind ^O parse_command eval S.rotate s.list.mhist -1\;I.nicklist.ng
	@ s.help.nicklist.k1 = [Keys:  ^R         Get the current nick, completes command.]
	@ s.help.nicklist.k2 = [       ^P / ^O    Get last/next nick, and rotate list.]
}
^bind ^X^P parse_command I.nicklist.cr 1
^bind ^X^O parse_command I.nicklist.cr -1
^bind ^X^X parse_command I.nicklist.nd $$word(1 $L)
@ s.help.nicklist.k3 = [     ^X^X         Delete nick on command line from list.]
@ s.help.nicklist.k4 = [     ^X^P / ^X^O  Get current nick, and rotate command list fwd/back.]

###
##  External aliases
#

alias I.nicklist.na {
	if ([$0] != []) {
		@ s.na = match($0 $s.list.mhist)
		if (s.na) {
			@ s.list.mhist = [$strip(@ $0 $s.notWord(${s.na - 1} $s.list.mhist))]
		} {	@ s.list.mhist = [$strip(@ $s.WordTo($s.misc.maxnicks $0 $s.list.mhist))]
		}
	}
}
alias I.nicklist.cr {
	S.Rotate s.list.complete $0
	^parsekey erase_line
	I.nicklist.ng
}
alias I.nicklist.ng {
	@ s.nicklast = [$s.c2s(, $word(0 $s.list.mhist))]
	@ s.tmp2 = [$match($strip($(K) $word(0 $L))% $s.list.complete)]
	if ((s.tmp2) && (match($(K)% $word(0 $L)))) {
		if (ischannel($word(1 $L)) && match(%: $word(2 $L))) {
			@ s.tmp3 = 3
		} {	@ s.tmp3 = 2
		}
		@ s.tmp = [$(K)$word(${s.tmp2 - 1} $s.list.complete) $(s.nicklast) $s.wordfrom($s.tmp3 $L)]
	} {	@ s.tmp = [$(K)$word(0 $s.list.complete) $(s.nicklast) $L]
	}
	^parsekey erase_line
	^xtype -LITERAL $s.tmp
}
alias I.nicklist.nd {
	if (match($0 $s.list.mhist) && ([$0] != [.])) {
		@ s.list.mhist = [$s.notword(${match($0 $s.list.mhist) - 1} $s.list.mhist)]
		if (!match(% $s.list.mhist)) {
			@ s.list.mhist = [@]
			^parsekey erase_line
		} {	I.nicklist.ng
		}
		S.echo Nickname $0 deleted from history.
	}
}
@ s.parms.nicklist = 0
@ s.help.nicklist.a = [Usage: $(s.C.UNDERL)$(K)i nicklist]
@ s.help.nicklist.b = [Displays the nicks in the message history.]
alias I.nicklist {
	@ s.tmp2 = [$strip(@ $s.list.mhist)]
	if ([$word(0 $s.tmp2)]!=[]) {
		@ s.tmp = [$#s.list.mhist] - 1
		S.echo Current: $(s.C.BOLD)$word(0 $s.list.mhist)$(s.C.BOLD)  History: $s.WordFrom(1 $s.list.mhist)
		S.echo $#s.tmp2 \(max $s.misc.maxnicks\) slots are occupied.
	} {	S.echo The message history is empty.
	}
}


###
##  Hooks..
#
alias S.Set.Msg_Hist {
	^on #-msg 70 -*
	^on #-send_msg 70 -*
	^on #-notice 70 -*
	^on #-send_notice 70 -*
	^on #-dcc_chat 70 -*
	^on #-send_dcc_chat 70 -*
	^on #-public 70 -*
	^on #-send_public 70 -*
	if ([$s.set.msg_hist] == [1]) {
		@ s.set.msg_hist = [msg notice dcc_chat public]
	}
	if (match(m% $s.set.msg_hist)) {
		^on #-msg      70 * {I.nicklist.na $0}
		^on #-send_msg 70 * {I.nicklist.na $0}
	}
	if (match(n% $s.set.msg_hist)) {
		^on #-notice      70 * {I.nicklist.na $0}
		^on #-send_notice 70 * {I.nicklist.na $0}
	}
	if (match(d% $s.set.msg_hist)) {
		^on #-dcc_chat      70 * {I.nicklist.na =$0}
		^on #-send_dcc_chat 70 * {I.nicklist.na =$0}
	}
	if (match(p% $s.set.msg_hist)) {
		^on #-public 70 * {if (match(%$N% $2-)) {I.nicklist.na $1,$0:}}
		^on #-send_public 70 * {if (match(%: $1)) {I.nicklist.na $0,$1}}
	}
}
@ s.set.msg_hist.d = [Listed events update msg hist.  1..ALL, 0..NONE ]
@ s.set.msg_hist = (s.cfg.load.MSG_HISTORY == 1)
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.msg_hist]

} ## End of msg history code.


##############################################################################
###[ FLOOD PROTECTION ]#######################################################
##############################################################################
##
##  Level #00 hooks:	raw_irc 
##  Other hooks:	msg/notice/invite/ctcp/ctcp_reply (#-71)
##
if (s.cfg.load.FLOOD_PROT) {

###
##  Assigns..
#
@ s.REF.LASTFLOOD = [880101 300]
@ s.REF.UNSILENCE = [880102 300]

@ s.FLOOD.COUNT = 0
@ s.misc.badflood.d = [It only takes one of these to activate flood prot..] 
@ s.misc.badflood   = [***** **\[**\[* **\]**\]*]

@ s.list.ok_flood.d = [Disables msg flood prot. for nick!user@host patterns.]
@ s.list.ok_flood = []

###
##  External aliases..
#
alias I.Flood.D {
	^on #^raw_irc 00 -"%$0 % % *"
	^on #-raw_irc 00 -"%$0 % #% *"
	^on #-raw_irc 00 -"%$0 % &% *"
	^timer -delete $(s.flooded.$encode($0).ref)
	S.Echo No longer silencing $(0), deleting flood data.
	S.UnAssign s.flooded.$encode($0)
	if ([$s.lastflood]==[$0]) {
		@ s.lastflood = []
	}
}
alias I.Flood.S.INVITE {S.rxecho CRAP $0 invited you to channel $mid(1 -1 $4)}
alias I.Flood.S.PRIVMSG {
	if (match(*:$(s.C.CTCP)* $4)) {
		if (match(??ACTION $4)) {
			xecho -LEVEL MSGS *> $s.nickonly($1) $strip($s.C.CTCP $5-)
		} {	S.rxecho CTCP CTCP $strip(:$(s.C.CTCP) $4) from $s.nickonly($1) ignored.
		}
	} {	s.ShowMsg $s.nickonly($1) $mid(1 -1 $4-)
	}
}
alias I.Flood.S.NOTICE {
	if (match(*:$(s.C.CTCP)* $4)) {
		S.rxecho CTCP CTCP $strip(:$(s.C.CTCP) $4) reply from $s.nickonly($1): $strip($s.C.CTCP $5-)
	} {	s.ShowNotice $s.nickonly($1) $mid(1 -1 $4-)
	}
}
alias I.Flood.P {
	S.Echo Displaying flood from $(0):
	@ s.lastecho = []
	@ s.tmp = [s.flooded.$encode($0)]
	@ s.tmp2 = [$($(s.tmp).txt.0)]
	@ s.XX = 1
	while ([$(s.tmp2)]!=[]) {
		I.Flood.S.$word(1 $s.tmp2) $($(s.tmp).who) $s.tmp2
		@ s.tmp2 = [$($(s.tmp).txt.$(s.XX))]
		@ s.XX = s.XX + 1
	}
}
alias I.Flood.S {
	I.Flood.P $0
	I.Flood.D $0
}
alias I.Flood.I {
	I.TmpIgnore *$0 600 ALL -PUBLIC
	I.Flood.D $0
}
alias I.Flood.L {
	@ s.tmp = 1
 	foreach s.flooded s.XX {
		if (s.tmp) {
			S.Echo Flooders being silenced:
			@ s.tmp = 0
		}
		if ([$s.lastflood]==[$decode($s.XX)]) {
			S.Echo   $decode($s.XX) $(s.C.BOLD)(most recent)
		} {	S.Echo   $decode($s.XX)
		}
	}
	if (s.tmp) {
		S.Echo Noone is being silenced.
	}
}
@ s.parms.flood = 1
@ s.help.flood.a = [Usage: $(s.C.UNDERL)$(K)i flood list|ignore|delete|print|show \[flooder\]]
@ s.help.flood.c = [ ]
@ s.help.flood.d = [  $(s.C.UNDERL)list             $(s.C.UNDERL)Prints a list of flooders being silenced.]
@ s.help.flood.e = [  $(s.C.UNDERL)ignore \[flooder\]$(s.C.UNDERL) Ignores "flooder" or the most recent flooder.]
@ s.help.flood.f = [  $(s.C.UNDERL)delete \[flooder\]$(s.C.UNDERL) Deletes flooder from list.]
@ s.help.flood.g = [  $(s.C.UNDERL)print  \[flooder\]$(s.C.UNDERL) Print stored flood data.]
@ s.help.flood.h = [  $(s.C.UNDERL)show   \[flooder\]$(s.C.UNDERL) Print data and delete flooder.]
@ s.help.flood.i = [ ]
@ s.help.flood.j = [Use $(s.C.UNDERL)/i set flood_prot.$(s.C.UNDERL) to set the flood protection's sensitivity.]
alias I.Flood {
	if (rmatch($0 l%)) {
		I.Flood.L
	} {
	    if (rmatch($0 d% s% i% p%)) {
	    	if ([$1]!=[]) {
			@ s.fv = [$s.getVariable(assign s.flooded.$encode($1))]
			if ([$#s.fv] == 1) {
				@ s.fn = [$decode($mid(${rindex(. $s.fv) + 1} -1 $s.fv))]
				I.Flood.$left(1 $0) $s.fn
			} {     if ([$#s.fv] > 1) {
					S.Echo $1 matches more than one flooder.  Try $(s.C.UNDERL)/i flood list
				} {     S.Echo No such flooder.  Try $(s.C.UNDERL)/i flood list
				}
			}
		} {     if ([$s.lastflood]!=[]) {
				I.Flood.$left(1 $0) $s.lastflood
			} {	S.Echo Try $(s.C.UNDERL)/i flood list
			}
		}
	    } {	S.Echo Try $(s.C.UNDERL)/i help flood$(s.C.UNDERL) or $(s.C.UNDERL)/i flood list
	    }
	}
}

###
##  Internal aliases
#
alias S.Flood.Line {
	#
	# Store up to 15 lines of flood..
	#
	@ s.flooded.$(0) = [$(s.flooded.$(0))] + 1
	@ s.flooded.$(0).txt.$(s.flooded.$(0).cnt) = [$1-]
	if ([$(s.flooded.$(0))] > 15) {
		#
		#  Minimize action if whoever it is keeps flooding, after 
		#  storing 15 lines.  This is ALMOST like auto-ignoring..
		#
		S.Echo 15 flood lines from $decode($0) stored, discarding remainder.
		^on #^raw_irc 00 "%$decode($0) % % *" #
	}
}
alias S.Flood.Hook {
	#
	# Silence the flood...
	#
	@ s.lastflood = [$1]
	@ s.FLOOD.COUNT = s.FLOOD.COUNT + 1
	@ s.flooded.$(2) = 1
	@ s.flooded.$(2).who = [$0]
	@ s.flooded.$(2).ref = [$word(0 $s.REF.UNSILENCE)$s.FLOOD.COUNT]
	@ s.flooded.$(2).txt.0 = [$0!$1 $3 $N :$s.lmsg]
	^on #^raw_irc 00 "%$1 % % *" \{s.flood.line $2 $$0-\}
	^on #-raw_irc 00 "%$1 % #% *" {comment}
	^on #-raw_irc 00 "%$1 % &% *" {comment}
	^timer -refnum $(s.flooded.$(2).ref) $word(1 $s.REF.UNSILENCE) I.Flood.D $0
	#
	# Warn the user, silence THIS flood line..
	#
	s.echo Flood detected by $(s.C.BOLD)$(1)$(s.C.BOLD) - silencing.
	s.echo Type $(s.C.UNDERL)/i flood see$(s.C.UNDERL) to display it, $(s.C.UNDERL)/i help flood$(s.C.UNDERL) for help.
	^on #^window 00 * #
	^timer 0 ^on #^window 00 -*
}
alias S.Flood.Count {
	@ s.tmp = [$encode($strip(~ $1))]
	@ s.lmsg = [$4-]
	if ((!rmatch($0!$1  $s.list.ok_flood)) && (!ischannel($2))) {
		if (rmatch($3$4$5$6$8  $s.misc.badflood)) {
			S.Flood.Hook $0 $1 $s.tmp $3
		} {	S.MassCheck s.FloodLines.$(s.tmp) 1 $s.fp.sense S.Flood.Hook $0 $1 $s.tmp $3
		}
	}
}

alias S.Set.Flood_prot.fix {
	#
	#  Set flood sensitivity ..
	#
	if ([$s.set.flood_prot] == 1) {
		@ s.set.flood_prot = [3 lines/per 2 seconds]
	}
	@ s.fp.sense = [$strip($s.NONNUMERICS $word(0 $s.set.flood_prot))]
	if (!s.fp.sense) {
		@ s.fp.sense = 3
	}
	@ s.tmp = [$strip($s.NONNUMERICS $word(2 $s.set.flood_prot))]
	if (!s.tmp) {
		@ s.tmp = 2
	}
	@ s.set.flood_prot = [$s.fp.sense lines/per $s.tmp seconds]
	@ s.fp.sense = [$s.fp.sense $s.tmp]
}
alias S.Set.Flood_prot {
	if (s.set.flood_prot) {
		S.set.flood_prot.fix
		#
		#  Enable flood protection..
		#
		^on #-notice -71 "*" {s.flood.count $0 $userhost() X NOTICE $1-}
		^on #-msg -71 "*" {s.flood.count $0 $userhost() X PRIVMSG $1-}
		^on #-ctcp -71 "*" {s.flood.count $0 $userhost() $1 PRIVMSG $(s.C.CTCP)$2-$(s.C.CTCP)}
		^on #-ctcp_reply -71 "*" {s.flood.count $0 $userhost() X NOTICE $(s.C.CTCP)$1-$(s.C.CTCP)}
		^on #-invite -71 "*" {s.flood.count $0 $userhost() X INVITE $1-}
	} {	^on #-notice -71 -"*"
		^on #-msg -71 -"*"
		^on #-ctcp -71 -"*"
		^on #-ctcp_reply -71 -"*"
		^on #-invite -71 -"*" 
	}
}
@ s.set.flood_prot.d = [Flood prot. sensitivity.  0..OFF, 1..DEFAULTS ]
@ s.set.flood_prot = (s.cfg.load.FLOOD_PROT == 1)
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.flood_prot]

###
##  Catch standard CTCP floods..
#
alias s.flood.ctcphook {
	@ s.tmp = s.uHostOnly($0)
	if ([$s.tmp] != [$s.lastflood]) {
		@ s.lmsg = [$3-]
		S.Flood.Hook $s.c2s(! $0) $encode($s.tmp) PRIVMSG
	}
}
alias s.set.no_ctcp_flood {
	if (s.set.no_ctcp_flood) {
		^eval on #^raw_irc 00 "%!% PRIVMSG % *$(s.C.CTCP)*$(s.C.CTCP)*$(s.C.CTCP)*" {s.flood.ctcphook $0-}
	} {	^eval on #^raw_irc 00 -"%!% PRIVMSG % *$(s.C.CTCP)*$(s.C.CTCP)*$(s.C.CTCP)*"
	}
}
@ s.set.no_ctcp_flood.d = [Quick CTCP protection, screws up /ignore.  0..OFF, 1..ON]
@ s.set.no_ctcp_flood = 0
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.no_ctcp_flood]

} ## End of flood protection


##############################################################################
###[ CLEAN UP DESYNCHED CHANNEL MESSAGES ]####################################
##############################################################################
##
##  Level #00 hooks:	raw_irc
##
##  .. Thanks to Aard for this idea. :-)

if (s.cfg.load.QUIET_DESYNCH) {

###
##  Assigns..
#
@ s.desynched = []

###
##  Hook (internal) aliases..
#
alias s.desynch.hook {
	if ([$0 $3]!=[$s.desynched]) {
		s.echo $3 is desynched on $0
		@ s.desynched = [$0 $3]
	}
}
alias S.set.quiet_desynch {
	if (s.set.quiet_desynch) {
		^on #^raw_irc 00 "% 404 % % :*" {s.desynch.hook $0-}
		^on #^raw_irc 00 "% 442 % % :*" {s.desynch.hook $0-}
	} {	^on #^raw_irc 00 -"% 404 % % :*"
		^on #^raw_irc 00 -"% 442 % % :*"
	}
}
@ s.set.quiet_desynch.d = [Decrease noise created by desynched channels?  1..YES, 0..NO ]
@ s.set.quiet_desynch = (s.cfg.load.QUIET_DESYNCH == 1)
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.quiet_desynch]

} ## End of desynch code.


##############################################################################
###[ CLEAN UP SPLIT SIGNOFFS ]################################################
##############################################################################
##
##  Level #00 hooks:	channel_signoff
##  Other hooks: 	timer/join (#-72)
##
##  .. Idea adopted from PhoEniX by Vassago.

if (s.cfg.load.QUIET_SPLIT) {

###
##  Internal variables..
#
@ s.SPLIT.COUNT = 0
@ s.REF.SPLIT = [88020 120]

###
##  External aliases
#
@ s.parms.whosplit = 0
@ s.help.whosplit.a = [Usage: $(s.C.UNDERL)$(K)i whosplit]
@ s.help.whosplit.d = [Displays a summary of who split in recent netsplits.]
alias I.whosplit {
	@ s.tmp = 1
	foreach s.SPLIT.NICKS s.ii {
		S.echo Split $decode($s.ii):  (nicks split)
		S.echo       $(s.SPLIT.NICKS.$(s.ii))
		@ s.tmp = 0
	}
	if (s.tmp) {
		S.echo No netsplit detected.  (data may have expired)
	}
}

###
##  Hook (internal) aliases
#
alias S.split.so {
	@ s.tmp = [s.SPLIT.NICKS.$encode($2<->$3)]
	if ([$($s.tmp)]==[]) {
                S.echo Netsplit \($3\) detected\; $(s.C.UNDERL)$(K)i whosplit$(s.C.UNDERL) to see who left.
	}
	if (!match($1 $($s.tmp))) {
		@ $(s.tmp) = [$($s.tmp) $1]
		@ $(s.tmp).WHEN = [$time()]
	}
}
alias S.split.jn {
	foreach s.SPLIT.NICKS s.ii {
		@ s.tmp = [s.SPLIT.NICKS.$s.ii]
		@ s.tmp2 = [$match($0 $($(s.tmp)))]
		if (s.tmp2) {
			@ s.silent = 1
			@ $(s.tmp) = [$s.notWord(${s.tmp2 - 1} $($(s.tmp)))]
			@ $(s.tmp).WHEN = [$time()]
			if (!match(% $($(s.tmp)))) {
				^assign -$(s.tmp)
				^assign -$(s.tmp).WHEN
			}
		}
	}
}
alias S.split.timer {
	foreach s.SPLIT.NICKS s.ii {
		@ s.tmp = [s.SPLIT.NICKS.$s.ii]
		if ([${time() - [$($(s.tmp).WHEN)]}] > 120) {
			^assign -$(s.tmp)
			^assign -$(s.tmp).WHEN
		}
	}
}
alias S.set.quiet_split {
	if (s.set.quiet_split) {
		^on #^channel_signoff 00 "% % %.% %.%" {s.split.so $0-}
	   	^on #^join -72 * {S.split.jn $0-}
	   	^on #^timer -72 * {S.split.timer}
	} {	^on #^channel_signoff 00 -"% % %.% %.%"
		^on #^join -72 -*
	   	^on #^timer -72 -*
	}
}
@ s.set.quiet_split.d = [Hide signoff/join messages caused by netsplits?  1..YES, 0..NO ]
@ s.set.quiet_split = (s.cfg.load.QUIET_SPLIT == 1)
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.quiet_split]

} ## End of split silencer.


##############################################################################
###[ CHANNEL POWER! ]#########################################################
##############################################################################
##
##  Level #-73 hooks:	mode, join, raw_irc, who, nick
##
if (s.cfg.load.CHANNEL_CODE) {

###
##  Shorthand..
#
alias ban i ban
alias unban i unban
alias kban {if (match(-% $0)) {i ban $C $(0)K $1-} {i ban $C -K $0-}}
alias bkick kban
alias um {i lmode $0 u}
alias lm {i lmode}
alias mop {i modenop $0 +o}
alias mdop {i modeop $0 -o}
alias mvop {i modenop $0 +v}
alias mdvop {i modeall $0 -v}
alias whowas i.nickcache -U

@ s.help.aliases.ppl0  = [$(s.help.aliases.ppl0), whowas]
@ s.help.aliases.ch2   = [            ban, kban, unban, lm=last mode, um=undo mode]
@ s.help.aliases.ch3   = [            mop=mass op, mvop, mdop, mdvop]

@ s.misc.kickmsg.d = [Message printed when you $(K)k or autokick someone.]
@ s.misc.kickmsg   = [Go away.]

###
##    External aliases..
#
@ s.parms.modeop = 1
@ s.help.modeop.a = [Usage: $(s.C.UNDERL)$(K)i modeOp [channel] <+|->]
@ s.help.modeop.d = [Performs a mode change on all channel ops (e.g. -o = massdeop).]
alias I.ModeOp {
	@ s.tch = [$s.channel($0)]
	s.LoopMode $s.tch $($s.0) $s.chops($s.tch)
}

@ s.parms.modenop = 1
@ s.help.modenop.a = [Usage: $(s.C.UNDERL)$(K)i modeNop [channel] <+|->]
@ s.help.modenop.d = [Performs a mode change on all op-less users (e.g. +v = massvop).]
alias I.ModeNOp {
	@ s.tch = [$s.channel($0)]
	s.LoopMode $s.tch $($s.0) $s.nchops($s.tch)
}

@ s.parms.modeall = 1
@ s.help.modeall.a = [Usage: $(s.C.UNDERL)$(K)i modeAll [channel] <+|->]
@ s.help.modeall.d = [Performs a mode change on everyone (e.g. +v = massvop).]
alias I.ModeAll {
	@ s.tch = [$s.channel($0)]
	s.LoopMode $s.tch $($s.0) $strip(@+ $s.names($s.tch))
}

@ s.parms.whocmd = 3
@ s.help.whocmd.a = [Usage: $(s.C.UNDERL)$(K)i whocmd [chnl] [s]<[n]nick|email|mask|full>  ]
@ s.help.whocmd.b = [ ]
@ s.help.whocmd.c = [Goes through the /WHO list on [chnl], and for each one comparing]
@ s.help.whocmd.d = [[status/]nick!user@host to the masks given.  It then executes ]
@ s.help.whocmd.e = [giving a list of nicks/email addresses/ban masks/nick!user@host as]
@ s.help.whocmd.f = [arguments.]
@ s.help.whocmd.g = [If you prefix the type with an 'S' then you can search by status]
@ s.help.whocmd.h = [(H@*+) as well.  Prefixing nick with an 'n' returns the nick list]
@ s.help.whocmd.i = [/names style, ex: sam joe @juggler +silly doofus]
@ s.help.whocmd.j = [ ]
@ s.help.whocmd.k = [Examples:   $(K)i whocmd #evil snick *@*/*.edu echo Chanops from *.edu: $$0-]
@ s.help.whocmd.l = [            $(K)i whocmd #evil snick *G*/*.* echo People who are away: $$0-]
alias I.WhoCmd {
	@ s.tch = [$s.channel($0)]
	^alias I.WhoCmd.C \{$(${s.0 + 2}-)\}
	I.WhoCmd.C $s.filtwho($s.tch $($s.0) $s.c2s(, $(${s.0 + 1})))
}

alias I.Ban.Kick {
	if ([$2]!=[]) {
		$(K)$(K)quote KICK $s.tch $0,$1,$2 :$s.misc.kickmsg
	} {
		if ([$1]!=[]) {
			$(K)$(K)quote KICK $s.tch $0,$1 :$s.misc.kickmsg
		} {
			$(K)$(K)quote KICK $s.tch $0 :$s.misc.kickmsg
		}
	}
	if ([$3]!=[]) {
		I.Ban.Kick $1-
	}
}
@ s.parms.ban = 0
@ s.help.ban.a = [Usage: $(s.C.UNDERL)$(K)i ban \[channel\] \[-E|K|P|D|N\] ]
@ s.help.ban.d = [Bans/kicks people from a channel.  The flags mean...]
@ s.help.ban.e = [    -K    Kick after ban.      -1    Ban nick!*user@host.]
@ s.help.ban.f = [    -D    Delayed kick.        -2    Ban *!*user@host.]
@ s.help.ban.g = [    -P    Permanent ban.       -3    Ban *!*user@*.host. (default)]
@ s.help.ban.h = [    -S    Screw ban.           -4    Ban *!*@host.]
@ s.help.ban.i = [    -N    No ban, kick only.   -5    Ban *!*@*.host.]
@ s.help.ban.k = [    -F    Faster, less complete kick code.]
@ s.help.ban.z = [Multiple flags MUST be combined, ex:  $(s.C.UNDERL)$(K)i ban #evil -2SD juggler]
alias I.Ban {
	@ s.tch = [$s.channel($0)]
	if (rmatch($($s.0) -%)) {
		@ s.t.arg = [$($s.0)]
		@ s.0 = s.0 + 1
	} {
		@ s.t.arg = [-]
	}
	if ([$($s.0)]!=[]) {
		s.mask.fix $s.t.arg $($(s.0)-) 
		if (match(% $s.mask.fix)) {
			if (!match(%F% $s.t.arg)) {
				@ s.mask.nicks = [$strip(@+ $s.nfilt($s.filtwho($s.tch nnick $s.mask.fix)))]
			}
			if (!match(%N% $s.t.arg)) {
				S.LoopMode $s.tch -o $strip(@ $s.chops)
				S.LoopMode $s.tch +b $s.mask.fix
			}
			if (match(% $s.mask.nicks)) {
				if (match(%D% $s.t.arg)) {
					timer 10 I.Ban.Kick $s.mask.nicks
				} {
					if (rmatch($s.t.arg %N% %K%)) {
						I.Ban.Kick $s.mask.nicks
					}
				}
			}
			if (match(%P% $s.t.arg)) {
				s.echo Warning:  The bans will NOT be automatically removed.
			} {
				timer 600 S.LoopMode $s.tch -b $s.mask.fix
			}
		}
	} {
		$(K)$(K)mode $s.tch b
	}
}

@ s.parms.nickcache = 1
@ s.help.nickcache.a = [Usage: $(s.C.UNDERL)$(K)i nickcache <-L|-D|-S|-U|-P> \[username\]]
@ s.help.nickcache.b = [Prints out stats (-S) about the nick cache and displays (-U) or]
@ s.help.nickcache.c = [deletes (-D) entries.  Can also list/purge (-L or -P) the whole cache.]
@ s.help.nickcache.d = []
@ s.help.nickcache.e = [The nick cache operates by caching information your client 'sees']
@ s.help.nickcache.f = [all the time, about the nicks you are associating with.  It]
@ s.help.nickcache.g = [rewrites the $(K)userhost command to use this cache for speed.]
alias I.NickCache {
	if (!match(-% $0)) {
		i nickcache
	}
	if ([$s.set.nick_cache] == [0]) {
		s.echo The nick cache is OFF: /I SET NICK_CACHE ON turns it on.
	}
       	@ s.tmp = [$(s.nick_cache.$tolower($encode($1)))]
       	if (match(-L $0)) {
       		foreach s.nick_cache s.ii {
       			s.echo $decode($s.ii) was last seen as $(s.nick_cache.$s.ii)
       		}
       	}
       	if (match(-D $0)) {
       		s.nick_cache.del $1
       		s.echo Removed $1 \($s.tmp\) from the nick cache.
       	}
       	if (match(-S $0)) {
       		@ s.tmp = 0 
       		foreach s.nick_cache s.ii {
       			@ s.tmp = s.tmp + 1
       		}
       		s.echo The nick-cache contains $s.tmp entries, and has had $s.nick_cache_hits hits.
	}
	if (match(-U $0)) {
	      	if ([$s.tmp] == []) {
	       	       	s.echo $1 is not in the cache.
	      	} {
       			s.echo $1 was last seen as $s.tmp
		}
	}
}

@ s.parms.lmode = 0
@ s.help.lmode.a = [Usage: $(s.C.UNDERL)$(K)i lmode \[channel\] [-U]]
@ s.help.lmode.b = [Redisplays the last mode change on a channel, or undoes it.]
alias I.LMode {
	@ s.tch = [$s.channel($0)]
	@ s.tmp = [$(s.lmode.$encode($tolower($s.tch)))]
	if (match(%U% $($s.0))) {
		$(K)$(K)quote MODE $s.tch $s.cXc(+ - $word(0 $s.tmp)) $s.wordfrom(1 $s.tmp) 
	} {
		s.echo Last mode change on $(s.tch): "$s.tmp"
	}
}

@ s.parms.unban = 1
@ s.help.unban.a = [Usage: $(s.C.UNDERL)$(K)i unban \[channel\] ]
@ s.help.unban.b = [ ]
@ s.help.unban.c = [Attempts to remove any bans on a user, if you specify his nick]
@ s.help.unban.d = [or bans on a group of users if you specify masks.  More than one]
@ s.help.unban.e = [nick or mask, or a combination is OK.]
alias I.UnBan {
	@ s.tch = [$s.channel($0)]
	s.mask.fix -1 $($(s.0)-)
	if (match(% $s.mask.fix)) {
		@ s.mask.bl.$encode($tolower($s.tch)) = s.mask.fix
		@ s.mask.ub.$encode($tolower($s.tch)) = []
		^stack push on 367
		^stack push on 368
		^on #^367 00 "% $s.tch *" \{if \(\(match\($$2 $$\(s.mask.bl.$encode($tolower($s.tch))\)\)\) || \(rmatch\($$2 $$\(s.mask.bl.$encode($tolower($s.tch))\)\)\)\) \{@ s.mask.ub.$encode($tolower($s.tch)) = \[$$\(s.mask.ub.$encode($tolower($s.tch))\)$$2 \]\}\}
		$(K)$(K)quote MODE $s.tch b
		^on #^368 00 "% $s.tch *" {
			^on #^367 00 -"% $1 *"
			^on #^368 00 -"% $1 *"
			^stack pop on 368
			^stack pop on 367
			@ s.tmpb = [$(s.mask.ub.$encode($tolower($1)))]
			if (match(% $s.tmpb)) {
				S.loopmode $1 -b $s.tmpb
			}
			^assign -s.mask.ub.$encode($tolower($1))
			^assign -s.mask.bl.$encode($tolower($1))
		}
	}
}


###
##  Internal aliases...
#
alias s.hide_nc_error {
	# Hide "*** : No such nick/channel"
	#  and "***   They aren't on that channel" errors.
	#
	^on #^401 00 $0* #
	^on #^441 00 $0* #
}

@ s.mask.screw = [azqxswcdevfrbgtnhymjukilop]
@ s.mask.type.1 = [$$2!*$$strip(~ $3)@$$4]
@ s.mask.type.2 = [*!*$$strip(~ $3)@$$4]
@ s.mask.type.3 = [$$s.wilduhost(* $3 $4)]
@ s.mask.type.4 = [*!*@$$4]
@ s.mask.type.5 = [*!*@$$S.host2banmask($4)]
@ s.mask.type.0 = s.mask.type.3
alias s.mask.hook {
	if ([$3]!=[]) {
		@ s.bant = rmatch($0 %1% %2% %3% %4% %5%)
		eval @ s.tmpb = [$(s.mask.type.$(s.bant))]
		if (match(%S% $0)) {
			@ s.tmpb = [$s.c2c(0123456789$mid($rand(14) 12 $s.ban.screw) ? $s.tmpb)]
		}
		@ function_return = [$s.tmpb]
	} {
		s.echo WARNING: Could not find $2 online..
		@ function_return = [$2!*@*]
	}
}
@ s.mask.fix.1 = [*$$($s.bann)*]
@ s.mask.fix.2 = [$$($s.bann)*]
@ s.mask.fix.3 = [*$$($s.bann)]
@ s.mask.fix.4 = [$$($s.bann)]
@ s.mask.fix.5 = [$$($s.bann)*@*]
@ s.mask.fix.6 = [*$$($s.bann)@*]
@ s.mask.fix.7 = [$$($s.bann)@*]
@ s.mask.fix.8 = [*!*$$($s.bann)*]
@ s.mask.fix.9 = [*!$$($s.bann)]
@ s.mask.fix.10 = [*!*@$$($s.bann)]
@ s.mask.fix.0 = s.mask.fix.1
alias s.mask.fix {
	# Prepare masks for proper banning and stuff..
	# .. /userhost's nicks automatically or fixes masks.
	#
	@ s.mask.fix = []
	@ s.mask.nicks = []
	@ s.bann = [$1-]
	@ s.bann = [$#s.bann]
	while (s.bann > 0) {
		@ s.bant = rmatch($($s.bann) !%@ %!%@ !%@% %!%@% %! !% %!% %@ %@% %.% %)
		if (s.bant == 11) {
			@ s.mask.nicks = s.mask.nicks ## [$($s.bann) ]
			userhost $($s.bann) -CMD @ s.banf = [$$s.mask.hook\($0 $s.tch $$0 $$3 $$4\) $$s.mask.fix]
		} {
			eval @ s.banf = [$(s.mask.fix.$(s.bant)) $$s.mask.fix]
		}
		@ s.mask.fix = s.banf
		@ s.bann = s.bann - 1
	}
	@ function_return = [$s.mask.fix]
}
alias s.names {
	^stack push on NAMES
	^on #^names 00 "$0 *" {@ s.nlist = [$1-]}
	$(K)$(K)names $0
	wait
	^on names -
	^stack pop on NAMES
	@ function_return = [$s.nlist]
}
alias s.chops {
	# Returns a list of OPped people.  Strips @ and + chars from nicks.
	#
	s.nfilt $s.names($0)
	@ function_return = [$strip(@+ $s.chops)]
}
alias s.nchops {
	# Returns a list of unOPped P-pl.  Strips @ and + chars from nicks.
	#
	s.nfilt $s.names($0)
	@ function_return = [$strip(@+ $s.nlist)]
}
alias s.filtwho.email {^eval on #^who 00 "$0 *" \{if \(rmatch\($$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$3@$$4 $$s.nlist\]\}\}}
alias s.filtwho.mask {^eval on #^who  00 "$0 *" \{if \(rmatch\($$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$s.wilduhost\(* $$3 $$4\) $$s.nlist\]\}\}}
alias s.filtwho.nick {^eval on #^who  00 "$0 *" \{if \(rmatch\($$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$1 $$s.nlist\]\}\}}
alias s.filtwho.nnick {^eval on #^who  00 "$0 *" \{if \(rmatch\($$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$strip\(HG* $$2\)$$1 $$s.nlist\]\}\}}
alias s.filtwho.full {^eval on #^who  00 "$0 *" \{if \(rmatch\($$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$1!$$3@$$4 $$s.nlist\]\}\}}
alias s.filtwho.Semail {^eval on #^who 00 "$0 *" \{if \(rmatch\($$2/$$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$3@$$4 $$s.nlist\]\}\}}
alias s.filtwho.Smask {^eval on #^who  00 "$0 *" \{if \(rmatch\($$2/$$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$s.wilduhost\(* $$3 $$4\) $$s.nlist\]\}\}}
alias s.filtwho.Snick {^eval on #^who  00 "$0 *" \{if \(rmatch\($$2/$$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$1 $$s.nlist\]\}\}}
alias s.filtwho.Snnick {^eval on #^who  00 "$0 *" \{if \(rmatch\($$2/$$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$strip\(HG* $$2\)$$1 $$s.nlist\]\}\}}
alias s.filtwho.Sfull {^eval on #^who  00 "$0 *" \{if \(rmatch\($$2/$$1!$$3@$$4 $1-\)\) \{@ s.nlist = \[$$1!$$3@$$4 $$s.nlist\]\}\}}
alias s.filtwho {
	# s.filtwho   
	# Returns a list of users on $0 who's nick!user@host matches one of
	# the specified patterns.  (This is *much* slower than s.names!)
	#
	@ s.nlist = []
	^stack push on WHO
	s.filtwho.$1 $0 $2-
	who $0
	wait
	^on who -
	^stack pop on WHO
	@ function_return = [$s.nlist]
}

###
##  Hook aliases.
#
alias s.channel.autorejoin {
	if ((s.set.auto_rejoin) && ([$3]==[$N])) {
		timer 1 join $2
		@ s.set.auto_rejoin = 0
		timer 10 @ s.set.auto_rejoin = 1
	}
}
alias S.set.auto_rejoin {
	if (s.set.auto_rejoin) {
		^on #-raw_irc -73 "% KICK % % :*" {s.channel.autorejoin $0-}
	} {
		^on #-raw_irc -73 -"% KICK % % :*"
	}
}
@ s.set.auto_rejoin.d = [Auto-rejoin channels after being kicked?  1..YES, 0..NO ]
@ s.set.auto_rejoin = s.cfg.load.CHANNEL_CODE.auto_rejoin
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.auto_rejoin]

alias s.nick_cache.add {
	@ s.nick_cache.$encode($tolower($0)) = [$1]
}
alias s.nick_cache.del {
	^assign -s.nick_cache.$encode($tolower($0))
}
alias S.set.nick_cache {
	if (s.set.nick_cache) {
		^on #-raw_irc -73 "%!%@% *" {s.nick_cache.add $s.nickonly($0) $s.ruhostonly($0)}
		^on #-raw_irc -73 "% 302 % :%=%@%" {s.nick_cache.add $mid(1 ${index(= $3) -1} $3) $mid(${index(= $3) +2} -1 $3)}
		^on #-who -73 * {s.nick_cache.add $1 $3@$4}
		^on #-nick -73 * {
			@ s.nick_cache.$encode($tolower($1)) = $(s.nick_cache.$encode($tolower($0)))
			^assign -s.nick_cache.$encode($tolower($0))
		}
		@ s.nick_cache_hits = 0
		^alias userhost {
			@ s.uhtmp = [$(s.nick_cache.$encode($tolower($0)))]
			if ([$s.uhtmp] != []) {
				if ([$1] == [-cmd]) {
					@ s.nick_cache_hits = s.nick_cache_hits + 1
					@ s.i = [$index(@ $s.uhtmp)]
					^alias s.tmp $2-
					^s.tmp $0 - - $left($s.i $s.uhtmp) $mid(${s.i + 1} -1 $s.uhtmp)
					^alias -s.tmp
				} {
					s.rxecho CRAP $0 is $s.uhtmp
				}
			} {
				$(K)$(K)userhost $0-
				wait
			}
		}
	} {
		^on #-raw_irc -73 -"%!%@% *"
		^on #-raw_irc -73 -"% 302 % :%=%@%"
		^on #-nick -73 -*
		^on #-who -73 -*
		^alias -userhost
	}
}
@ s.set.nick_cache.d = [Cache nick!user@host info?  1..YES, 0..NO ]
@ s.set.nick_cache = s.cfg.load.CHANNEL_CODE.nick_cache
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.nick_cache]

alias S.set.no_server_modes {
	if (s.set.no_server_modes) {
                ^on #^mode -73 "% % *" {
			if (match(%.% $0)) {
				$(K)$(K)quote MODE $1 $s.cXc(+ - $2) $3-
			} {
				@ s.lmode.$encode($tolower($1)) = [$2-]
			}
		}
        } {     ^on #^mode -73 "% % *" {@ s.lmode.$encode($tolower($1)) = [$2-]}
	}
}
@ s.set.no_server_modes.d = [Undo all mode changes from servers?  1..YES, 0..NO ]
@ s.set.no_server_modes = s.cfg.load.CHANNEL_CODE.no_server_modes
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.no_server_modes]


} ## End of channel code.


##############################################################################
###[ NOTIFY STUFF ]###########################################################
##############################################################################
##
##  Level #00 hooks:	notify_signon, notify_signoff
##
if (s.cfg.load.NOTIFY_STUFF) {

@ s.list.notify.d = [Special notify nick!user@host patterns.  Full nick req'd.]
@ s.list.notify   = []
@ s.misc.notify_on.d   = [Notify_signon messages. $$0 = nick, $$s.notify.info = u@h/ircop/away ]
@ s.misc.notify_on     = [Signed on: $$[9]0 \\\($$s.notify.info\\\)]
@ s.misc.notify_off.d  = [Notify_signoff message. $$0 = nick, $$1 = u@h/ircop ]
@ s.misc.notify_off    = [Signed off: $$[9]0 \\\(was $$s.notify.info\\\)]
@ s.not.1$encode(+) = [, an IrcOp]
@ s.not.2$encode(+) = [, $(K)away]

alias s.notified {
	@ s.notify.info = [$3@$4$(s.not.1$encode($1))$(s.not.2$encode($2))]
	if (match($0!* $s.list.notify)) {
		if (rmatch($0!$3@$4 $s.list.notify)) {
			eval s.rxecho CRAP $s.misc.notify_on
			@ s.notified.$encode($tolower($0)) = [$3@$4$(s.not.1$encode($1))]
		}
	} {
		eval s.rxecho CRAP $s.misc.notify_on
		@ s.notified.$encode($tolower($0)) = [$3@$4$(s.not.1$encode($1))]
	}
}

alias s.set.notify_stuff {
	if (s.set.notify_stuff) {
		^on #^notify_signon 00 * {
			if (!s.silent) {
				$(K)$(K)userhost $0 -cmd s.notified $$0-
			} {
				@ s.silent = 0
			}
		}
		^on #^notify_signoff 00 * {
			@ s.notify.info = [$(s.notified.$encode($tolower($0)))]
			^assign -s.notified.$encode($tolower($0))
			if ([$s.notify.info]!=[]) {
				eval s.rxecho CRAP $s.misc.notify_off
			}
		}
	} {
		^on #^notify_signon 00 -*
	}
}
@ s.set.notify_stuff.d = [Enhance notify messages?  1..YES, 0..NO ]
@ s.set.notify_stuff   = (s.cfg.load.NOTIFY_STUFF == 1)
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.notify_stuff]

} ## end of notify code


##############################################################################
###[ AWAY STUFF ]#############################################################
##############################################################################
##
##  Level #00 hooks:	channel_signoff, raw_irc
##  Other hooks:	idle (#74), 305 (#74,#75), 306 (#74,#75),
##			msg (#75), notice (#75), dcc_chat (#75)
##
if (s.cfg.load.AWAY_STUFF) {

###
##  Assigns
#
@ s.misc.awaystub.d = [This is appended to your $(K)AWAY message when logging.]
@ s.misc.awaystub   = [\[Logging Messages\]]
@ s.MLOGC = 0

###
##  Shorthand...
#
alias away i.away

###
##  External aliases
#
@ s.parms.messages = 0
@ s.help.messages.a = [Usage: $(s.C.UNDERL)$(K)i messages \[kill\]]
@ s.help.messages.d = [Displays and deletes messages that were logged while you were away.]
@ s.help.messages.e = [The "kill" parameters deletes messages without displaying them.]
alias I.Messages {
   if (s.MLOGC > 0) {
	if (!match(k% $0)) {
		s.echo $(s.C.BOLD)Logged messages:$(s.C.BOLD)   (deleting)
	} {
		s.echo Deleting logged messages.
	}
	foreach s.MLOG s.XX {
		if (!match(k% $0)) {s.echo  $(s.MLOG.$(s.XX))}
		^assign -s.MLOG.$(s.XX)
	}
	@ s.MLOGC = 0
   } {
	s.echo No messages have been logged.
   }
}
@ s.parms.away = 0
@ s.help.away.a = [Usage: $(s.C.UNDERL)$(K)i away \[message\]]
@ s.help.away.d = [Sets you away, and appends $s.misc.awaystub to the message.]
alias I.away {
	if (([$0-] != []) && (s.set.away_logging)) {
		$(K)$(K)away $0-  $(s.misc.awaystub)
	} {
		$(K)$(K)away $0-
	}
}

###
##  Internal aliases
#
alias s.away_lawg {
	@ s.mlog.$right(4 0000$(s.MLOGC)) = [\($Z\) $0$1$2$0 $3-]
	@ s.MLOGC = s.MLOGC + 1
}
alias S.away_hook {
    ^on #-timer 75 "*0" {/date}
	^on #-msg 75 "*" {s.away_lawg * $0 !$userhost() $1-}
	^on #-notice 75 "*" {s.away_lawg - $0 !$userhost() $1-}
	^on #-dcc_chat 75 "*" {s.away_lawg = $0 $(s.C.JUNK) $1-}
	^on #-305 71 "*" {
	    ^on #-timer 75 -"*0"
		^on #-msg 75 -"*"
		^on #-notice 75 -"*"
		^on #-dcc_chat 75 -"*"
		^on #-305 75 -"*"
		if (s.MLOGC) {
			S.echo Type $(s.C.UNDERL)$(K)i messages$(s.C.UNDERL) to read $(s.MLOGC) logged message(s).
		}
	}
}
alias S.set.away_logging {
	if (s.set.away_logging) {
		^on #-306 75 "*" {s.away_hook}
	} {
		^on #-306 75 -"*"
	}
}
@ s.set.away_logging.d = [Log messages while you are $(K)away?  1..YES, 0..NO ]
@ s.set.away_logging = (s.cfg.load.AWAY_STUFF == 1)
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.away_logging]

@ s.misc.auto_away_msg.d = [Auto away message. $$0 is idle time in minutes.]
alias S.fix_auto_away_msg {
	if (!match(% $s.misc.auto_away_msg)) {
		@ s.misc.auto_away_msg = [Idle for $$0 minutes .. ]
	}
}
@ s.rehashcmds.MISC = s.rehashcmds.MISC ## [\;S.fix_auto_away_msg]
alias S.auto_away {
	if ([$0] >= [$word(0 $s.set.auto_away)]) {
		if (([$word(0 $A)] == [Idle]) || ([$A]==[])) {
			if ([$A]==[]) {
 				^on #-306 74 "*" {
					^on #^raw_irc 0 "% 306 *" {comment}
					^on #-306 74 -"*"
				}
				^on #-305 74 "*" {
					^on #^raw_irc 0 -"% 306 *"
					^on #-305 74 -"*"
				}
			}
			eval I.away $s.misc.auto_away_msg
		}
	} {     if ([$word(0 $A)] == [Idle]) {away}
	}
}

alias S.set.auto_away {
	if ([$word(0 $s.set.auto_away)]) {
		@ s.set.auto_away = [$strip($s.NONNUMERICS $word(0 $s.set.auto_away))]
		if (s.set.auto_away < 1) {
			@ s.set.auto_away = 2 
		}
		@ s.set.auto_away = [$s.set.auto_away minute(s)]
		^on #^idle 74 * {S.auto_away $0-}
	} {
		^on #^idle 74 -*
		@ s.set.auto_away = 0
	}
}
@ s.set.auto_away.d = [Number of idle minutes before auto-away.  0..OFF ]
if (s.cfg.load.AWAY_STUFF == 1) {
	@ s.set.auto_away = 2
} {
	@ s.set.auto_away = 0
}
@ s.cfg.lastcmds = s.cfg.lastcmds ## [\;S.set.auto_away]

} ## End of /AWAY stuff.


##############################################################################
###[ TAH DAH!! ]##############################################################
##############################################################################

eval @ s.tmp = [$W]
eval ^cd $s.TIS_HOME
eval if ([$W]==[$s.tmp]) {
	^exec mkdir $s.TIS_HOME
	^sleep 1
	^cd $s.TIS_HOME
	eval if ([$W]==[$s.tmp]) {
		timer 2 s.echo WARNING:  Failed to create $(s.TIS_HOME), using $s.tmp instead.
		@ s.TIS_HOME = [$s.tmp]
	} {
		timer 2 s.echo Created $s.TIS_HOME for script save files.
	}
}
eval ^cd $s.tmp

if (s.cfg.load.LOADED_BLURB == 2) {
	eval S.echo Installed: $(s.C.BOLD)$s.TIS_VERSION$(s.C.BOLD) by Juggler/BTL
} {
    if (s.cfg.load.LOADED_BLURB) {
	eval echo ______________________________________________________________________________
	eval echo $(s.C.JUNK)
	eval echo         You have loaded $(s.C.BOLD)$(s.TIS_VERSION)$(s.C.BOLD) by Juggler/BTL
	eval echo                    Type $(s.C.UNDERL)$(K)i help$(s.C.UNDERL) for a list of commands.
	eval echo $(s.C.JUNK)
	eval echo WARNING:  This script is not finished, please don't expect anything to work.
	eval echo NOTE:     If you just upgraded from an older version, see: $(s.C.UNDERL)$(K)i help new
	eval echo ______________________________________________________________________________
	eval echo $(s.C.JUNK)
    }
}

##
##  Check if the script has been configured, and warn user if he hasn't 
##  done so..
##
@ s.loaded.configuration = 0
eval load $(s.TIS_HOME)/$word(0 $(s.save.file.CFG))
eval load $(s.TIS_HOME)/$word(0 $(s.save.file.LISTS))
eval load $(s.TIS_HOME)/$word(0 $(s.save.file.MISC))
eval eval $s.rehashcmds.CFG
eval eval $s.rehashcmds.LISTS
eval eval $s.rehashcmds.MISC

###
##   Configuration check..
#
if (!s.loaded.configuration) {
	
alias s.AutoCfg {
	s.echo
	s.echo Configure your script now!  Everything was loaded, but
	s.echo few things are active.  Use $(s.C.UNDERL)$(K)i config load$(s.C.UNDERL) to avoid loading
	s.echo things you never use in the future, or to enable emulation of other
	s.echo common IRC scripts, such as TABKEY.
	s.echo Read $(s.C.UNDERL)$(K) help$(s.C.UNDERL)!!
	s.echo
	i config cfg
	^alias -s.autocfg
}
input "Press ENTER for autoconfiguration (be sure to save!) . . . " s.autocfg

} ## Configuration check..

^assign -s.loaded.configuration
^assign -s.loaded.lists
^assign -s.loaded.load

eval timer 0 eval $s.cfg.lastcmds