------ art_20344_4369595.1173621305310
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Code's slow :(
post's fast ;)
hopefully I find some time to profile and optimise the whole thing.
run.rb is the shell cmdline frontend
torus.rb is the freezer
ascii.rb and ppm.rb are two output plugins.
actually the output of the follwoing is nice already
rubr run.rb -f ascii 80 80 0.5 && \
for i in output/run-80-80.000000*.txt ; do clear; cat $i; sleep 1; done
GQView shows the ppm files nicely too and I guess lot's of other
viewers do but I did not mange to create movies on Linux yet, any
hints would be appreciated.
And before I forget
YET ANOTHER GREAT RUBY QUIZ :))
534/35 > cat run.rb
-------------------------
# vim: sw sts nu tw expandtab:
#
require 'fileutils'
require 'torus'
def usage msg il
$stderr.puts msg if msg
$stderr.puts <<-EOS
usage:
#{$0} [options] height width vapor_probability
options and their defaults
-s|--start <height>/2@<width>/2 where to put the initial freezer
please use Smalltalk syntax here
-n|--name run-<height>-<width> name of the output file
-v|--vapor 255/0/255 rgb value for PPM
O use strings for ASCII
-0|--vacuum 0/0/0 idem
<space>
-i|--ice 255/255/255 idem
*
-f|--format ppm ppm or ascii are supported
write your own plugins ;)
have fun
EOS
exit -1
end
@start name il
@vapor il
@vacuum il
@ice il
@format ppm"
options /^-f|^--format/ :format,
/^-s|^--start/ :start,
/^-n|^--name/ :name,
/^-v|^--vapor/ :vapor,
/^-0|^--vacuum/ :vacuum,
/^-i|^--ice/ :ice }
loop do
break if ARGV.empty?
break if ARGV.first "--"
break unless /^-/ ARGV.first
illegal_option rue
options.each do
| opt_reg, opt_sym |
if opt_reg ARGV.first then
usage "Missing argument for option #{ARGV}" if ARGV.length < 2
instance_variable_set( "@#{opt_sym}", ARGV[1] )
ARGV.slice!( 0, 2 )
illegal_option alse
end
end
usage ARGV.first if illegal_option
end
usage ARGV.join(", ") unless ARGV.size 3
require @format rescue usage
begin
mkdir( "output" ) unless File.directory?( "output" )
rescue
$stderr.puts 'Cannot create output directory "output"'
usage
end
t orus( *(ARGV << @start) )
t.name name || "run-#{ARGV[0..1].join("-")}"
t.formatter ormatter.new( ICE @ice, VAPOR @vapor, VACUUM @vacuum )
t.start_sim
35/36 > cat torus.rb
--------------------------
# vim: sw sts nu tw expandtab nowrap:
#
#
ICE lass.new
VAPOR lass.new
VACUUM lass.new
###############################################################
#
# a small reference to Python ;)
#
###############################################################
def Torus( rows, cols, vapors, start il )
Torus_.new( rows.to_i, cols.to_i, vapors.to_f, start )
end
class Torus_
###############################################################
#
# Torus_
#
###############################################################
attr_reader :lines, :columns
attr_reader :generation
attr_accessor :formatter, :name
def initialize rows, cols, vapors, start
@lines ows
@columns ols
@vapors apors
@generation
if start then
@start tart.split("@").map{|e| e.to_i}
else
@start || rows/2, cols /2 ]
end
@nhoods ] # we will store neighborhoods identified by
# their upper left corner index, odd is for even generations
# and even is for odd generations, which might seem odd.
reset_values
set_vapors
end
def [] line, col l
return @values[line] unless col
@values[line][col]
end # def [](line, col l)
def [] ine, col, val
@values[line][col] al
end
def each_cell
(1..@lines).each do
| line |
(1..@columns).each do
| column |
yield @values[line-1][column-1], line-1, column-1
end # (0..@columns).each do
end # (0..@lines).each do
end # def each_cell &blk
def each_line
@values.each{ |line| yield line }
end
def each_nbh
r generation % 2
loop do
yield @nhoods[ linear_idx( r, c ) ] ||Neighborhood.new( self, r, r.succ % @lines, c, c.succ % @columns )
c +
r + unless c < @columns
return unless r < @lines
c % columns
r % lines
end
end
def set_from_str str
@values ]
str.strip.split("\n").each do
| line_str |
@values << []
line_str.each_byte do
| char |
@values.last << case char.chr
when ICE.to_s
ICE
when VACUUM.to_s
VACUUM
when VAPOR.to_s
VAPOR
end
end
end
end
def start_sim
until no_more_vapor? do
tick
write
end
end # def start_sim
def tick
puts "Simulation #{@name} generation #{@generation}:"
@generation +
each_nbh do
| nbh |
nbh.recalc
end
end
private
def no_more_vapor?
! @values.any?{ |line|
line.any?{ |v| v VAPOR }
}
end
def reset_values
@values rray.new(@lines){
Array.new(@columns){
VACUUM
}
}
end
def set_vapors
total lines * @columns
v @vapors * (total-1) ).to_i
x *0..total-2]
at ]
v.times do
at << x.delete_at( rand(x.size) )
end
at.each do
| index |
l,c atrix_idx index
@values[l][c] APOR
end
@values[@lines-1][@columns-1] values[@start.first][@start.last]
@values[@start.first][@start.last] CE
end # def set_vapors
def linear_idx r, c
r * @columns + c
end
def matrix_idx l
return l / @columns, l % @columns
end
def write
@formatter.to_file self, "output/#{@name}.%08d" % @generation
end # def write
end # class Torus_
###############################################################
#
# Neighborhood is implementing a 2x2 window to any object
# that responds to #[]n,m and #[] m,value
# It implements the operation of rotation.
#
###############################################################
class Neighborhood < Struct.new( :torus, :top, :bottom, :left, :right )
include Enumerable
# Neighborhood gives us the following indexed view to the underlying
# torus
# +---+---+ +-----------+-----------+
# | 0 | 1 | | @top,@lft | @top,@rgt |
# +---+---+ +-----------+-----------+
# | 3 | 2 | | @bot,@lft | @bot,@rgt |
# +---+---+ +-----------+-----------+
#
# The Name and the Indexer implement that mapping
Names
%w{ top left },
%w{ top right },
%w{ bottom right },
%w{ bottom left }
]
def initialize *args
super *args
end
alias_method :__access__, :[] # Needed b/c/o the limited access
# abilities of Struct
def [] n
__access__("torus")[ *resolve_idx( n ) ]
end
def [] , val
__access__("torus")[ *resolve_idx( n ) ] al
end
def each
4.times do
| idx |
yield self[idx]
end
end
def recalc
if any?{|v| v ICE} then
4.times do
| idx |
self[ idx ] CE if self[ idx ] VAPOR
end
else
rotate( rand(2) )
end
end
def rotate dir
x elf[0]
3.times do
| n |
self[ n + 2*dir*n ] elf[ n + 1 + dir*2*n.succ ]
end # 3.times do
self[ 3 + 2 * dir ]
end # def rotate dir
private
def resolve_idx n
[
__access__( Names[ n % 4 ].first ),
__access__( Names[ n % 4 ].last)
]
end # def resolv_idx
end # class Neighborhood
538/39 > cat ascii.rb
--------------------------
# vim: sw sts nu tw expandtab nowrap:
class Formatter
@@default ICE "*",
VAPOR "0",
VACUUM " "
}
def initialize chars
@chars Hash[ *chars.to_a.map{ |(k,v)| [k, v || @@default[k] ] }.flatten ]
end # def initialize colors
def to_file( source, file, comment il )
File.open( "#{file}.txt", "w" ) do
| f |
source.each_line{
|line|
line.each do
| cell |
f.print @chars[cell]
end
f.puts
}
end
end
end
539/40 > cat ppm.rb
--------------------------
# vim: sw sts nu tw expandtab nowrap:
class Formatter
@@default ICE "255/255/255",
VAPOR "255/0/255",
VACUUM "0/0/0"
}
def initialize colors
@colors }
colors.each do
| element, color |
color || @default[element]
@colors[ element ] " << color.gsub("/", " ") << " "
end # colors.each do
end # def initialize colors
def to_file( source, file, comment il )
comment || ile
File.open( "#{file}.ppm", "w" ) do
| f |
f.puts "P3 #{source.columns} #{source.lines} 255"
f.puts "#"
f.puts "# #{comment}"
f.puts "#"
source.each_line{
|line|
count
line.each do
| cell |
s colors[cell]
if count + s.size > 70 then
f.puts
count
end
count + .size
f.print s
end
f.puts unless count.zero?
}
end
end
end
------ art_20344_4369595.1173621305310
Content-Type: application/x-ruby; name="ascii.rb"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="ascii.rb"
X-Attachment-Id: f_ez5idwji
IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWIgbm93cmFwOgoKCmNsYXNzIEZvcm1h
dHRlcgoKICBAQGRlZmF1bHQgPSB7IElDRSA9PiAiKiIsCiAgICAgICAgICAgICAgICBWQVBPUiA9
PiAiMCIsCiAgICAgICAgICAgICAgICBWQUNVVU0gPT4gIiAiIAogIH0KICBkZWYgaW5pdGlhbGl6
ZSBjaGFycz17fQogICAgQGNoYXJzID0gCiAgICAgIEhhc2hbICpjaGFycy50b19hLm1hcHsgfChr
LHYpfCBbaywgdiB8fCBAQGRlZmF1bHRba10gXSB9LmZsYXR0ZW4gXQogIGVuZCAjIGRlZiBpbml0
aWFsaXplIGNvbG9ycz17fQoKICBkZWYgdG9fZmlsZSggc291cmNlLCBmaWxlLCBjb21tZW50ID0g
bmlsICkKICAgIEZpbGUub3BlbiggIiN7ZmlsZX0udHh0IiwgInciICkgZG8KICAgICAgfCBmIHwK
ICAgICAgc291cmNlLmVhY2hfbGluZXsKICAgICAgICB8bGluZXwKICAgICAgICBsaW5lLmVhY2gg
ZG8KICAgICAgICAgIHwgY2VsbCB8CiAgICAgICAgICBmLnByaW50IEBjaGFyc1tjZWxsXQogICAg
ICAgIGVuZAogICAgICAgIGYucHV0cwogICAgICB9CiAgICBlbmQKICBlbmQKICAKZW5kCg ------ art_20344_4369595.1173621305310
Content-Type: application/x-ruby; name="ppm.rb"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="ppm.rb"
X-Attachment-Id: f_ez5ief6f
IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWIgbm93cmFwOgoKCmNsYXNzIEZvcm1h
dHRlcgoKICBAQGRlZmF1bHQgPSB7IElDRSA9PiAiMjU1LzI1NS8yNTUiLAogICAgICAgICAgICAg
ICAgVkFQT1IgPT4gIjI1NS8wLzI1NSIsCiAgICAgICAgICAgICAgICBWQUNVVU0gPT4gIjAvMC8w
IiAKICB9CgogIGRlZiBpbml0aWFsaXplIGNvbG9ycz17fQogICAgQGNvbG9ycyA9IHt9CiAgICBj
b2xvcnMuZWFjaCBkbwogICAgICB8IGVsZW1lbnQsIGNvbG9yIHwKICAgICAgY29sb3IgfHw9IEBA
ZGVmYXVsdFtlbGVtZW50XQogICAgICBAY29sb3JzWyBlbGVtZW50IF0gPSAiICIgPDwgY29sb3Iu
Z3N1YigiLyIsICIgIikgPDwgIiAiCiAgICBlbmQgIyBjb2xvcnMuZWFjaCBkbwogIGVuZCAjIGRl
ZiBpbml0aWFsaXplIGNvbG9ycz17fQoKICBkZWYgdG9fZmlsZSggc291cmNlLCBmaWxlLCBjb21t
ZW50ID0gbmlsICkKICAgIGNvbW1lbnQgfHw9IGZpbGUKICAgIEZpbGUub3BlbiggIiN7ZmlsZX0u
cHBtIiwgInciICkgZG8KICAgICAgfCBmIHwKICAgICAgZi5wdXRzICJQMyAje3NvdXJjZS5jb2x1
bW5zfSAje3NvdXJjZS5saW5lc30gMjU1IgogICAgICBmLnB1dHMgIiMiCiAgICAgIGYucHV0cyAi
IyAje2NvbW1lbnR9IgogICAgICBmLnB1dHMgIiMiCiAgICAgIHNvdXJjZS5lYWNoX2xpbmV7CiAg
ICAgICAgfGxpbmV8CiAgICAgICAgY291bnQgPSAwCiAgICAgICAgbGluZS5lYWNoIGRvCiAgICAg
ICAgICB8IGNlbGwgfAogICAgICAgICAgcyA9IEBjb2xvcnNbY2VsbF0KICAgICAgICAgIGlmIGNv
dW50ICsgcy5zaXplID4gNzAgdGhlbgogICAgICAgICAgICBmLnB1dHMgCiAgICAgICAgICAgIGNv
dW50ID0gMAogICAgICAgICAgZW5kCiAgICAgICAgICBjb3VudCArPSBzLnNpemUKICAgICAgICAg
IGYucHJpbnQgcwogICAgICAgIGVuZAogICAgICAgIGYucHV0cyB1bmxlc3MgY291bnQuemVybz8K
ICAgICAgfQogICAgZW5kCiAgZW5kCiAgCmVuZAo------ art_20344_4369595.1173621305310
Content-Type: application/x-ruby; name="run.rb"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="run.rb"
X-Attachment-Id: f_ez5ielfk
IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWI6DQojDQpyZXF1aXJlICdmaWxldXRp
bHMnDQpyZXF1aXJlICd0b3J1cycNCg0KZGVmIHVzYWdlIG1zZyA9IG5pbA0KICAkc3RkZXJyLnB1
dHMgbXNnIGlmIG1zZw0KICAkc3RkZXJyLnB1dHMgPDwtRU9TDQogIHVzYWdlOg0KICAjeyQwfSBb
b3B0aW9uc10gaGVpZ2h0IHdpZHRoIHZhcG9yX3Byb2JhYmlsaXR5DQoNCiAgb3B0aW9ucyBhbmQg
dGhlaXIgZGVmYXVsdHMNCiAgLXN8LS1zdGFydCA8aGVpZ2h0Pi8yQDx3aWR0aD4vMiAgICAgIHdo
ZXJlIHRvIHB1dCB0aGUgaW5pdGlhbCBmcmVlemVyDQogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICBwbGVhc2UgdXNlIFNtYWxsdGFsayBzeW50YXggaGVyZQ0KICAtbnwtLW5h
bWUgICBydW4tPGhlaWdodD4tPHdpZHRoPiAgICAgbmFtZSBvZiB0aGUgb3V0cHV0IGZpbGUNCiAg
LXZ8LS12YXBvciAgMjU1LzAvMjU1ICAgICAgICAgICAgICAgIHJnYiB2YWx1ZSBmb3IgUFBNDQog
ICAgICAgICAgICAgIE8gICAgICAgICAgICAgICAgICAgICAgICB1c2Ugc3RyaW5ncyBmb3IgQVND
SUkNCiAgLTB8LS12YWN1dW0gMC8wLzAgICAgICAgICAgICAgICAgICAgIGlkZW0NCiAgICAgICAg
ICAgICAgPHNwYWNlPg0KICAtaXwtLWljZSAgICAyNTUvMjU1LzI1NSAgICAgICAgICAgICAgaWRl
bQ0KICAgICAgICAgICAgICAqDQogIC1mfC0tZm9ybWF0IHBwbSAgICAgICAgICAgICAgICAgICAg
ICBwcG0gb3IgYXNjaWkgYXJlIHN1cHBvcnRlZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgd3JpdGUgeW91ciBvd24gcGx1Z2lucyA7KQ0KDQogIGhhdmUgZnVuDQogIEVP
Uw0KICBleGl0IC0xDQplbmQNCg0KQHN0YXJ0ID0gQG5hbWUgPSBuaWwNCkB2YXBvciA9IG5pbA0K
QHZhY3V1bSA9IG5pbA0KQGljZSAgICA9IG5pbA0KQGZvcm1hdCA9ICJwcG0iIA0Kb3B0aW9ucyA9
IHsgL14tZnxeLS1mb3JtYXQvID0+IDpmb3JtYXQsDQogICAgICAgICAgICAvXi1zfF4tLXN0YXJ0
LyAgPT4gOnN0YXJ0LA0KICAgICAgICAgICAgL14tbnxeLS1uYW1lLyAgID0+IDpuYW1lLA0KICAg
ICAgICAgICAgL14tdnxeLS12YXBvci8gID0+IDp2YXBvciwNCiAgICAgICAgICAgIC9eLTB8Xi0t
dmFjdXVtLyA9PiA6dmFjdXVtLA0KICAgICAgICAgICAgL14taXxeLS1pY2UvICAgID0+IDppY2Ug
fQ0KbG9vcCBkbw0KICBicmVhayBpZiBBUkdWLmVtcHR5Pw0KICBicmVhayBpZiBBUkdWLmZpcnN0
ID09ICItLSINCiAgYnJlYWsgdW5sZXNzIC9eLS8gPT09IEFSR1YuZmlyc3QNCiAgaWxsZWdhbF9v
cHRpb24gPSB0cnVlDQogIG9wdGlvbnMuZWFjaCBkbw0KICAgIHwgb3B0X3JlZywgb3B0X3N5bSB8
DQogICAgaWYgb3B0X3JlZyA9PT0gQVJHVi5maXJzdCB0aGVuDQogICAgICB1c2FnZSAiTWlzc2lu
ZyBhcmd1bWVudCBmb3Igb3B0aW9uICN7QVJHVn0iIGlmIEFSR1YubGVuZ3RoIDwgMg0KICAgICAg
aW5zdGFuY2VfdmFyaWFibGVfc2V0KCAiQCN7b3B0X3N5bX0iLCBBUkdWWzFdICkNCiAgICAgIEFS
R1Yuc2xpY2UhKCAwLCAyICkNCiAgICAgIGlsbGVnYWxfb3B0aW9uID0gZmFsc2UNCiAgICBlbmQN
CiAgZW5kDQogIHVzYWdlIEFSR1YuZmlyc3QgaWYgaWxsZWdhbF9vcHRpb24gDQplbmQNCnVzYWdl
IEFSR1Yuam9pbigiLCAiKSB1bmxlc3MgQVJHVi5zaXplID09IDMNCg0KcmVxdWlyZSBAZm9ybWF0
IHJlc2N1ZSB1c2FnZQ0KDQpiZWdpbg0KICBta2RpciggIm91dHB1dCIgKSB1bmxlc3MgRmlsZS5k
aXJlY3Rvcnk/KCAib3V0cHV0IiApIA0KcmVzY3VlIA0KICAkc3RkZXJyLnB1dHMgJ0Nhbm5vdCBj
cmVhdGUgb3V0cHV0IGRpcmVjdG9yeSAib3V0cHV0IicNCiAgdXNhZ2UNCmVuZA0KDQp0ID0gVG9y
dXMoICooQVJHViA8PCBAc3RhcnQpICkNCnQubmFtZSA9IEBuYW1lIHx8ICJydW4tI3tBUkdWWzAu
LjFdLmpvaW4oIi0iKX0iDQp0LmZvcm1hdHRlciA9IEZvcm1hdHRlci5uZXcoIElDRSA9PiBAaWNl
LCBWQVBPUiA9PiBAdmFwb3IsIFZBQ1VVTSA9PiBAdmFjdXVtICkNCnQuc3RhcnRfc2ltDQo------ art_20344_4369595.1173621305310
Content-Type: application/x-ruby; name="torus.rb"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="torus.rb"
X-Attachment-Id: f_ez5ieoum
IyB2aW06IHN3PTIgc3RzPTIgbnUgdHc9MCBleHBhbmR0YWIgbm93cmFwOg0KIw0KIw0KDQpJQ0Ug
PSBDbGFzcy5uZXcNClZBUE9SID0gQ2xhc3MubmV3DQpWQUNVVU0gPSBDbGFzcy5uZXcNCg0KDQoj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMNCiMNCiMgYSBzbWFsbCByZWZlcmVuY2UgdG8gUHl0aG9uIDspDQojDQojIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCmRl
ZiBUb3J1cyggcm93cywgY29scywgdmFwb3JzLCBzdGFydCA9IG5pbCApDQogIFRvcnVzXy5uZXco
IHJvd3MudG9faSwgY29scy50b19pLCB2YXBvcnMudG9fZiwgc3RhcnQgKQ0KZW5kDQoNCmNsYXNz
IFRvcnVzXw0KDQogICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIw0KICAjDQogICMgICAgVG9ydXNfDQogICMNCiAgIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQog
IGF0dHJfcmVhZGVyIDpsaW5lcywgOmNvbHVtbnMNCiAgYXR0cl9yZWFkZXIgOmdlbmVyYXRpb24N
CiAgYXR0cl9hY2Nlc3NvciA6Zm9ybWF0dGVyLCA6bmFtZQ0KICBkZWYgaW5pdGlhbGl6ZSByb3dz
LCBjb2xzLCB2YXBvcnMsIHN0YXJ0DQogICAgQGxpbmVzID0gcm93cw0KICAgIEBjb2x1bW5zID0g
Y29scw0KICAgIEB2YXBvcnMgPSB2YXBvcnMNCiAgICBAZ2VuZXJhdGlvbiA9IDANCiAgICBpZiBz
dGFydCB0aGVuDQogICAgICBAc3RhcnQgPSBzdGFydC5zcGxpdCgiQCIpLm1hcHt8ZXwgZS50b19p
fQ0KICAgIGVsc2UNCiAgICAgIEBzdGFydCB8fD0gWyByb3dzLzIsIGNvbHMgLzIgXQ0KICAgIGVu
ZA0KICAgIEBuaG9vZHMgPSBbXSAgIyB3ZSB3aWxsIHN0b3JlIG5laWdoYm9yaG9vZHMgaWRlbnRp
ZmllZCBieQ0KICAgICMgdGhlaXIgdXBwZXIgbGVmdCBjb3JuZXIgaW5kZXgsIG9kZCBpcyBmb3Ig
ZXZlbiBnZW5lcmF0aW9ucw0KICAgICMgYW5kIGV2ZW4gaXMgZm9yIG9kZCBnZW5lcmF0aW9ucywg
d2hpY2ggbWlnaHQgc2VlbSBvZGQuDQogICAgcmVzZXRfdmFsdWVzDQogICAgc2V0X3ZhcG9ycw0K
ICBlbmQNCg0KICBkZWYgW10gbGluZSwgY29sPW5pbA0KICAgIHJldHVybiBAdmFsdWVzW2xpbmVd
IHVubGVzcyBjb2wNCiAgICBAdmFsdWVzW2xpbmVdW2NvbF0NCiAgZW5kICMgZGVmIFtdKGxpbmUs
IGNvbD1uaWwpDQogIGRlZiBbXT0gbGluZSwgY29sLCB2YWwNCiAgICBAdmFsdWVzW2xpbmVdW2Nv
bF0gPSB2YWwNCiAgZW5kDQogIGRlZiBlYWNoX2NlbGwgDQogICAgKDEuLkBsaW5lcykuZWFjaCBk
bw0KICAgICAgfCBsaW5lIHwNCiAgICAgICgxLi5AY29sdW1ucykuZWFjaCBkbw0KICAgICAgICB8
IGNvbHVtbiB8DQogICAgICAgIHlpZWxkIEB2YWx1ZXNbbGluZS0xXVtjb2x1bW4tMV0sIGxpbmUt
MSwgY29sdW1uLTENCiAgICAgIGVuZCAjICgwLi5AY29sdW1ucykuZWFjaCBkbw0KICAgIGVuZCAj
ICgwLi5AbGluZXMpLmVhY2ggZG8NCiAgZW5kICMgZGVmIGVhY2hfY2VsbCAmYmxrDQoNCiAgZGVm
IGVhY2hfbGluZQ0KICAgIEB2YWx1ZXMuZWFjaHsgfGxpbmV8IHlpZWxkIGxpbmUgfQ0KICBlbmQN
Cg0KICBkZWYgZWFjaF9uYmgNCiAgICByID0gYyA9IEBnZW5lcmF0aW9uICUgMg0KICAgIGxvb3Ag
ZG8NCiAgICAgIHlpZWxkIEBuaG9vZHNbIGxpbmVhcl9pZHgoIHIsIGMgKSBdIHx8PSANCiAgICAg
ICAgICBOZWlnaGJvcmhvb2QubmV3KCBzZWxmLCByLCByLnN1Y2MgJSBAbGluZXMsIGMsIGMuc3Vj
YyAlIEBjb2x1bW5zICkNCiAgICAgIGMgKz0gMg0KICAgICAgciArPSAyIHVubGVzcyBjIDwgQGNv
bHVtbnMNCiAgICAgIHJldHVybiB1bmxlc3MgciA8IEBsaW5lcw0KICAgICAgYyAlPSBAY29sdW1u
cw0KICAgICAgciAlPSBAbGluZXMNCiAgICBlbmQNCiAgZW5kDQoNCiAgZGVmIHNldF9mcm9tX3N0
ciBzdHINCiAgICBAdmFsdWVzID0gW10NCiAgICBzdHIuc3RyaXAuc3BsaXQoIlxuIikuZWFjaCBk
bw0KICAgICAgfCBsaW5lX3N0ciB8DQogICAgICBAdmFsdWVzIDw8IFtdDQogICAgICBsaW5lX3N0
ci5lYWNoX2J5dGUgZG8NCiAgICAgICAgIHwgY2hhciB8DQogICAgICAgICBAdmFsdWVzLmxhc3Qg
PDwgY2FzZSBjaGFyLmNocg0KICAgICAgICAgICAgICAgICAgICAgICAgICB3aGVuIElDRS50b19z
DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNFDQogICAgICAgICAgICAgICAgICAgICAg
ICAgIHdoZW4gVkFDVVVNLnRvX3MNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUNVVU0N
CiAgICAgICAgICAgICAgICAgICAgICAgICAgd2hlbiBWQVBPUi50b19zDQogICAgICAgICAgICAg
ICAgICAgICAgICAgICAgVkFQT1INCiAgICAgICAgICAgICAgICAgICAgICAgICBlbmQNCg0KICAg
ICAgZW5kDQogICAgZW5kDQogIGVuZA0KDQogIGRlZiBzdGFydF9zaW0NCiAgICB1bnRpbCBub19t
b3JlX3ZhcG9yPyBkbw0KICAgICAgdGljaw0KICAgICAgd3JpdGUNCiAgICBlbmQNCiAgZW5kICMg
ZGVmIHN0YXJ0X3NpbQ0KDQogIGRlZiB0aWNrDQogICAgcHV0cyAiU2ltdWxhdGlvbiAje0BuYW1l
fSBnZW5lcmF0aW9uICN7QGdlbmVyYXRpb259OiINCiAgICBAZ2VuZXJhdGlvbiArPSAxDQogICAg
ZWFjaF9uYmggZG8NCiAgICAgIHwgbmJoIHwNCiAgICAgIG5iaC5yZWNhbGMNCiAgICBlbmQgDQog
IGVuZA0KDQogIHByaXZhdGUNCg0KICBkZWYgbm9fbW9yZV92YXBvcj8NCiAgICAhIEB2YWx1ZXMu
YW55P3sgfGxpbmV8DQogICAgICBsaW5lLmFueT97IHx2fCB2ID09IFZBUE9SIH0NCiAgICB9DQog
IGVuZA0KDQogIGRlZiByZXNldF92YWx1ZXMNCiAgICBAdmFsdWVzID0gQXJyYXkubmV3KEBsaW5l
cyl7DQogICAgICBBcnJheS5uZXcoQGNvbHVtbnMpew0KICAgICAgICBWQUNVVU0NCiAgICAgIH0N
CiAgICB9DQogIGVuZA0KICBkZWYgc2V0X3ZhcG9ycw0KICAgIHRvdGFsID0gQGxpbmVzICogQGNv
bHVtbnMNCiAgICB2ID0gKCBAdmFwb3JzICogICh0b3RhbC0xKSApLnRvX2kNCiAgICB4ID0gWyow
Li50b3RhbC0yXQ0KICAgIGF0ID0gW10NCiAgICB2LnRpbWVzIGRvDQogICAgICBhdCA8PCB4LmRl
bGV0ZV9hdCggcmFuZCh4LnNpemUpICkNCiAgICBlbmQNCiAgICBhdC5lYWNoIGRvDQogICAgICB8
IGluZGV4IHwNCiAgICAgIGwsYyA9IG1hdHJpeF9pZHggaW5kZXgNCiAgICAgIEB2YWx1ZXNbbF1b
Y10gPSBWQVBPUg0KICAgIGVuZA0KICAgIEB2YWx1ZXNbQGxpbmVzLTFdW0Bjb2x1bW5zLTFdID0g
QHZhbHVlc1tAc3RhcnQuZmlyc3RdW0BzdGFydC5sYXN0XQ0KICAgIEB2YWx1ZXNbQHN0YXJ0LmZp
cnN0XVtAc3RhcnQubGFzdF0gPSBJQ0UNCiAgZW5kICMgZGVmIHNldF92YXBvcnMNCg0KICBkZWYg
bGluZWFyX2lkeCByLCBjDQogICAgciAqIEBjb2x1bW5zICsgYw0KICBlbmQNCiAgZGVmIG1hdHJp
eF9pZHggbA0KICAgIHJldHVybiBsIC8gQGNvbHVtbnMsIGwgJSBAY29sdW1ucw0KICBlbmQNCg0K
ICBkZWYgd3JpdGUNCiAgICBAZm9ybWF0dGVyLnRvX2ZpbGUgc2VsZiwgIm91dHB1dC8je0BuYW1l
fS4lMDhkIiAlIEBnZW5lcmF0aW9uDQogIGVuZCAjIGRlZiB3cml0ZQ0KICANCmVuZCAjIGNsYXNz
IFRvcnVzXw0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMNCiMNCiMgICAgTmVpZ2hib3Job29kIGlzIGltcGxlbWVudGluZyBh
IDJ4MiB3aW5kb3cgdG8gYW55IG9iamVjdA0KIyAgICB0aGF0IHJlc3BvbmRzIHRvICNbXW4sbSBh
bmQgI1tdPW4sbSx2YWx1ZQ0KIyAgICBJdCBpbXBsZW1lbnRzIHRoZSBvcGVyYXRpb24gb2Ygcm90
YXRpb24uDQojDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
IyMjIyMjIyMjIyMjIyMjIyMNCmNsYXNzIE5laWdoYm9yaG9vZCA8IFN0cnVjdC5uZXcoIDp0b3J1
cywgOnRvcCwgOmJvdHRvbSwgIDpsZWZ0LCA6cmlnaHQgKQ0KICBpbmNsdWRlIEVudW1lcmFibGUN
Cg0KICAjIE5laWdoYm9yaG9vZCBnaXZlcyB1cyB0aGUgZm9sbG93aW5nIGluZGV4ZWQgdmlldyB0
byB0aGUgdW5kZXJseWluZw0KICAjIHRvcnVzDQogICMgICAgICstLS0rLS0tKyAgICAgKy0tLS0t
LS0tLS0tKy0tLS0tLS0tLS0tKw0KICAjICAgICB8IDAgfCAxIHwgICAgIHwgQHRvcCxAbGZ0IHwg
QHRvcCxAcmd0IHwNCiAgIyAgICAgKy0tLSstLS0rICAgICArLS0tLS0tLS0tLS0rLS0tLS0tLS0t
LS0rDQogICMgICAgIHwgMyB8IDIgfCAgICAgfCBAYm90LEBsZnQgfCBAYm90LEByZ3QgfA0KICAj
ICAgICArLS0tKy0tLSsgICAgICstLS0tLS0tLS0tLSstLS0tLS0tLS0tLSsNCiAgIw0KICAjIFRo
ZSBOYW1lIGFuZCB0aGUgSW5kZXhlciBpbXBsZW1lbnQgdGhhdCBtYXBwaW5nDQoNCiAgTmFtZXMg
PSBbIA0KICAgICAgJXd7IHRvcCBsZWZ0IH0sDQogICAgICAld3sgdG9wIHJpZ2h0IH0sDQogICAg
ICAld3sgYm90dG9tIHJpZ2h0IH0sDQogICAgICAld3sgYm90dG9tIGxlZnQgfQ0KICAgICAgXQ0K
DQogIGRlZiBpbml0aWFsaXplICphcmdzDQogICAgc3VwZXIgKmFyZ3MNCiAgZW5kDQoNCiAgYWxp
YXNfbWV0aG9kIDpfX2FjY2Vzc19fLCA6W10gIyBOZWVkZWQgYi9jL28gdGhlIGxpbWl0ZWQgYWNj
ZXNzDQogICMgYWJpbGl0aWVzIG9mIFN0cnVjdA0KDQogIGRlZiBbXSBuDQogICAgX19hY2Nlc3Nf
XygidG9ydXMiKVsgKnJlc29sdmVfaWR4KCBuICkgXQ0KICBlbmQNCiAgZGVmIFtdPSBuLCB2YWwN
CiAgICBfX2FjY2Vzc19fKCJ0b3J1cyIpWyAqcmVzb2x2ZV9pZHgoIG4gKSBdID0gdmFsDQogIGVu
ZA0KDQogIGRlZiBlYWNoDQogICAgNC50aW1lcyBkbw0KICAgICAgfCBpZHggfA0KICAgICAgeWll
bGQgc2VsZltpZHhdDQogICAgZW5kDQogIGVuZA0KDQogIGRlZiByZWNhbGMNCiAgICANCiAgICBp
ZiBhbnk/e3x2fCB2ID09IElDRX0gdGhlbg0KICAgICAgNC50aW1lcyBkbw0KICAgICAgICB8IGlk
eCB8DQogICAgICAgIHNlbGZbIGlkeCBdID0gSUNFIGlmIHNlbGZbIGlkeCBdID09IFZBUE9SDQog
ICAgICBlbmQNCiAgICBlbHNlDQogICAgICByb3RhdGUoIHJhbmQoMikgKQ0KICAgIGVuZA0KICBl
bmQNCg0KICBkZWYgcm90YXRlIGRpcg0KICAgIHggPSBzZWxmWzBdDQogICAgMy50aW1lcyBkbw0K
ICAgICAgfCBuIHwNCiAgICAgIHNlbGZbIG4gKyAyKmRpcipuIF0gPSBzZWxmWyBuICsgMSArIGRp
cioyKm4uc3VjYyBdDQogICAgZW5kICMgMy50aW1lcyBkbw0KICAgIHNlbGZbIDMgKyAyICogZGly
IF0gPSB4DQogIGVuZCAjIGRlZiByb3RhdGUgZGlyDQoNCiAgcHJpdmF0ZQ0KICBkZWYgcmVzb2x2
ZV9pZHggbg0KICAgIFsNCiAgICBfX2FjY2Vzc19fKCBOYW1lc1sgbiAlIDQgXS5maXJzdCApLA0K
ICAgIF9fYWNjZXNzX18oIE5hbWVzWyBuICUgNCBdLmxhc3QpDQogICAgXQ0KICBlbmQgIyBkZWYg
cmVzb2x2X2lkeA0KDQplbmQgIyBjbGFzcyBOZWlnaGJvcmhvb2QNCg0K
------ art_20344_4369595.1173621305310--