Project

General

Profile

Scripting » History » Version 158

Per Amundsen, 08/14/2012 12:01 PM

1 149 Per Amundsen
h1. Notice: this is info for 1.8.10 and higher.
2 39 Per Amundsen
3 1 Per Amundsen
h1. Scripting
4
5 148 Per Amundsen
*[[Scripting BETA]] Click here to see scripting in the latest beta versions.*
6 1 Per Amundsen
7 149 Per Amundsen
You can write full scripts in Commands -> Edit Scripts or you can create one liners in Commands -> Edit Commands
8 38 Per Amundsen
9 149 Per Amundsen
h1. Custom Commands:
10 1 Per Amundsen
11 149 Per Amundsen
Custom Commands are created in Commands -> Edit Commands
12 1 Per Amundsen
13 149 Per Amundsen
Custom commands consists of differents ways to execute a script either by making your own command, or use a hotkey, you can also enter a full script as a one liner (for legacy reasons)
14 1 Per Amundsen
15 150 Per Amundsen
*Alias*
16 149 Per Amundsen
<pre>
17
/hello /msg $channel hello everybody
18
</pre>
19 1 Per Amundsen
20 149 Per Amundsen
This creates a alias named "/hello", everytime you type "/hello" the script "/msg $channel hello everybody" will be executed, you can use any script features here.
21 1 Per Amundsen
22 150 Per Amundsen
*Hot keys*
23 149 Per Amundsen
<pre>
24
Ctrl&r /msg $channel hello everybody i pressed 'ctrl' and 'r'
25
</pre>
26 1 Per Amundsen
27 149 Per Amundsen
Every time you press ctrl + r, the script "/msg $channel hello everybody i pressed 'ctrl' and 'r'" will be executed, you can use any script features her.
28 1 Per Amundsen
29 149 Per Amundsen
You can comment out a command by putting a # in front of it.
30 1 Per Amundsen
31 149 Per Amundsen
It is also possible to use a full script, but it has to be on one line, and the script editor is preferred.
32 1 Per Amundsen
33 149 Per Amundsen
h1. Scripts:
34 1 Per Amundsen
35 150 Per Amundsen
*Events:*
36 149 Per Amundsen
There are different ways to listen to the irc client/server events for legacy reasons.
37 158 Per Amundsen
On/OnEvent will be executed after the event
38
OnBefore/OnBeforeEvent will be executed before the event
39
40 149 Per Amundsen
<pre>
41
OnEvent if ($event == PRIVMSG) { /EXECUTE }
42
OnBeforeEvent if ($event == PRIVMSG) { /EXECUTE }
43 1 Per Amundsen
44 149 Per Amundsen
On PRIVMSG { /EXECUTE }
45
OnBefore PRIVMSG { /EXECUTE }
46 1 Per Amundsen
47 149 Per Amundsen
OnBefore OnCommand { /EXECUTE }
48
OnCommand /mode { /EXECUTE }
49
</pre>
50 1 Per Amundsen
51 150 Per Amundsen
*Available events:*
52 149 Per Amundsen
<pre>
53
OnLoad / Called when the script is loaded
54
OnUnload / Called when the script is unloaded
55
OnReload / Called when the script is reloaded
56
OnConnecting / Called when a server is connecting
57
OnLookingUp / Called when a server is looking up the hostname
58
OnConnected / Called when a server is connected
59
OnDisconnect / Called when a server gets disconnected
60
OnCommand / Called whenever a user types a /slash command in the client ($0- will hold the full command, $0 will be the first word, $1 the second and so on)
61 1 Per Amundsen
62 149 Per Amundsen
OnCTCPRequest / Called when a user recives a CTCP request
63
OnCTCPReply / Called when a user recives a CTCP reply
64
OnDCCRequest / Called when a user recived a DCC request
65 1 Per Amundsen
66 149 Per Amundsen
OnNickChanged / Called when a user's nick changes, will only trigger on the user unlike NICK who triggers for everyone
67
OnSongChanged / Called when a song is changed in the selected media player
68 1 Per Amundsen
69 149 Per Amundsen
OnDeVoice / Called when a user gets devoiced
70
OnVoice / Called when a user gets voiced
71
OnDeHop / Called when a user gets dehalfoppeed
72
OnHop / Called when a user gets halfopped
73
OnOp / Called when a user gets opped
74
OnDeOp / Called when a user gets deopped
75
OnDeOwner/ Called when a user gets owner deopped
76
OnOwner/ Called when a user gets owner opped
77
OnDeSop / Called when a user gets special deopped
78
OnSop / Called when a user gets special opped
79 1 Per Amundsen
80 149 Per Amundsen
MODE / Called whenever a channel or user mode is changed
81
JOIN / Called whenever a user joins a channel
82
PART / Called when a user parts a channel 
83
NICK / Called when a user changes their nick
84
TOPIC / Called when a topic is set/changed
85
KICK / Called when any user gets kicked
86
NOTICE / Called when any notice is recived
87
QUIT / Called when a user quits irc
88
PRIVMSG / Called when any message is recived
89
WHOIS / Called when any whois reply is recived
90
LIST / Called when a user gets a /list
91
KILL / Called when a user gets killed
92
ACTION / Called when a user recives a ACTION (/me) message
93 1 Per Amundsen
94 149 Per Amundsen
<irc numeric> / Called when a raw irc line with <irc numeric> is recived
95
<irc textual> / Called when a raw irc line with <irc textual> is recived
96
</pre>
97 1 Per Amundsen
98 150 Per Amundsen
*if/else if/else blocks:*
99 1 Per Amundsen
100 149 Per Amundsen
You can use any combination of if, else if, else and while
101
<pre>
102
OnEvent if ($event == PRIVMSG) { 
103
	if (%test == null) { 
104
		/echo Hello world
105
		if (%test == null) { 
106
			/echo Hello world
107
		}
108
		else /echo Hello World
109
	} else if (%test == null) { 
110
		/echo Hello world
111
	} else (%test == null) { 
112
		/echo Hello world 
113
	} 
114 1 Per Amundsen
115 149 Per Amundsen
	if (%test == null) { 
116
		/echo Hello world
117
		while (%test == null) {
118
			/echo Hello world
119
		}
120
	}
121 1 Per Amundsen
122 149 Per Amundsen
	if(%test == null)/echo Hello World
123
	else if(%test == null)/echo Hello World
124
	else/echo Hello world
125
	
126
	if(%test == null){/echo Hello World
127
	}else if(%test == null){/echo Hello World
128
	}else{/echo Hello World
129
	}
130 1 Per Amundsen
131 149 Per Amundsen
	if(%test == null){/echo Hello World}else if(%test == null){/echo Hello World}else{/echo Hello World}
132
}
133
</pre>
134 1 Per Amundsen
135 150 Per Amundsen
*while blocks:*
136 151 Per Amundsen
<pre>
137 149 Per Amundsen
On JOIN {
138
	var %t = 0
139
	/echo There are ($user($chan, 0)) users in ($chan)
140
	
141
	while (%t < $user($chan, 0)) {
142
		%t++
143
		var %nick = $user($chan, %t)
144
		/echo User (%t) is (%nick) and is $iif(%nick isop $chan, opped, not opped)
145
	}
146
}
147
</pre>
148 1 Per Amundsen
149 150 Per Amundsen
*goto/label:*
150 1 Per Amundsen
151
<pre>
152 149 Per Amundsen
OnCommand /goto {
153
	var %loop = 0 
154
	if ($1 == 1) {
155
		goto 1
156
	} else if ($1 == 2) {
157
		goto 2
158
	} else if ($1 == loop) {
159
		:3
160
		/echo you typed loop
161
		%loop++
162
		if (%loop < 5) {
163
			goto 3
164
		}
165
		return
166
	} else {
167
		goto 4
168
	}
169 1 Per Amundsen
170 149 Per Amundsen
	:1
171
	/echo You typed 1
172
	return
173
	:2
174
	/echo You typed 2
175
	return
176
	:4
177
	/echo The end
178
	return
179
}
180
</pre>
181 1 Per Amundsen
182 150 Per Amundsen
*client variables:*
183 152 Per Amundsen
<pre>
184 1 Per Amundsen
$event / current event, e.g PRIVMSG 001 MODE and so forth
185
$channel / the channel the event occurred on, if any
186
$msg / the message to the channel/user or the message in a raw irc line e.g whois [kr0n] is a registered nick
187
$nick / the nick the event was sent from, can be a irc.server.com, a nick or null
188
$me / my current nick
189
$network / the network the event occured on e.g Quakenet
190
$ident / the from user ident if any
191
$host / the from user hostname if any
192
$myident / my ident
193
$myhost / my host
194
$server / host from the server e.g irc.server.com
195 149 Per Amundsen
$now / returns unixtime/ctime from current time.
196
$active / returns the current window Status/#channel/Nick.
197
$activeserver / returns an id for current server
198
$status / returns current server status
199
$crlf / returns newline \r\n
200
$0-$9 / will return parts of the $msg, $<number>- will combine parts of the $msg from 0 to <number>. $0- will return everything
201
$! / returns how many $0 $1 etc variables are filled (not sure if final name of it)
202
$raw0-$raw9 / will return parts of the raw message, $raw<number>- will combine parts of the raw message from 0 to <number>. $raw0- will return everything
203 1 Per Amundsen
$r! / returns how many $raw0 $raw1 etc variables are filled (not sure if final name of it)
204 152 Per Amundsen
</pre>
205 153 Per Amundsen
*user set variables:*
206 149 Per Amundsen
var %variable = 4242, %variable2 = 4343; will create local variables that gets deleted when the script is done.
207
using += instead of = will append to the variable, if both variable and new value is numbers it will combine them to a new number %variable += 4242.
208 1 Per Amundsen
209 149 Per Amundsen
If a variable is created without var, the variable will be available to all scripts, saved to a file and restored when AdiIRC is started.
210
211 157 Per Amundsen
Commands for manipulating variables:
212 1 Per Amundsen
<pre>
213 149 Per Amundsen
/set {-u seconds/-d] [%var] [value] / create or update a variable with value -u seconds, will delete the variable after X seconds, -d will decrease its value by 1 every second, then remove it
214 1 Per Amundsen
215 149 Per Amundsen
/unset [var] / deletes a variable
216 1 Per Amundsen
217 149 Per Amundsen
/inc {-u seconds/-d] [%var] [value] / increases a variable with value (only if value and var is ints) -u seconds, will delete the variable after X seconds, -d will decrease its value by 1 every second, then remove it
218 1 Per Amundsen
219 149 Per Amundsen
/dec {-u seconds/-d] [%var] [value] / decreases a variable with value (only if value and var is ints) -u seconds, will delete the variable after X seconds, -d will decrease its value by 1 every second, then remove it
220 1 Per Amundsen
221 149 Per Amundsen
/vars shows a list of all variables and their values
222
</pre>
223 1 Per Amundsen
224 150 Per Amundsen
*functions:*
225 149 Per Amundsen
Several functions are exsists, they are all recursive and you can use any %variable or $variable as parameters:
226
They are also usable inside if () else if () while () statements.
227
All variable numbers are floats and all functions supports floats for precise calculations.
228 36 Per Amundsen
229
<pre>
230 149 Per Amundsen
$replace(text, text2, text3) / replace all occurrences of text2 in text with text3
231
$upper(text) / return text uppercase
232
$lower(text) return text lowercase
233
$mid(text, startpos, endpos) / return part of text from startpos to endpos
234
$substr(text, startpos, endpos) / return part of text from startpos to endpos
235
$left(text, pos) / return pos characters starting from left of the text
236
$right(text, pos) / return pos characters starting from right of the text
237
$remove(text, text2) / replace all occurrences of text2 from text
238
$len(text) / return length of text
239
$count(text, text2) / counts all occurrences of text2 in text
240
$pos(text, text2) / returns first occurrences position of text2 in text
241
$lastpos(text, text2) / returns last occurrences position of text2 in text
242
$strip(text) / removes all color and font tags
243
$repeat(text, times) / repeats text X times
244
$insert(text, text2, pos) / inserts text2 into pos of text
245
$chr(num) / returns ascii character from the number num
246
$char(num) / returns ascii character from the number num
247 1 Per Amundsen
248 149 Per Amundsen
$calc(formula) / calculate any variation of +-*/
249
$formatdate(date, text) / formats a unix timestamp into date using date variables %d %m %y etc
250
$fdate(date, text) / formats a unix timestamp into date using date variables %d %m %y etc
251
$ctime(datestamp) / converts most variations of a date stamp to unix/ctime
252
$datediff(ctime1, ctime2) / diffs two unix/ctime and fills the $datematch array with values
253
$datematch(num) / returns part of a $datediff, 0 = milliseconds, 1 = seconds, 2 = minutes, 3 = hours, 4 = days
254
$host(nick) / returns the hostmask of nick
255
$ident(nick) / returns the ident of nick
256
$(number) / dynamically gets a $0 $1 $2 variable e.g $(1) is same as $1 (not sure if final function name)
257
$cond(cond, execute1, execute2) / checks if cond is true then executes execute1, else executes execute2, will return string if not at the begining of the line
258
$iif(cond, execute1, execute2) / checks if cond is true then executes execute1, else executes execute2, will return string if not at the begining of the line
259
$round(num, decimals) / rounds down a float to X decimals
260
$regex(text, pattern) / does a regular expression test if text matches pattern, then returns the matched part
261
$regmatch(num) / returns the captured group at pos num from a $regex. 0 returns group count
262
$regreplace(text, pattern, text2) / replace any occurence in text of patterh with text2 where pattern is a regular expression
263 3 Per Amundsen
264 149 Per Amundsen
$file(path) / reads file to end and returns the entire output without newlines
265
$fileloop(path) / reads through a file one line at the time, line increases +1 every time the same file is called
266
$floop(path) / reads through a file one line at the time, line increases +1 every time the same file is called
267
$filerandom(path) / returns a random line from a file
268
$frand(path) / returns a random line from a file
269
$fread(name) / reads a line from current pos in file named name
270
$fileread(name) / reads a line from current pos in file named name
271
$freadc(name) / reads a char/byte from current pos in file named name
272
$freadchar(name) / reads a char/byte from current pos in file named name
273
$fsize(file) / returns size off file in bytes
274
$filesize(file) / returns size off file in bytes
275
$fpos(name) / returns current position/byte in file named name
276
$filepos(name) / returns current position/byte in file named name
277
$flines(file) / returns amount of lines in file
278
$filelines(file) / returns amount of lines in file
279
$fileexists(file) / returns if file exists or not
280
$isfile(file) / returns if file exists or not
281 1 Per Amundsen
282 149 Per Amundsen
$chan(num) / if num is 0 returns how many channels you are joined on this server else returns channel name in position num
283
$user(#chan, num) / if num is 0 returns how many users are on this #chan else returns nick in position num
284
$nick(#chan, num) / if num is 0 returns how many users are on this #chan else returns nick in position num
285
$server(num) / if num is 0 returns how many servers you are connected to else returns server id in position num
286 1 Per Amundsen
287 149 Per Amundsen
$sread(name) / reads available bytes from socket named name (on sockread)
288
$sockread(name) / reads available bytes from socket named name (on sockread)
289
$sbytes(name) / returns amount of available bytes to be read from socket named name
290
$sockbytes(name) / returns amount of available bytes to be read from socket named name
291 1 Per Amundsen
</pre>
292
293 158 Per Amundsen
*operators:*
294
295
All operators can use ! to reverse the logic e.g !ison. 
296
If no operators are added it will test if remaining text is not null if (%test), if ($channel) or if (!$channel) etc.
297
298
<pre>
299
> / Will try and cast left and right variable to int and try "int1 greater than int2"
300
< / Will try and cast left and right variable to int and try "int1 lower than int2"
301
>= / Will try and cast left and right variable to int and try "int1 greater than or equal to int2"
302
<= / Will try and cast left and right variable to int and try "int1 lower than or equal to int2"
303
isbetween / Will try and cast left variable to int and right variable have to be int-int, e.g "40 isbetween 30-50"
304
ison / check if ($nick ison $channel) nick is the channel
305
isop / check if ($nick isop $channel) is operator on the channel
306
ishop / check if ($nick ishop $channel) is half operator on the channel
307
issop / check if ($nick issop $channel) is special operator on the channel
308
isowner / check if ($nick isowner $channel) is channel owner
309
hasvoice / check if ($nick hasvoice $channel) have voice on the channel
310
inchan / check if i am in chan (#channel inchan) (#channel !inchan)
311
isnum / check something is a number (5 isnum) (5 !isnum)
312
ismatch / will check if left contains right value or right contains left value
313
isin / same as ismatch except only checking if left value is in right value, ismatch checks both
314
</pre>
315
316
*tips:*
317
/ is not needed to execute a command in scripts e.g /echo and echo is the same.
318
use null to check for nothing "if ($nick == null)"
319
Comment out a line with # or several lines with /* code */
320
321 155 Per Amundsen
h1. Example scripts
322 154 Per Amundsen
323
Simple kickcounter script:
324
325
<pre>
326
OnBefore OnCommand { 
327
	if ($0 != /kick)  return
328
		
329
	if (%kickcount == null) %kickcount = 0
330
331
	%kickcount++
332
		 
333
	if ($2 == null) { 
334
		/kick $channel $1 Kick number %kickcount
335
		halt
336
	} 
337
}
338
</pre>
339
340
Kickban example
341
<pre>
342
OnCommand /kb {
343
	if (!$1) {
344
		/echo /kb - Nick missing
345
		return
346
	}
347
348
	var %msg = $iif($channel, $2-, $3-)
349
	var %chan = $iif($channel, $channel, $2)
350
		
351
	# Set this for default ban reason, or remove for no default reason
352
	# Can be shortened to %msg = $iif(%msg, %msg, GTFO)
353
	if (%msg == null) %msg = GTFO
354
355
	if ($me isop %chan) {
356
		/raw MODE %chan +b *!$ident($1)@$host($1)
357
		/raw KICK %chan $1 %msg
358
	} 
359
	else /echo You are not oper on %chan
360
}
361
</pre>
362
363
Simple calculator script:
364
<pre>
365
OnCommand /calc {
366
	if (!$1) {
367
		/echo /calc - Parameters missing
368
		return
369
	}
370
		
371
	# typing /calc -p <expression> sends output to channel
372
	if ($1 == -p) {
373
		/msg $channel Calculating : $2-
374
		/msg $channel Result is : $calc($2-)
375
	} else {
376
		/echo Calculating : $1-
377
		/echo Result is : $calc($1-)
378
	}
379
}
380
</pre>
381
382
Colored version
383
<pre>
384
OnCommand /calc {
385
	if (!$1) {
386
		/echo /calc - Parameters missing
387
		return
388
	}
389
	
390
	# typing /calc -p <expression> sends output to channel
391
	if ($1 == -p) {
392
		/msg $channel $chr(3)4Calculating : $2-
393
		/msg $channel $chr(3)4Result is : $calc($2-)
394
	} else {
395
		/echo $chr(3)4Calculating : 4$1-
396
		/echo $chr(3)4Result is : $calc($1-)
397
	}
398
}*/
399
</pre>
400
401
CTCP flood detection example
402
403
<pre>
404
On OnCTCPRequest {
405
	if (%count == null) /set -u 10 %count 1
406
	else /inc -u 10 %count 1
407
408
	if (%count > 4) /ignore  -u 30 -t $nick!$ident@$host
409
}
410
</pre>
411
412
Mass mode example
413
414
<pre>
415
OnCommand /mass {
416
	if (!$2) {
417
		/echo /mass - Parameters missing [+/-<mode> <nick> <nick> <nick>]
418
		return
419
	}
420
421
	%len = 2
422
	
423
	# equal to while (%len <= $count(%0-, $chr(32)))
424
	while (%len <= $!) {
425
		if ($(%len) ison $channel) /mode $channel $1 $(%len)
426
		/inc %len
427
	}
428
}
429
</pre>
430
431
Shows info about servers, channels and users
432
<pre>
433
On JOIN {
434
	var %s = $server(0), %c = 0, %u = 0, %t = 0, %c2 = 0;
435
	
436
	while (%t < %s) {
437
		%t++
438
		/setserver $server(%t);
439
		%c += $chan(0)
440
	
441
		%c2 = 0
442
		while (%c2 < $chan(0)) {
443
			%c2++
444
			%u += $user($chan(%c2), 0)
445
		}
446
	}
447
448
	/echo You are on (%s) servers, (%c) channels with (%u) users
449
}
450
</pre>
451
452 156 Per Amundsen
It is possible to use scripts as functions.
453
These functions are fully nested like the client functions.
454 154 Per Amundsen
455
Lets say you make a /mycalc like this.
456
<pre>
457
OnCommand /mycalc {
458
	return $calc($0+$1);
459
}
460
</pre>
461
462
Then you can call this function with eiter /mycalc <number> <number> the normal way or $mycalc(<number, <number>)
463
Typing /testcalc will show the result.
464
<pre>
465
OnCommand /testcalc {
466
	/echo $0 + $1 is $mycalc($0, $1);
467
	/echo 5 + 4 is $mycalc(5, 4);
468
}
469
</pre>
470
471
Simple convert temperature C to F or F to C
472
/temp C 20 will print 68 F
473
474
<pre>
475
OnCommand /temp {
476
	if ($1 == C) /echo $calc(($2 * 9/5) + 32) F
477
	else if ($1 == F) /echo $round($calc(($2 - 32) * 5/9), 1) C
478
	else /echo Temp missing
479
}
480
</pre>
481
482
Test if input contains a link
483
<pre>
484
OnCommand /testlink {
485
	if (!$1) {
486
		/echo Link missing
487
		return
488
	}
489
490
	/echo $iif($regex($1, (?i)\\b((?:[a-z][\\w-]+:(?:/\{1\,3\}|[a-z0-9%])|www\\d\{0\,3\}[.]|[a-z0-9.\\-]+[.][a-z]\{2\,4\}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]\\\{\\\}\\\;:'".\,<>?«»“”‘’]))), yes, no)
491
}
492
493
</pre>
494
495
Retrives plot summary from captured imbd links
496
<pre>
497
On PRIVMSG {
498
	var %reg = $regex($0-, http://www\\.imdb\\.com(/title/[a-z0-9]+/))
499
	if (!%reg) { return }
500
		
501
	/sockclose imdb
502
	%text = null
503
	%imdb = $regmatch(1)plotsummary
504
	%imdbchan = $channel
505
	/sockopen imdb www.imdb.com 80
506
}
507
508
On SockOpen {
509
	if ($1 != imdb) { return }
510
511
	/sockwrite -n imdb GET %imdb HTTP/1.1
512
	/sockwrite -n imdb Host: www.imdb.com
513
	/sockwrite -n imdb User-Agent: Mozilla/5.0 (Windows NT 6.1\; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.24 Safari/536.5
514
	/sockwrite -n imdb Referer: http://www.imdb.com
515
	/sockwrite -n imdb Accept: text/xml,application/xml,application/xhtml+xml,text/html\;q=0.9,text/plain\;q=0.8,video/x-mng,image/png,image/jpeg,image/gif\;q=0.2,text/css,*\/*\;q=0.1
516
	/sockwrite -n imdb Accept-Language: en-us, en\;q=0.50
517
	/sockwrite -n imdb Connection: Close$crlf
518
}
519
520
On SockRead {
521
	if ($1 != imdb) { return }
522
		
523
	%text += $sockread(imdb)
524
}
525
526
On SockClose {
527
	if ($1 != imdb) { return }
528
	
529
	if ($regex(%text, <p class="plotpar">([\\s\\S]*?)<i>)) {
530
		/msg %imdbchan $regmatch(1)
531
	}
532
533
	%text = null
534
}
535
</pre>
536
537
An example showing the difference between dates
538
<pre>
539
OnCommand /test {
540
	$datediff($ctime(1/1 2042), $now)
541
	
542
	var %text = Difference is
543
	%text += $chr(32)$datematch(4) $iif($datematch(4) == 1, day, days)
544
	%text += $chr(32)$datematch(3) $iif($datematch(3) == 1, hour, hours) 
545
	%text += $chr(32)$datematch(2) $iif($datematch(3) == 1, minut, minutes) 
546
    
547
	/echo %text
548
}
549
</pre>
550 158 Per Amundsen
551
Announce song changes in a channel or to a user
552
<pre>
553
On OnSongChanged { 
554
	/nmsg <network> <channel/Nick> $0-
555
}
556
</pre>
557
558
Announce to several channels with:
559
<pre>
560
On OnSongChanged { 
561
	/nmsg <network> <channel1/Nick>,<channel2/Nick> $0-
562
	/nmsg <network2> <channel3/Nick> $0- 
563
}
564 154 Per Amundsen
</pre>