Keith Vetter 2019-01-24 : Recently I needed to darken an image and I didn't have access to ImageMagick. All I needed to do was to run ::tk::Darken on every pixel, and to store the result back into the image. After writing the scaffolding for processing each pixel, I realized that I could generalize the code to call not just ::tk::Darken but any arbitrary filter command.
So here's a fun little tool that lets you play with some simple pixel-base image processing. You can swap the various red, green and blue color channels, you can drop any red, green or blue color channel or darken (or brighten) an image. The filters are accumulative--each filter works on the output of the previous filter--until you press the reset button.
KPV 2019-01-28 : added a filter to create sepia toned images.
##+##########################################################################
#
# Filter Image Fun -- some simple image processing
# by Keith Vetter 2019-01-07
# Sepia code: https://groups.google.com/forum/#!topic/comp.lang.java.programmer/nSCnLECxGdA
#
package require Tk
package require Img
set CTRL(fname,msg) "Image: <builtin>"
proc DoDisplay {} {
wm title . "Image Filtering Fun"
image create photo ::img::org
image create photo ::img::post
::ttk::label .org -image ::img::org -text "Original Image" -compound top
::ttk::label .post -image ::img::post -text "Processed Image" -compound top
::ttk::frame .ctrl -borderwidth 2 -relief solid
::ttk::label .msg -textvariable CTRL(message) -anchor c
::ttk::label .time -textvariable CTRL(time) -anchor c
grid .org .post -sticky n
grid .ctrl - -sticky ew
grid .msg - -sticky ew
pack .time -in .msg -side right -padx {0 5}
ControlPanel .ctrl
}
proc ProcessImage {img out cmd} {
# Scaffolding for filtering an image, it handles walking through all the pixel
# data and calling $cmd to filter that pixel. It also calls $cmd at various
# points for status updates.
# {*}$cmd status [start|row #|done]
# {*}$cmd filter pixel
set w [image width $img]
set h [image height $img]
set stepSize 10
{*}$cmd $img $out status start
for {set row 0} {$row < $h} {incr row $stepSize} {
set row2 [expr {min($h, $row + $stepSize)}]
set data [$img data -from 0 $row $w $row2]
set newData {}
foreach rowData $data {
set newRowData [lmap color $rowData {{*}$cmd $img $out filter $color}]
lappend newData $newRowData
}
$out put $newData -to 0 $row
{*}$cmd $img $out status $row
}
{*}$cmd $img $out status done
return $out
}
proc MEMOIZE {} {
global MEM
set cmd [info level -1]
if {[info level] > 2 && [lindex [info level -2] 0] eq {MEMOIZE}} return
if {![info exists MEM($cmd)]} {set MEM($cmd) [eval $cmd]}
return -code return $MEM($cmd)
}
proc FilterCmd {filterArg img out cmd arg} {
# Procedure to actually filter an image
if {$cmd ni {status filter}} { error "unknown command $cmd: must be status or filter" }
if {$cmd eq "status"} {
if {$arg eq "start"} { $out blank ; set ::START [clock milliseconds] }
if {$arg eq "done" } {
set delta [expr {[clock milliseconds] - $::START}]
if {$delta > 1000} {
set ::CTRL(time) [format "%.1f sec" [expr {$delta / 1000.}]]
} else {
set ::CTRL(time) "$delta ms"
}
}
update
return
}
MEMOIZE
set color $arg
# Handle darken## argument
if {[string match "darken*" $filterArg]} {
set percent [string range $filterArg 6 end]
set result [::tk::Darken $color $percent]
return $result
}
# Handle swap and drop
lassign [winfo rgb . $color] red green blue
set red [expr {min(255, $red/256)}]
set green [expr {min(255, $green/256)}]
set blue [expr {min(255, $blue/256)}]
array set RGB {
rgb {red green blue} rbg {red blue green} grb {green red blue}
gbr {green blue red} brg {blue red green} bgr {blue green red}
}
if {[regexp {^sepia(\d+),(\d+)$} $filterArg . depth intensity]} {
# depth: 0 is b/w, 20 works well
# intensity: 0-255, 30 is nice
set gray [expr {($red + $green + $blue) / 3}]
set red [expr {min(255, $gray + 2 * $depth)}]
set green [expr {min(255, $gray + $depth)}]
# Darken blue to increase sepia effect
set blue [expr {max(0, $gray - $intensity)}]
} elseif {$filterArg in [array names RGB]} {
lassign [list $red $green $blue] {*}$RGB($filterArg)
} else {
foreach fcolor $filterArg {
set $fcolor 0
}
}
set result [format "#%02x%02x%02x" $red $green $blue]
return $result
}
proc ControlPanel {f} {
global CTRL
destroy {*}[winfo child $f]
set w $f.new
if {1} {
::ttk::labelframe $w -text "Image"
pack $w -side left -anchor n -expand 1 -fill y
::ttk::button $w.reset -text "Reset Image" -command {Controller reset}
::ttk::button $w.show -text "Show Filters" -command {Controller filter}
::ttk::button $w.new -text "New Image" -command {Controller new}
pack {*}[winfo child $w] -side top
pack config $w.new -pady {.1i 0}
}
set w $f.drop
if {1} {
::ttk::labelframe $w -text "Drop Color"
pack $w -side left -anchor n -expand 1 -fill y
set w $f.drop.f
::ttk::frame $w
pack $w -side top -anchor c
foreach clr {red green blue} {
set w1 $w.$clr
::ttk::checkbutton $w1 -text [string totitle $clr] -variable CTRL(drop,$clr)
set CTRL(drop,$clr) [expr {$clr eq "red"}]
pack $w1 -side top -anchor w
}
::ttk::button $f.drop.go -text Go -command {Controller drop}
pack $f.drop.go -side bottom
}
set w $f.swap
if {1} {
::ttk::labelframe $w -text "Swap Colors"
pack $w -side left -anchor n -expand 1 -fill y
set w $f.swap.f
::ttk::frame $w
pack $w -side top -anchor c
foreach swap {rgb rbg grb gbr brg bgr} {
::ttk::radiobutton $w.$swap -text [string toupper $swap] -variable CTRL(swap) -value $swap
}
grid $w.rgb $w.rbg
grid $w.grb $w.gbr
grid $w.brg $w.bgr
set CTRL(swap) grb
::ttk::button $f.swap.go -text Go -command {Controller swap}
pack $f.swap.go -side bottom
}
set w $f.darken
if {1} {
::ttk::labelframe $w -text "Darken"
pack $w -side left -anchor n -expand 1 -fill y
set w $f.darken.f
::ttk::frame $w
pack $w -side top -anchor c
set row 0
set col 0
foreach darken {10 25 50 75 100 110 125 150 200} {
::ttk::radiobutton $w.$darken -text "${darken}%" -variable CTRL(darken) -value $darken
grid $w.$darken -row $row -column $col
if {[incr col] >= 3} { incr row; set col 0}
}
set CTRL(darken) 50
::ttk::button $f.darken.go -text Go -command {Controller darken}
pack $f.darken.go -side bottom
}
set w $f.sepia
if {1} {
::ttk::labelframe $w -text "Sepia"
pack $w -side left -anchor n -expand 1 -fill y
set CTRL(sepia,depth) 20
set CTRL(sepia,intensity) 30
::ttk::label $w.ldepth -textvariable CTRL(sepia,label,depth)
::ttk::scale $w.depth -from 0 -to 255 -orient h -variable CTRL(sepia,depth) \
-command ControlPanelSepia
::ttk::label $w.lintensity -textvariable CTRL(sepia,label,intensity)
::ttk::scale $w.intensity -from 0 -to 255 -orient h -variable CTRL(sepia,intensity) \
-command ControlPanelSepia
ControlPanelSepia 0
pack $w.ldepth $w.depth $w.lintensity $w.intensity -side top -fill x
::ttk::button $f.sepia.go -text Go -command {Controller sepia}
pack $f.sepia.go -side top
}
}
proc ControlPanelSepia {value} {
global CTRL
set CTRL(sepia,label,depth) "Depth: [expr {round($CTRL(sepia,depth))}]"
set CTRL(sepia,label,intensity) "Intensity: [expr {round($CTRL(sepia,intensity))}]"
}
proc Controller {cmd} {
global CTRL
set ::cmd $cmd
if {$cmd eq "drop"} {
set colors [lmap c {red green blue} { if {$CTRL(drop,$c)} {set c} else continue}]
if {[llength $colors] == 0} {
set CTRL(message) "Dropping colors: none"
lappend CTRL(filters) "Drop: none"
} elseif {[llength $colors] == 3} {
set CTRL(message) "Dropping color: all"
lappend CTRL(filters) "Drop: all"
} else {
set CTRL(message) "Dropping color: [join $colors {, }]"
lappend CTRL(filters) "Drop: $colors"
}
set CTRL(cmd) [list FilterCmd $colors]
} elseif {$cmd eq "swap"} {
array set msgs {
rgb {no color swap} rbg {blue <-> green} grb {green <-> red}
gbr {red -> green -> blue} brg {red -> blue -> green} bgr {red <-> blue}
}
set CTRL(message) "Swapping colors: $msgs($CTRL(swap))"
lappend CTRL(filters) "Swap: rgb <-> $CTRL(swap)"
set CTRL(cmd) [list FilterCmd $CTRL(swap)]
} elseif {$cmd eq "darken"} {
if {$CTRL(darken) <= 100} {
set CTRL(message) "Darkening colors: $CTRL(darken)%"
} else {
set CTRL(message) "Brightening colors: $CTRL(darken)%"
}
lappend CTRL(filters) "Darken $CTRL(darken)%"
set CTRL(cmd) [list FilterCmd darken$CTRL(darken)]
} elseif {$cmd eq "sepia"} {
set depth [expr {round($CTRL(sepia,depth))}]
set intensity [expr {round($CTRL(sepia,intensity))}]
set CTRL(cmd) [list FilterCmd "sepia${depth},${intensity}"]
set CTRL(message) "Sepia depth:$depth intensity:$intensity"
lappend CTRL(filters) "Sepia: $depth $intensity"
} elseif {$cmd eq "reset"} {
::img::post copy ::img::org
set CTRL(message) ""
set CTRL(time) ""
set CTRL(filters) {}
return
} elseif {$cmd eq "filter"} {
set msg $CTRL(fname,msg)
append msg "\nFilters:\n "
if {$CTRL(filters) eq {}} {
append msg "no filters yet"
} else {
append msg [join $CTRL(filters) "\n "]
}
tk_messageBox -message $msg -title "Image Filtering Fun Filters"
return
} elseif {$cmd eq "new"} {
set fname [GetNewImage]
if {$fname eq ""} return
set CTRL(fname,msg) "Image: [file tail $fname]"
::img::org config -file $fname
set w [image width ::img::org]
set h [image height ::img::org]
::img::post config -width $w -height $h
Controller reset
return
}
image create photo ::img::source
::img::source copy ::img::post
ProcessImage ::img::source ::img::post $CTRL(cmd)
}
proc GetNewImage {} {
global CTRL
set ftypes {{"Images" {.jpg .png .gif}} {all *}}
set fname [tk_getOpenFile -defaultextension ".jpg" \
-title "Open Image" -filetypes $ftypes]
return $fname
}
set imageData {
/9j/4AAQSkZJRgABAQAAAQABAAD/7QBIUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAA8cAVoAAxslRxwC
AAACAAIAOEJJTQQlAAAAAAAQ/OEfici3yXgvNGI0B1h36//hABhFeGlmAABJSSoACAAAAAAAAAAAAAAA
/+EDZ2h0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJX
NU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRh
LyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4zLWMwMTEgNjYuMTQ1NjYxLCAyMDEyLzAyLzA2LTE0
OjU2OjI3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkv
MDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4
bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9u
cy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnhtcD0iaHR0cDovL25z
LmFkb2JlLmNvbS94YXAvMS4wLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJBN0EyNjdDMjBBMkUw
Q0RENURBNzFBMjVERTYzQzA2NiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxN0IwMDhGQTA4OTgx
MUUyOUJGOEY5MjI0QjQwNUZCMiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxN0IwMDhGOTA4OTgx
MUUyOUJGOEY5MjI0QjQwNUZCMiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IE1h
Y2ludG9zaCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjAzODAx
MTc0MDcyMDY4MTE4MDgzOUJEQTFGNDhBNDdGIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjA0ODAx
MTc0MDcyMDY4MTE4MDgzRTI1RjZGNDkwRDdCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+
IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZ
EhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJCQkMCwwYDQ0YMiEc
ITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgA1QFA
AwERAAIRAQMRAf/EABwAAAIDAQEBAQAAAAAAAAAAAAMEAQIFBgAHCP/EAEUQAAIBAwIEAwUHAgQDBQkA
AAECAwAEERIhBRMxQSJRYQYycYGRFCNCobHB0RVScuHw8QdDYhYXJDOTJTQ1U2NzgpKi/8QAGwEAAwEB
AQEBAAAAAAAAAAAAAQIDAAQFBgf/xAAwEQACAgEDBAEDAwQCAwEAAAAAAQIRAxIhMQQTQVEUBSJhMpGh
FUJScYGxwdHwI//aAAwDAQACEQMRAD8A4dgVavTs5aLLMQcHrWs1BBLmjZi5lLjBzWMLs2DkUGwkCfFC
zUTrLbVrNRIiD1qMSbcgdKFBKCFicAHNYJcQyY6GsYKsMmMgGsYsrzIe9YwRrqUx6WzRswNbhxQswZJn
fbzomHIlTcs4JHamSBZoW97FbKSACcYG3SmoVlFvs3BlON+1YwebiCXQVFjUN/dQoIxNeT23KJfw4AXT
tSNDo2Vvobm3Tx4YjOGPepvYZIwrm+ljuyVXABwD2rBPf1iTmh0wGH5UGFFn4zK6sNRJPU5pKootwEfF
5UfKMcmllRSKZqcIlkvJCrHBJ7nGTXLllW5141ZuycMWCRVkk8R7VBZpNWO8cUaBEMcSIJAgxjST+dTU
pN2M0gUbWwu8DUR5571WpNWJqinRYzRa2Zc46DfrVEn5EckIXnEFbKKQfMCpzL4tjJubsyqzsdKkdjtt
QiqKuRhtxQ282tW3zXT29SpnP3tDtAH4u5JZXIJ8qKxJCvqG9wTX8jZLOSTTaUuBHNvkot+YmyM5o0Lq
oeg42zEa9yNht0pHAZZA/wDVm56kjJ6b70unYOodk45y0xgjI2oaQ6tz5RB7RxNETPAyvjI0nINdS6j2
eS8foeXivDWj1faUG2SpyCKp3o+xdDPR8Y4WRn7Uoz2ZTn9KKzQ9m0M0rWa2nTXFIkq+anOKpGalwK00
Oi2tpUAxg+YpqMJyWkayEAH0NCjEC2CkEEYrUaxlIdJDYyKJhuARs2kDrQewVuFa3jQamAyTQTsaqKFF
znbFEAaIR5wVG9CzUXkgh0lsDPbFFGaoy7hFJ8Ox70zQtgYlGrDChRrGFhCE5NGgWDZlUkbgigEE0pJ2
JoWGi6ZJ2atZqGI1AYHJo2ahppGcKrN4V6CgxkMxzhmXbpUpFIjt48MqJGBsfIVNN+SrivBiyq0UhUqQ
R2o6gaXYW10nJPapTkXxwGYbcMQxX3j5VNyKqJvcLtEW4V9Ryu4PTeoTbexVUjVaR2kMpIJUYXO9NHHt
RKWTeyDNHy9Uhw46k96Pbp7AWS0ADiZywJCjy701AsBc8QjgXxHcnCihY6iZhuo4i8i5Z275wBU3Gy6d
CUt7A8Lgt2wMHrTKLA5qjAuGXVtXQmcsluC5mDW1ASLqzudhS2MkySoHvHetZtJKMEOd6NmR4zOxyuaF
hpsJBHNM4yWNJKaHjBs+apArENE+sAdCcFaW/ZwFk6BsEDvprGJ5McijG2/XP6itdB2LRJPauHhmZXBx
lTg0VOt0Bqzc4d7SPAnLvUZ8ZxIgyx+INdOPqK/UTli9GzFxSzuwvJuI2ZjgIdmzjPQ10LLF8Mk4tBOZ
huvQZp9SBQRbo9KNmDRTYYHNKxo7DU0p0DNBDSArLRFQQSsR4etAJYyuB4mpkwMGhjOWzuDRFBz3ECga
BuDufOsAD9o1LtWsIGTfxZ3pWFA1YZ3pRg8bgU1gGRMuK1mLcwaetK2OkGh5jsAgJJ6VGUi0ItnVez3B
5Li5H2lNMYG+e/wrh6nqNK+07sGHfcLxjhEIkdox42OAfOlw5W1uNlgkzLsuGgS4f3QSCfOqSYsUkdEe
GRQ2kbkjX2UeVTg7lQ03StF41EedKLk7YParaUc7m/J64P2e2aUg4UZFNdCVqYlEi3sKu5IPUgHHypXM
qoil9JLHpjhXIHYUuqx1EymtL2Z+YULP13GwrakOkKTQXellZCu+5xW1IOliP2OUtjBo60L22e/p8hbB
BoPIHtMat+DyOR4DjzpHkHWL2Hfhph7fSl7g/bXgUks2J904p1NCPGTDYB85oSyUaOI1YOCAqDiueWZ+
C0ccUaVtwkqwVVA8jUZZH5LJLwfDoVSaLUkgHbpvXc20z59F+VMgCkhl9Ns/LzoWmYHKrkhViznAKkYz
RTMFMZC55ZG2cgihZhdopWnB1AgDfTufpTpqjKyTb5RjIvbbtijYyjZEV5d2spW3uHAA6E6h9DTxnJcC
uCOj4bxqC7IguQILnpg7Kx9PI+ldWPMnyRlCuDV9075FWsUs92cAZBrWYhLjzoWYYjnGaAQpZWOaYBRg
pOBRAWFmmjUw60QFTw9SMxyfKtQQJsJ2yAQcdN6WmZATZTKASNzQoYC6SRHelZkSszA7k0rkNQVZWY7d
KRyHSNbh5fWpBOc0j3Lw2O2XiAJQRD7zAA1bY2rkeF+TrWT0K3qXcjCSVysancn+KaCS2QG2+QFlFzpD
GGxp3G/WjIy4s3oopJApbsMUFsTluM8lYx5tjNHWLobFppEkUx9V6Glch1GgSwqRpVcfCkscpNyrKPmz
5OOgo3YUmZ8vtGgGiO2YHzo0FLcNDJcXyA8oFT5jFScqLJB34TEWBcooX3j5VOWTbYpBW6ZWKCyMjLlS
R0I6GhGTfI2RJfpD82GFsaV0jvT66I6GxC+ZCVVFXLNjbepuVlVForJw53RdWAO9Lr9B/wBhrThaa/cB
pJza5CvwOSNbwrgZ2/t71HWymgWi4hCs4ijRmJ28RpJuTKxjFHwArhSE2J7rsRXsnzJ6CMqBqcs4HXrk
eRFCT9ADSQA5kWV0Y+9v/NKpeDF3dYgGckHGAxXIopWMgElyZAsY+q7ZqiSQdiotrs6gNLeQJzW1I25C
wYl1sGSQdfL40HI3kmWHmZYAnz2zWTozQex41d2aiMgywj8LdQPQ1eOVxJOKZ0VlPbcSi1RSaZerIeo/
kV0QyKRNxaCNbSq2M04CdM0Qzg4rGLx3Dttg0bMG1uu+MedGwUS1+WXGelGzUeW6bG5xQ1GoYtnd5Bg5
FazUb0dqksJ5g1HyHWmCLT8LglBYMEA65rVZjLbh8CMRryPOkcAqQ1DYRquoYx5ml0D6zYsIoVZWK4Ud
Se9K4jxmCnv4Yb7Uu6L2z1radja97Gm4vJxH7g7I7A1FwUd0dEJuXJrQGz4ZIqyEu5GdQGdNc9OW5Zva
jVF/EyKyOCG2GBU3sZRsWkuoyWDzKCNzk0u46SQnNxK3tFLOScmmjFyM6iVtuMpeTCK3XSGOAx/PNaa0
8hj9w/PawXpwjiUr0GrIFQc65KKIO34MgdQ8YLHoM96lLMWUTSSwlgQroAGO1SeYZRRzXFk4ldKQkXLh
z+LqarjywXJpY34M+2trlImEiMH/AAn96eWWN7GWN1uaVrwKa6iaS9uSgG+Ouwrly9Vp/SisMK8mibSM
QpHDEWGd3YYxUIZJN2y80kqHQsOkIIjgVZzaObTZKoyJJEihWbYFu1SlNtjqKQN+EJH95NcAk9lpdTGT
RQ8PtbYBlIOry60LZrPztCiacSSE7Y3TFe6/wfNpHuYkgKFwWztpOSPnQprcDJYIY9D6vj2rb8oAKCxV
hqkb7vso7+tGWSuDDYgTSFUjA6DGKnqZiGiKMCq5OcElqZbjpMiaZhGWBxjpnAz86yiGmC5iShQT4+oI
I3p9NBSsowjkOHJjk8/OtuhWiGtpI9BQkMD7y/lTKQtGtYe0csCiG8haYLtrXZh8fOrwzNciOFm/b8Us
r1RyZVPYq2zD5V0RyRZNxaGgsO+wB86cAJxhSgcHNEFgTaRt7pwa1Gso9u8LZZdS+YoUaxuC5CLhVANM
jGxYSuCHYnTjvTAsveXcRwiKDk5b1rBsHBBEwZ2fO2cHoKARe64gmoKgBx3AoNmFbjiMjIqpqxjGaW6G
oHbNzJPvcjPnU27HSNixeJJMhC5HQUklZeDopeX9xKzZhfJ2yRSpJDtthbVmhgMtxIyHGVTzpJPU6Q8Y
uKtis/FWkdsHAo1FAuTFml5zZaVs/wDVQcvQyjfJ0nAY7WIFrqULqAC4HWuLM5Pg68cUkdhw2zsoyLmA
6VPTfGa4pyb2LJUONdxxylsxrg4Hp/nUmPpbRe1mknkcBseW3WkozSS3BTcNa4kJnl27DFMk/BtaSGou
GWgkAIGcZJNbRJiPK1wEksLdXCnDAbgdqjODoMc0qtAp0hZlUnbp6CtjjSGUnW4G4g5JUJp33Bz1pqCp
2LJBcySa+eNJ6r6UrQ+pUVuIEyCZSdRwADWNZf8ApYKqNeAw33pHI2pH5i5gcgu7BfxEV9DR87ZLAEao
ZEbbbO2TWv2BtAxDdp94zAEds9RitcXsKMxznA1AZPqAKRxDRJJBJVScnqc/SskFIlptSHUo/SnopZKs
k8QRwCCcYrcMZMrLCrOzImMdO21aw2inJ5iEOSpPun1ouVCtpi88s0RXIJUjGQciiqZNstFJ+Ft++MVm
jIpJGqrkHfPQb4ooA5BxS/hCLHKXj7BxkfDzp45ZIVxTH4eOqSRcI0TDuNxVo5/YjxmnBd8yMSxHWn9y
1VTT4EcaHIZ2kHjyBTpgDRrCr6upPnTIA5LdfdaYzjbHWnsUU1sWyZNx5ClCMxyJINLvkHrg1kGwyrYx
kaYu+5JrUjKRE1zbBwFRQtK0h1Io0lk+5UA+hpGkOmzy3UMIxG5waTYom2Fjvyxwpx6k0jplU2FEkrnS
5Vh5mkaLJm1wewspHLXPJjQdSTtXm9ZPKo1jVs9DpowScpDrcP4JxKdoYo2Vl8KyhsA+uO1csJdRiSc2
X0wyeAUns5awFRJeHLe6FPQetV+RJrYVYVY6jW/DrOUI7506VZjkg57Vy3Oc9zpcIxjsCsLmKWcc5ZHY
9Hds4pM6klaHhFNHVNxCHhtrEzsIy+3i6saXBmuPG5yTxOcn6FYuMPeXXJQDWRkY74p/kaeUGfTKKu9i
ZJZ+viFB9QhVhQPnzMMZNK8qHWMq5mcY3ON+lJ3BtJMfPDDwaiP7q2ts1JFp54LZSbq4KKQAFB8X+1Tb
nwhlC+DLk4zw8MAEl0IThydiPXvR05P+Sixe2KNx8S3GdWi2XoWByafsS078jrSuD8/RSQpIQjkt0XAr
6JpnyOwz4JFxGV5vTxLik45MzyG5ifSIEdztu2x+G9B6X5FPch3lV5IlDYyWBx+/50dW1IwUSJGdiWLd
fQ0KY6FJ2kWQqpDA9O+1URgBuXUKg8LbDOKNGsaSY5YM3T50rRrCJM6sgDd85oNGIkuEjm0lcs25AGNq
FNoDKrpkbmR4Ixsds4xR4AWhilRyDG2G3yR/FFtBTD81dByuCOx65oIYCssNw4RlyzbDfpRpoGzLRySW
JYwyuh7gHY/GmjJ+AUvIw/GLyVWVWVSRjIGMfCqd2QNCH7Xi0CWi/aXYTKACeuv1qscyrcnLHvsM2/EY
7qMOr6T3QncVWORSEcGi54gqsUDrnOME03cQNLKNxZIgS0yKF64NDupB0MoeNQGQJ9oUknGR0+tK8yCs
bGA7yDUMsDWcxlBllEh/CaRyKKIeOORj2pHIvCNjsdpckjQCSe2Kk8qReOBvwOrw6+Uq0kqRZ6a2wfpU
n1K8HRHpX52Nnh3s9PxGdV+2oxPZTv8AKuHN1ujwdUenilqk9jci9m/sIkYzbKNmc4BNcU+qczoxxgns
Yd5P9ru9PMDRx+FSBjby9atCWmI8oXIZfLWogSHWoOVJB2qHeipW2W7bqqBW9rfiQaYyNXTIoZOpxyVA
jicd7NO7tjJahLly0iHOA5IFc0M2mVopoUkX9no5lZ5UjA0+FM7/AJUnU5NWyJSjFRqR1S62i8WzHqQK
lFN7s43SexXkL5VZMbWTywq6ME57Dah5Bfkk27tGQqkHtgdKpvWwNaT3OdvPZLi1/ePMuNBO2rPSnx64
qlEpLqcK5kNQexcxthDOwdQc6cd6yjlctSRn1uJLSEPsJbkYfWw8meqaM/gn83H6Py00sBOVtwM4xhiK
+ipnzuxJdk0uDnO5UdaFWCwvOQ+LcA+vT+KGkUmSRveV+vbVj61kjHjcOSoXGwz5kVqGTBvcEXZ+9ZV2
yaZLYN7lZLhmiCuWOW2bA/WtQGz3O8ROT2wCO3rWo1jluUSPXIRlt84+uKSV+AoZdbSeMM0jKR0I2qdy
QHuLtby8vSqpIgOxUjPxp9SAWMU8B1AMy9ih6VrTMXEz4KywFiV6lcEDyoV6ZrBxRqhDrDpcdADkj+aL
YUAuLovKF0sD3DbZNOkaz0DBdZKAOD1PSszIPhZyFOx6HTQ4GLC1ySVcpuQK2o1HjZy++ZFIPrR1G0lW
tlQlCpPQgnpWs1HhEA+jz8h0rBD8y8WNeXPJysZGDsO1azWwq8VuggVppDjfdsZo2GwkXGbjXgzyrkbl
WNBjxm0P2PH7+MZt72UAHOGbV+uanLHGXKOjH1E48M3bLj7XUoW9CljtzF2x8RUJw0rY7cWbW/uO99nb
d+bkBk0kFnC5wP2rxuqyJs9FLTDc6Hiy200XLZtZzsqbg9+vSuJ5EuGDp1K91+5nQez8LsJYFkweoVMk
Goz6qb2W5WWeOPZ0dbw3gdsbRWeYkMOgU7GrdN0yyrXOdL/TPK6jrcmukhwcJttgDLgDHuV1LpIeG/2O
d9Xk/H7gF9lrPm6+VIw/tK/rvVI/T23tf7FH9Sy1Vo0IuF20KaeUcdN2C4+ldEOjhFbr+Uc0+pySd2FF
rCqgBItu5JJqi6eCXC/cm8s2+Wee3hVgDGN+6psPrTPDji90ZZJNbP8AkE89lbyxxsyB5DhQEyfnSuWG
DUXVsdQyzTkuEAuOLWcDiNbmPVnBxnC/Eip5OphB0mimPpsk1biLTu11LHMl3IIhhuWFO5+dQyZO401L
YtjWhOLjuBbi9lw1Sk8zu7MT4yNW9ZdTHGqdsb42TK7jSQFvazhCFdccihujHBFUj1cJLZMEuhzR8o/H
Z9OgPcV9AeKNLbM3VAoxgkNvSthIEUTatImDZxqxnNa2AoygDJ1hhv4lNEx5JFGxzjGcgfsaxiwnQKoI
V/FkBl3FaghJY2lTUAcHoFAx8AKCdGFgRpGpW170wA6hWhDKcNju2w38qXyEPCsgyVlVgD0DmldALs0v
4AmoDOnff1zQVGIWdItxExXrqQHT9T1rOLZikkjBdS3LFM5IwfpRS/BjxuQCGUHYVtJi32xJQAvjcDoy
5I+BNHTRheWc8tTpXLE5xTJGLWrmW4xuFG2x6Cg9kFGlDbiNSGbVuTmkbHSASGRTliQuehGc/KijBzJz
bY5Cuw3DdCKHkL4KQXf4SnhPb1pmgJlp0WTVIkpAAwVWsmFgAcDI8eNsHfFECJaMuyldj332rBIgmFvN
nds+E0Bk6NKK4j1ghxmkastCdM7DhPtvxGytEtPtgaBV0qrnGBnzG5+deZn6GMnqS3PTwdTC/v3O24fx
Kz4nbLInGbJWAGYWchlz2Ixvj518/wBRiyYv7T1I9Rjb+2Lf7f8As3V9qrexYW78ZspGOPBENgO3iIwO
lThLqIQuC2/0ccunx5Helr/b/wDB0nCvamzubh7Zry2bSq6PvgSfn+Ik16nR/VMibWZVFLZv8f8Ad+zz
ep6CUYqUU/zt/wDUbbXMhjBQKjnqGGcfTrXVl+q1BOFX+/8A0cSxxvfgVR58Zmuixz/8vTj5Zrih1s5b
yyfxX/ks4w4jH+Ra5QzEYuZFGcnAG/pipZMjm95stjen+1HpL1YnVMZQjGpQMg/Dyq3ylFqPj/g0cLkm
/JUvHKpEpdgTjB2zR7sZfqbYdMo/pAwmwJPLAYqcEaiMGhGeLwUksy5Lc6zwWATSP+vb9aOrH6Bpy8C0
l5A8LpZiJpB0DMdJ/OllkVVFFI4ppp5LoGnE4GdxJBApQbqw8Wcevb1pe5f9qGfTy8SZnnjlkurmwxau
xVelaC9otLBJcSPzRP7IcWgXIVJh/wDTOT9K+oXUQZ4kukmhaDgXFWk5f2WRcfiZDimeSHsRYMl1Rpp7
G8SuN5JVTbGCDU/kQRVdHNjaewnEF9y/jT0AJpfkx9DfBl7Ib/h/xAj/AN8iI/wGj8qPo3wZewX/AHf8
RDBhcQfDBo/KiD4U/ZB9huKadPPhIBzsT/Fb5ETfDn7K/wDYjiuTmaEg+ZNHvwF+JMofYjio6Pbf/tR7
8TfEmej9ieLo2pJLdT5iSg88AfEmEk9ieJSlTJcW4KjGA1ZZoo3xZeyY/ZG+iUrzrZgdj96Rn5UHlTB8
aQKX2S4hp8Elsh/6ZDg/lTLLED6eQNPZLiqE6JoAMY2l7Ue7EHx5EyeyfERuBasfPnAftWWVAeCYJvZj
i5VQLWJtPTRMuP1pu5EHZmUj4Bxa1kaV7XcjswP5Cs5xexu1JC8xubdiutVYdQTvn50yihd0HhtpruF7
iWRlWLfK/wA0dNBW4MxOH1xuxhwCp2y3nn50KMybe3hvLlg12kDHpzRjJ+VZpo0Un5Nq29mLvlMUureV
T0YMD+9LTfgao+z0fspfKCGkiA9M/lRafoyUfZZvZy+Qe8HxthVzQp+g/b7FT7NX/NB0DT3ONxTUwbDC
+yl3jPPjBPYqc0rsdJeww9lbxQCLmIn4GkZRQYWPgF9EwK3MYYdCpYEflU5RjJborHVF7MJ/Qb85bnxt
5+9/FI4RQ6c3uO2vBuJxMpSdAdiCNX8Vy5ceOSpnXilli9mdrw72r9o+HQNC8lvIXOdTqxI2xtmvGyfS
scn9smi8o4sjTnHf8bF5fbf2hY5P2QDPvcvfHoDQh9GxrfU/3F04VxH+Qcntfx+V9SyWoGcqvIJwPrV1
9MguWzLQuEGs/bDisc+q9ihkh07iGMq2exySRWl9OVfbLc32+hqX21ix4rK6x/jAoL6fP/JB1xj4/gAP
bG3yWWyusnYnminX06a/uD31xX8AT7YWgx/7On695BvVF9Pl/kD5IP8A7YW6yCROH3CkbgiYU39Pl/kB
9UqpoiT2uhmbL8Mmc+ZlFFfT2v7grqktkgDe1FqR/wDCZP8A1addDL/IHy16FVghJybyIDvlOn510duf
o5+7j9jKx2yAZ4hEPXC4/Wj2ZsHycS8kl7JQwbisPn1QUfjyFfWYl5APdcMVcNxgHy0Y2/Km+NIm+vwr
yLScR4YoJXjExPz/AGFN8WRN/UsK8iz8W4Xk67qeTfszAfSnXSSZGX1bAuWDXinCcnIuzt+FM5+pFVXR
S8kZfWsC4Lf1bhONrK/f0Ohf3NUXQ/7IS+uYlwQOLWOPDwe5Y4wQZ1wf/wCaf4BP+u4wX9StCfFwZseR
ucD8lp10P4/knL67F8Eji9sq6F4PbkH+6diaddCv/mTf1x+EQOJQEbcMtVPnrc/vT/AiL/W5+j32+PtZ
23wOr+aK6GBv6xkfor/VWQeC3tV8sIf5pvhY/QP6tl8ME/GbthhY4f8A0s/vW+Hj9C/1XN7Are3JOWWE
H/7IFMukxrwL/Usz8h4b283GUKnqCq4+W1FdNBeA/PzPllntzcT82RpCuAOWr6V+go9mPgddXLyNxQWg
sDaNYRcsnfQdGaDwopHq2Xto47OBre2gRIWbUVkPM3+YoLEkZ9S2GMZlADkMB20j+KziFZWwyx4TT7i+
hxUnEvHI6LhEI3I275pGOmVMaY7lvSkbKopy/wDpb6UjHRVdIYqFYj4UrKRCR6CCBzST5dPyqE2zqx0V
kKA4IkBzupAP61O2WpHoiFnKEQAE5BZjnP0xU5y2spBb1sPpalSNU2jOMgnSvwBrhnl/B0qKXkae0ZDg
6yTsA0h3HfFRWWx6BJaqoIAOtmG8jt1p3l8iqNbCzbnSLhCSdlUFsY88iqqX4FZLW8hDjkOwOD4MEDzO
x6UFNezNAzbDbVG4UbjIO/xIzTrJ+RXH8FHgi05ZVyTjYY+uRTqb8CtIr9iLqpiCj1Izij3K5F0Xwelt
CwICjIO+Rj9aKyGcBZreMYYRhs7HG312qimxHFAJLaB0LKFXB6+fxplNpiuMWciOd3kYn0avZ+PH0fFv
q5+GXCuOrNj/ABGm7CXgk+pyPyXGQOpx6mmWNIlLJKXLLLpB91d6KgibbfkkDrhV9cUdAL/JIQ5wQfjT
LGBsnk7DLHPkaPbQU2+EXEfYLqP1ptKF+4IIyDugA+GKZQJthFUAbLn5U6iI3YUEd+nxxTUKSGiHbP8A
+VHY1S9l1CucJGp3rUMjxSQnaMbnY1qHRV7STSSeUQOuHzWoL2L/ANNuo9/s6FT0K7/vQoenzQVLe4A3
Qr5DRQaKRbGooZ+yk5/10oUWTCAEDdTv69KWiiaLrEzL4QQT60Ghk0GjgYblhjyJyanJFoyL8mFttzv/
AHYqUrOmLTDBAfcXf54qLOhFgrBcGMemP3qTLRLDUye5px2PWkZRM8ukuNUTsCNtIBqci0GgcsqoWUxP
068oD96i02dMZJGfcXkrKeXExPTqR9QBSqC8jvK62QKC64i2qP7NJIW66FO3w8VJkxwW9hhlyPajZtLz
ikbBXs52B2CmA5HwO2a8/LjxPiS/c6lKXlDeeIs6SSwxxMRlUmLIR64JIP5VCsa2THTb3Ko/FxM64trc
DH/ODH5HrTViq92ZOTZDRcSlkCi4VZCcjQAMgeeRTKUEuDNNjAS9UhnIMi9XVSdv0pbh4DuXUTvqE7yM
PJYBjHXr1+ta14BXsVkt5GJklmcZ3Vnddh5bfxVYyXCFaZb7IzLqjZdA31aj19RW1ezUKzWmqLQDGD3G
MCqKe9iuO1Cz20eCkZjXbfMex9TVFJ+RHFeAItDE+UkDKxxsmAo+eaZztAUKexxH2y0RQS7Y9E/zr6ju
wPgfhdQ/H8ghxe0yAuW+WKXvxHX07M+WkebikSknkr9c0vfXop/TJeZFX4vzIzyUCkYyQNWkfChLqPQ+
P6Wk7nK0BF7dMBzJmVSuRhQD19OlSeeb8nbHoMC30gjJcacNczMSSuAd8Y2IB7UjnJvktHBiitooVVJZ
JBpmcluikEEH5ilbY6SXAwlrcFCZJJN1ypRgWJFK5sZYxlHnDKEmnSTuHBGr+DQjmmnszS6bHNU4r9h5
LribIrtaMwzjKbn44+NWXU5W6RyS+l9Mlcl/J0NnwU8QtRNzrm1fo0c0JB+IA7V1Kc5LfY5vh4IPZWTc
8LfhxMbXodD1JDLn6r+9FNryaWKH+KAxwINxJnbGVJNOn+SEscapRJkMSZUzt8D2qqkck8MQBCfhbPlg
VROzjyQ0llUHufkaYjqaDR4QghunmxFakBTaYyt0SdifLrml0llmfkvz3O+T/FBoqspYXHi317D1pHEs
s3gsswOD4yepORSNFY5PRoQyaYtQRsY9ahJHdjntZPPDMOoHcDpUZROqOQsCuokOT30hd/lUmi8ZBGUv
jlkoOp22+dTZVMvDEBIG1lgBjw42+f8AlUp8HRj5CzwSlgY4kY9vvDv9K5W15Z2xT8ITZLskoYBgnoXO
QKm3Hmy0dfFC8iz6wXjkYDqY5Nj8Rik+2tgvVe44I40P3EcLYIYcyRkIOO2wFcrt/qZWl/agk11fPbKi
21sFGNIOpt/Skjix3dsLcq2QGGPizq4EKgk7lNiKo1iXkVa/Q1/TJovHNDMp7EnI+YpHJPgZUMRWqlNS
a0fvpBGaRsP/ACW5GkFJY7hk/CEOR+YoqXoGktCsJlEaNIAfeDrpx88fpRbfJkjz8MB08lUBx0Z1z+ZF
NGXsDSQReHEgF9QcjHgkVfyyf1rajUFm4bE0R1SED8QkGAfmBQUmgszpraOBz/5QC9CrnP0xTptg2R8C
Os6S5VZCM5Y6j9POvorPmiSJinhck57qM/XyrGPcuZiFkjYP3LN1HwoWGhy2xpAnaIoPwsME/wAdaVlI
/kLy1iUyQhSzAZJIO3lQ1G0+Ry2k0gS8sSIGIJLkj642oOTHjFDNnYX3EJi8VpIYpXK81mwD6E4/Ot28
kuDaop7nUWvsKsaCXitw0KkatjgfAk7nr2FVXTvyI80TQhTgnCiTaXGTpwWmiLtn093aqxxKIks7apFD
7TyxgGKKHwe7rRT+fWqKlwc88jfJl3PGLi6naSS4CAn8JJx6CntkJNC0t40jFQ7MnUautOrZz5MkY8sH
l32bJHljFUUDin1S8HhGNs4qiSOOWaTCCJdJG+T60aJObssE0nIx8cUQXYaI77qH26HO30oitpB4nVGB
aENv3zREUqdmhILWJEYI5LdtK4/ypPuOq8aSf/oGV5wQwxAHuWIxQ45HVSrSEEVwNkUEDsen1qbaOmCf
gKouEGJG0DzzkfrUpKzphJrkYhE0g+70SY23b9POoSXs68c34CRXCsW5sTAqeykkVKUfR0Y8q8jkc9kT
4pGBP9wK1BxkdcZw9hTb20uOS2564k/mpttcnRCnwQbQxxaSojwdismM/lXNLdnXB0g0dkGGoOxHmZA2
fniuabOuAccMnCs0axhewzv9K5pSXkqi8NpMUxIYmXG6vFqH6/nUZSXgzQVeHWBUmaKMEf2KRS65h0oU
uhwq4QILh9Q2Gkt/vTxWRO6NcWqG7CCOFQcyTqfxDfHx70JWbbwacd3GxePDb9C4P8UqEcWSptdZXU2v
G41ZHy2ptgfcVktYHxy5985xzcj8xR2MpS8lf6fwxCJGWONm38LZ/fFNbF3vYFNPZxqUjmMmT0JBPyOK
1DK/IF0ijYMbm7XbOMqP5ooO7EL5rN1OtrktjOtlH6gU8b8Af5PzsbG52KozsNzjevoqZ83Zow8Kv7iN
FWCUqp8W+M/CsoyY1o0bfgN3JKFeeOJeulfGy/E460yxNsDyJDLeysMcymcSyRH/AJhOx+IG4qnZoTuJ
nUWS8MsLXRBw6xWYDGt11EH4naqLFFAeelsikPFVinVooYOYpyObCGGf8IGKdqBJZZEXnGru5BEskCkb
AxIEx8MChdbI2q+TLNy7Elp5Gx0w2cUqsDkLSSJknDEnuTmswWCJZtsH0z0oqNkp5FFFkUk4HzwKtGB5
+bqfQwqsvUE/FqqlRwylq8hVbV5n4DNGxNDfCLBwvXUMVlJG7U34LKyvvkbetMmmI8c4+AiocfhI+OaZ
Im2FUAnf9KIjsC99a29xyZJ1STTqweg+dJLLCLps6MfR580NcI7BrG/try7a3icvIoyRnAI8we9BZoSe
lFZfT8+OOuS2HRxu14dfrb6HkWM/+J04PL22A33Oevl061z5ctOken0fRNwcpbGlwXjUN/fusnDbiC1M
erVK6qxwdyBjsuTjY7GuTL1Dik6PSw9DHywvCvaDgvFL+5txaSxW0b8sTiUEnfAJHYHtjNTzdS8bXovh
6GE0/Y9Yv7O8Vufs/C+LATdRqQjXv0UkDPyqjne7JLp0tka8XAHmTQJtejqdHX60sk0x4xTVEv7KTBF1
BnzuArft/nU7KKBQ8IfQqxxjIO4CnP71Jo6Ugy8PuBIRoYgjJ0kfvUJwZ0QkGNhNFbao0QN1IIJI+VRe
JyLrKlsUguHaQazHn8Sg7gfI7VzZena8F4ZVJcjstnDIFlhLpkZyGyBXG4v0UjN+TOngSeVuTeyow848
jPxG9PFKK3QG23sKy2vLUpK0sxOxKHP64q0UnugNvhgY7qC1jOu4u4xnGhoTgfMA00sLb4FWVImK6iJL
x3YXPU3ET/utI8T8oZZUwySguc3FrKAO50H8/wCaV4/wMpjEMio2I4iqAYDbED5jrSOIbsHpDtmKfU4/
tU5z8aP+0Yo3OgbLyOc75PQflityEvFfFZR/4nUAuBq0kD9K1fgBBiS4fVpZsdTG38ULoaj41HJeNHuh
VfI4G9fXKMj45ziXZ7t1AZ3QHZQpNGmDurwEiQKCCxB7gvvR0g7ljbX7iExCUaG2OT2ot+AqwCS6TpEu
RjYelLQbI58265YL2zWo2wJjI4xrZ/ILvWow1bWV5dyKkUDPk4GRn/KmSYp1vD/+H/E7zZlwfJR7tFyS
5D22zet/+GcNqga6laRz0jTxZP6UFlXgD6dPkPL7Cxx/+ba6s+7ED+tFZr4Yj6SF7oyOI+x0FpHJNdPy
3xhUz09MVtWoZYIw8GFc2axW7tgxwDG5G5PliklZaEYrwX4fNbTWU0AtyZV3jkH4c7b0FY7UX4LWXs3x
Hicpis7Y/djxtqwB64G9bW1yK8MH4N0ewVvFba73imlyM6Ioi5J+tVjOfhHPPpsb5ON4nGeGW082nWFY
xxbNgnPUjAGKaeWcVZGPQ4ZPdbnIzXsrXobUGQsNTYwT8vI74Fcrm27Z3wxxhHTFbId+12wjmuIbUpcx
p4JE1AE5G2On1oN+UOvTMpb2NneQIisRlsDJ657996XUMoomPjWuVYZ5pHiUYj3yFJ6/Xb6UItJ2GTvY
pcyGKZprXUqmPEuk9Rn+cUrpuwq4oHb8QMcYEcaq8TAo2TkGje1AXNn6B9gfbBON2zxS3UEl+h1EAYbR
67b4O2fhSwTrSymSm9UTsW4k/MIkhxGNskVXtKtmQ7rsNIVdFIbSvUMqk1LSXUwIjgjYltieuQRmtobD
3K8AuVaSNjlknGPFg4o9utzdxvYUfg0POaRYUIb3gDpz/NBqLGUmiz2XD442WeUqvveHPh+m9TeG/A/f
a8is3AEuVLW11NGgPVQenrk1KUNq0plVN3bk0Zt1wCVAdN9cMAc6UJJP1Ncr1LdYzoi09nMyDbMmXMd0
OX1NxJsd/wC3P60YZYp1OI0sTq4SAztLltZ0KDgMp2P0rrjihNWjllknB0xaSxkmRSzSOCcg6lB/18af
sRXAvdk+RaV76xGIOZ8dar+hqcsMHyOsskJpxW4SbLaEc7kyEn8waV9PFoKzys1eHe0ciSYljjKd2DkH
865cvSqtmdGPqL5NkcR4VckFuQWA/E1cjxZI+DpWSD8jWq0VAyNEgHQjBGanpkPaPj6PbxZIdjkfAGvt
KSPg6kyhulBBA1Edz+1K2ikYMG92+QQwT1C0rKJJATKSf78+YxQofUjwkcNhV38lH+jWpi60N2FvC8mL
qRVBO+psfzmmjD2B5Udfww8AtJFLtFIAN8nb9aooqga1Z1Flx3hUL4trdWLdHAwPqa2lsfuR8Gyvtbbx
hhkKiDdIxnP81N4h+6qDL7UQRRxzRPoJGzSscD4jFK8LfIyyotF7WQ6D9mnNxcH3pZl6f4V8qV4fYyy+
hCa4sL24517NrlDeJZfCc+i9viaoo0qQjabNQ2nB1sA1pbQTFnJyz+FW+PWp/de4/wBtbGFeezcwDEsA
wGrSqERj543p00xWmisK8b4dZlLe5tR4dAcABgPQdabSnyK5Mz7tP6daLecSvW3OpY4kJd/LA75proXk
4T2k9rZOLXxWIpHw5QY0gkQ+M/3MeoPX12+NRlkvZcFYwrk4+WVW1ZnLJqHjyABv9SKgVGrTkzgpBdDm
atgxIJHw7isFCfFLF4pVOkoSNj2/2oNBM1bd1u41KEEvjfv3NKDya8OXuXQJqAUKSDkdc7fP9KyGZSWy
aISSJGrKG1B8Yypo0AZ4FxKbhnEftNtsHDReF9JII9KFcDJ0fRbX234ueHhEngjaPKGW6jKMRgEb5xqU
Hfbfrg4NPGbWzBLGnukbfBPafjVnBFO17b8VtH94RMv2hflsGI9OtLe1sLhvsd3wr2h4bxizE0FxHKhO
hkbwsD5EHcH0pLTew1SS3KmxhhumlEzBD+Bl3Wrfc1QqpOwfFvajhns/wx7iVJJWGAkUYy7sdgAP3Owq
bxS5HU0y3CeLcP8AaG1SVHCT6dTwgqWX446j1FCpRDqixxpRZqxj1v8AL9c0jhKTuhlOKVWRDd8wZaPt
0ABoOFBUrE761tLtSz2hBGQZBgEVKcE0WhNpmVa+z3CbKV50ttcsgw24H+/61OOSUWUlBSCPwFJj9ogk
aJQSRqQeXfvTfLl5Qvx1xZgcQs5YpQrXuok4wIioPzxikl1MWVjgkjOfgTXLkS2SSgfjUKcfpUflRXDK
Pp2+UZ957EuoaSCRYs7k6GOPpV8fVqXKOfJ0lfpZmt7O38YLpIJV80UH9RXZGUZHLLHOPAa2tLuHfVKD
6LinfTxkIs8onFlirZxkn6V3UeL3EULMxHQD6ChQHlIKdMZP+LpW0ivMwyRSH3jgflTKJGWZ+AyykDTH
0+A/Wm2Ec35KySMwGpy3oe1ZmTZQSFTkHf0Ga1hthxeXKrgzkZ+VMbW/BdJ5QCea3wBrNpDRcmF+1zSk
BndiOgJ6VJzOuK23G4OLXduhWNtAO2x/1vQ1Ma6HLbiQSUmXLKxGvJ6/EmmTQLZ0w4obayaaG9CRp03D
MufL1qjiqsKk+By145LLZgLdSFQwJ5oyf1oaUNqZHHPa4cEsM2ojfiEx0prwBGD1c+f8mkyKkPDdnzHi
fEOJcWvJLuRPtJPikCSDKkkjYZx8sVzSk7OhRVGFc8qRyJNXJYFmVmyYm9DsN/nUxiCsF48cEFwQqrkA
jBJHYUGwpGfd6kmCsQWAHiG2fKgYfs+JNPZyWd25kQ+KJm6qw6jPqKxkx5+HXFpEojj57ga4w4ycAeID
HXbt6Vmmgoi3hW6tIpLfEThCzg78zHUfHvSRUm6GdVY0Emls0DQAxOpxIp6ds/Xt61nOtmFRvgQMEllq
EsLRjQHCnfbrt8qKsV0elvL23++V+bbT4Z07HyOeoPrRaMpNDlhYyXjwx2lwSrHAEqeJT5Zzj+aWLd1I
etrR1PFPZy+4BwZr5+OXrK8qJIIsAEnudzkYGOlWyYYqN8snDNLVXBmcL9qJ/t8FxNxGYpC2MO5zGue2
d65JqVbHVjmr+7g+pD204ZFDBZ8buLW6uZWGp7cawiMMq0hwADg7qM1XHklHexcmOEtqoJP7Qez1o8aw
6pEJIE8WnCY2yBnJHwFF9dFuqbFXRSSu0a9tx7nBYo7mC6UnGk5En0NPCWOe8dhJ48kP1GlLErWvNiiO
R1C9RT+aZKzkr/iUrT6oDKxX3kU7jH50JYkXx5WeTir3VsguUmQdnAyR+4rlniZ1RmkLy3HE7Vz9mlMk
bH33JYAf4SP3rnlja3ZdST4Nq0v47m30XUaOxGPAcj6H+ak4QkNc48A3MEA1wQMo/EwzpB/PFceXA+Ud
MMqezLLeyIPCUCkd8kH9ajBb8lJENcCTd4kwPxIw2/Q134pziubOXJCMvwJSC1llzzoN+7ZDfUbGu/H1
DSOLJ06fJ8V5bY3X55r2KZ8hqRdIo85D/IDf61kkK5S9Fg7ISqjf4UUwNJ7s8+XOOWBRasy23sro28fS
hXsOr0Udo190AH13NBtDJN8lOYx6lgPX+KFjaV4PBjq8Iz8qDlRSGPVyFVHY5I+lI22dKSXARCwxlmC/
ClGolptyARjrWsOkJFcAEqyk5B90Z7UUw6QsTOU0kMYzuR1o2wpI6m247a8M4QrvyV8Qj0FfExIzsflV
e5GMbZljbZw/HH+38Tkv55g/MOTECSUT8INck5anZ0xjpVCaQQxzaGzoddgPdzn0qY6E7u0MkgCF22Og
dvgKFhaBQW7hVkRtRGDgHo37GjQpqI1rOdd1aDmEkHL42z28q2wQB4XZxXjqk+uNVyoOx6d8dcf6FDY1
DEfELo2ywRqrqo2lPXboR8BsTWbtUNFU7Os4fwmw1w8uUxzEAmN1yGbHi0n18qtiUdSFyKVMBe+zv2K7
SHWxtmfmRaDjIOx/g0cnT77cCQy7GX7RXVrDfzIJAWhjCMFGc5PQeg6VPL9sqXgeG8bYm19bcStmhjRY
umELbn4HvUZSaKRSZlRGS2uopGj1iJxhQwy2OlHUCtzsuI+0v2rg0lvBCJA2FuCSVYjY6sdDjoT/AL0v
3LZMq5Ra4MniVja3HDo5bUsGCkHbZvMj9CKnjbum7GnFONoVs9awaJUKSR4B9R2qzVEkwsqkFXjOATqz
ncN8KFBs63gvEJZbOGdGPMg8EgHbfY/A/wA0uNachaUtWM+n8E4lJKADN2yoO/yzXbp2OGfNmpNb2124
N3AokU5WVcAj50u/gC5sWvLBY4GQAFTsrdR/IqaVO0dCnapnP3dw/DQwh5gUY1EEkqf3FTyK1wXxbeTM
XjQaQMwZiTnUBp+oNcu3o6d/YweNggmFuW5OAGGot8x+9B6KCtSYSO2upWEhBhRsEHbxehA3qXZhLwP3
ZRCPb3seSrmRM/8AL6geXWpy6dLgdZ75F5SkqNE9qJF6ZyVYeurGRU6lB7Me4yW6PkugI2ZNR+eK+rpL
k/P7b/SSZo8EHOPIVrQNEgZbB+7QKPU5NL/oev8AJlgzk4L/AFo2xWkvBLE498H5UWZf6LCzfk84k6M4
JJxijo2sHc3pIrMn2d1BGoMMqV9elBqho/cWt5YtOXZ0bOCRgg/KpujrhxsWe6QkiLXjPUtnP5bUkn6L
qILmkjr8qSx1EtyMjIOfPFAdIbQIkCJLG5wuoGIDJG/U0yNRIuY4w7yxZVUJwOmewrWOomXfcdadUWG3
G248OlR8qjKbZZRSMWW5nmdw4ALnU+V6nzpDFFlmAGmU6VGAvXAoGJ5txIu7HAOAD39awd2VSaYSa85I
b4ZrADO90xZyxUEfDbz2rBpkwI3LMjLkZ2I7/Kgwodi+/nj8WvcagCB32H5CshjtbOO5s+KG4uXJjikV
UJGc9c4+XeuhRadoS09mzoN7krE4DxmXXG2PcY9R6Z2NduN6lucmVKL2OB45w1ZuMl5k2kAG229c2XHc
ykJ/aYC2rW9+NJ06HwN65ZxrYtF3uemie3mlLldQBQAHoT2zS1Y3DJjvZY3DxgjUc9A31zWMdBwOYTwt
DJgIGIjJJwM9FG/wxUZKpakdOPeNM6e2sIb3hQnMA1H7skjoRuN69PtqUDh16Z7mSOHBdMbIck4AH51D
tu9yutVsESyn4dd86GNiCQkvcMhxkHH+tqbtuwdxUbaG54VxMIrMYmwVIJwQe4rqhGnRyTntZ2XDeNs0
XJuQcqcqxPb4008flCQy+GdBFIVGnOUbfSw6iuaUTpjKjF4tAZQzQsWxswG21ScTohOzjOKIijIXlyjq
Rsr+uPOoziuToUmZEXEBFKAy4OeoO5HzqLx2OstGtHxtlzoK79g/U+fXr8KlLGVjlQxD7TSkgRSkP0KM
d/8AX1pNMkOpRkNP7S3aRh5hNpx7wcAfxQ0uXkNxj4Pl/Ld01duxJ619HTZ8NqSdHordpWwTtWULNLIo
8BDbRopyceWO9NoSE7kmyjIEJC438qWqHTvkGwIwdqDGVFlldc63znoDRTfkDinwgOo5xnNI2VjG2RnL
YAqLZ2QjseLFRg/lSsskQrbbA5pRg8E7QMTt8M0U6M0Gkv3ddJcMR5bbfKm1GopnmAggDV6UBkxGaFYg
Sqd6m4jqRnyBS5OT5nalaGslHieEAnDA+eKWg2iseGkOoeAHzxWo1hXjhV8KNIPl2rUG0GEK8ssSxU7D
+K2lmtDNpbRhssWRm6jJxp+FHSzKSNjhFnG3EFKprCDY43B7VTHjbYs8kUj6RxWwkn4XDK6eKPc+eAOt
d+lM4u4zPtWC3YVsgYBB89qeMaJznZk8esQ1z90p9/K/PFGULFjkOW4zYzxXMBgUag+o5HUVxZsTvY68
OVUeu+Em4tXmiQa1xzOg+dQeJo6VkizJjtkEitpU9mzUqGRs8OtY1ZGWQhS3hC7HUVIzQ06nRVNRVn0b
h/BHmhdLCXEbkHlOdw3oe9etGoo8qUnJmrdcFeEo88IBPXI/Ee9KqkxpNqJqcOsLcRF+TGync47N8KEn
uCD2GpOGWLHDwghTkKR7vwpdTGpCzcJhYusYCtjwjqpFHuPyDtrwHhVoSiBt9vCT0oOmFXEteqoJm0Eg
jf8AmoSi/B0QmvJzXFIrQtqGnD76JNhn0Nc88czthkgzmbvh3B7yN0F01ldJuOYMpn4iuf8A/WLurRVr
DJVdM4a4kvrDirW08WyksHGCCOuQe4roj96tHHNuEqZpRcXAiOkltQxoYA5+XalePcosvopZ3EstyUF4
0atlTE2wP7VRY0T7r9iDXOsktuSPhXoOdnzSx1siBcuqldRwRjFbWwvGmVMh6k5rWFRRIYncmtZmkUeT
PT60GxlEHqwPI0LGoqHy+D070kmXxRLcwKc7CptnSkQX3ySMUo6ILj0rBIBDNuBisYuMg+EeGjRrGYtW
+kH1pqBZdyhGD19azQFISntl1ArGSD5VNxHUgEdiGJGNvQdaGkbUNnhfLh1yDSvXbqabRtuLrB2vCnuJ
f7FG7HyFaOO2aU0jatuHQzYQtgKMjPkKusSZF5Whk2UWWbAA6DJwPnR7SN3WdF7McPtlkE02DGSMEDY1
0Y4JLY58mRt0zvrie1EDEkFMaAPj1/Ssk7A5Kjm+dZnjJSSIhACQxHX0qqWxBz3EeNTWphR4feQg58z2
rPYMHfBh3CrcpDc4Ok7P5gGpT33OiDrYosTRao2X7thjPp/FScSykYnEeE/Zbv3SARsw7GuWeOmdMJ2j
V4HFLG6opBI3IIyCP9ZrQgrDObqj6DwGQ63SNt86l3/I11PdHIrTOvRkvrCS2kQa/JuxqDuMrRZVJUzA
sY7mwknQhkC4YZ371ZyUiKhKA4t8/MDtGSudLHyPn8K2hUDW0wt1r5aywkHbOBSqK4Yzm+UXsrq2u0WO
caH6BhSyhKO6HjkjLZjRgeNSmc+THoaTVZTTXBhcR4dHdHl6Ahb8GPC/w8j6Uz4Gi96ZxfFfZonJR3UE
dGH5VyZHKLOyEYzWzOdXhHEYpgkWJVXYasMMHsQe1Ljy07RsmBtUOXPCDawgi2UNn/lDUM/CrvLFkFhk
kITWkckmlkMMw7sMA/xW7kQPFIx7hrQuRGGwAAoHQbfnXbLSfPRU+QQlwmBGufMihY2nfkoxIXLHGemB
QGW/AIt8fnSjpEFvOsagbN/vStlIxKlwPdpGdMUV5tKULAsd6wbLIjn4nuayQNQ5b2zSSLGqly3kPzqi
hYkp0PrHDCSQqysBgMdwPWn0pE9Vi7uHODkKO3SloOo9yuYQFX9q1B1BjCjfdodWe5/X4VnEKkMwWawL
kjUT2oqNG1BZWjaJnIAGenljpRYUBiI+zBE3Zu47mhE0hxALcp4SdS4q62OeTsI6tcKkCjdjmi1Zk6Nk
aLaxjjgkX7pd8Hqf96otlQklbHbO9e4j0s2lYoySPM9KZOyckDa4UTYODhT+mKInJkl2mVkkAOgEj1xS
SdjwVA7RiLWaPIOjxL8On8VNcF0zT4IVu4JImwJodQGe9BDoWCrNOY5cEEYGf0pHuU4EYsW98rRsQy5X
Y4Oak1TKpnUcKvI7gqD91Ou4kxsfjVE2TkkzuLa7SS3UNhZh1z39M1KXJWK2GHuAo5kxwBswK5zn/XWh
pvgLnp5CiDh3EUIIMUmMGheSH5BWOYuvDmtJNPNDRnpv1FN3b8C9mvJSbgsqM0sQDxnfY9DRWZcMD6d8
oagEwiOoY8snrSuSY8YSQY2ZmQvGiyL1aM9QfSl1pcjaGI39lDMmoRnV0Zeh+tHZ7MKbW6OXvOGKpaWI
aiOuRuPjjeozwrlHVjz3tIyWtjpMjRIyk++CP1GPzFQcW9mXjJcoPa8MWZC6HIHdWDY+hqfbfsrrTPk5
hdYuay6VPTO2flXsVtZ8hqV0C1kZApbH0oIIZCAxA/im0sXWiwSJdXMODjoN61JcguT4BSPDpAAJI8hi
g2h4qXkWc5bIGKmy0SjeI4pWXiyyoo6nJoUNYxBbvO6JGpLMcDanUbFcqNQW8NkMSgSSH3M9PjiqKKRJ
zbJMxSBjpIZhvg/lTXsIxIvI22o48h0pTWMQs5IQLqB6A1hrGdcQjZFZQceJuvyFHYAxbvaRRpgiSbqQ
3c9vgBRVB3G0hnvIpFg2YeIsNsgdh6elGm+DXQveW6wW6Ryk7jUdPU0JRpDKVmdHecpCIokQDbJOanqr
gdq+T0HE7hWAaZZQvQOOlZZGBwTCT8VmkkymlSNhjufWmeRmUEOyXCvAsZXSSQSQdsD/ADpnLYWh21vB
bI3iyhwD5etPGVE5xs0Z3iniEqbDYZ8zjp+VWvY563FEkBuCQRoIPyyKUdAYW5F3KjDIGxB7jyqd0yvg
YtpDZ3sqqd5BlT/d/uKVvceIOR3S85pGY36r3pWyqRa5tGd+egxJjJx+LypHuUSGeH3fImjuQoKE4kQ/
hPQ/KmW4rtHSvdMJYZLcloztpPVT0xTUvJrfKC2/tHImlZULx5wy9foaV4l4D3a5OitLq0u1Sa0lzt4k
bY1P7o7SHqMlcDRkuTGoXO4/C3f4VlFMDbQJuJKqa4mVdsEYo9q9mBZ63RlTe0LwTkTxx6TvqQ9R50V0
22zEfWU/uQ2ntJFGVJILHoQdJqb6eRZdXAK/tFZzgiXDjuyjDL8RSrFJDvNFmbd3cQcNhWjI8E6kkH0b
uKfSwKaFFtIJy7wlST7yAZHzHX5ipyj7LQmYt3ww29yZbaR4JR1Udf8AMVJwLxmuUfJQZZSC5YjzJru3
fJ849MeAoC4wmD5mmr0TbfkrJI5IGQAOw7UG2GMULs2o9qVlUqKMcdSKUZFSC5C7knsKAy2CCE6snwgd
STR0jKQSGISyqkcTPk469aKVhch0XAs3ePJZ2Glih90eQp7oR7lQ7EB5EbceFmPUeVYxY84gSBgSdlUd
cedGmL5KSa4m2UEHrq6Gg9grctHJLI+kDGdsUFY9IENQlAUFvhSjKjQtFCYMiHUTjFPFCyZvcNtp45Vu
JG5ajxKq7ZHYVaMXySlIQv5hJKWJyi5ApJKxoyMl7cFtIx5nHaouJVSLLboFzjetpNqJGmMAqo2rDXYS
aXB0bZ0gbeeaNgovHc+AxkHx9KykBxNCCfVZzQB9IBDLk9D6VVT2J6Nytkz6CSCQD06UIyC4Ap7j/wAe
5CtvvhjvWb3MkUe9LaS43Q4B9PKlsY27aeO/hKscEHdv3rbDpscSYRt4ympRgKejelLpVFVLc9JJYlkk
OY1kO/8A0t/FSaa4LqUHya9naLNHqgkUum3hb9q3da5CsClwZCpcWNzIrklGO/mvkRTxypkpYGhqC+kB
DQMVuUOodtY7g1TWvJHttfpOn4f7RR3UKx30Emn3S6jxIam65gyqviaG5V0nUrLPC3SRdmH+IUyye9hJ
Yt9tzKueFz3MZIQSRA5BUatP8U3yFH8E/iOX5EEsrhFME9rK0flnIx6bb0j6xIZfT21VAJuEzRS8y2uH
TyR0IPyzWfURkFdHKHDGIftUcWp0O5wwPut/FTllSLwwvyUlt7kKJ4BLEwPuP+zCpvMiywvlA14pcvmO
8DMo6Z95fnWtPgaOpP7j42k7s2CdvKqqTPJcEkNR5KZ1HOe1VRCVWQzYONIoMKRQ9KAUQAvlQoNsuJTr
0KAvQZFGzUem+5nZBvg9TvWewyJEjgaQ7eu/Wsa7LKASqjbJxmiGw1vGbiVlLEBVJHy7UUrA2b3BLSO5
id22IV2yPJVJxXRjSaIZHTM5og7KckZOPhk4pGhlJ0M8Wt04ZKIYcky41OeuPL4UJrTwNDfkz4547Yqw
hDuR1Zjj6VNOitWMcNka5md3ONONh33psbtiz2R0l1cGMRQBcmYAtJnfHkK6GRMbiOEkYDonSps1mehO
ck52zU6HvYK03LjB05Jo1RlJtiyXDO+ogYHQVMsuAkr8wjKjIA3rBssbhyVbYEDFKxkVMjMNWem1AIza
3sgBj/CRv61rGPTzFpo8jtitbNSIkYxptuG2INawUX4ZcvHckDcYIPrW1MKW41JdlJShTUM43NG9g1uX
Ls22o48qVjo0bC5fnxAEqWwpKnFI2VjydDn7YrRTbyAeGUbMKm9uDpj92zMiaMXA0uTrQga12Joqbq0I
4Rbpma13c8PlWWOZmDEhlbfNPGV+CM4teTo+HcdkeZUeLUHOk+M/lVW9tiS3e49xG+uuD3StDMzBtwG6
j502NRyLdE80pYXs7Cwe0t1dCQSBlZPxRyFc0mTpIMpi67JwaEkUk9lHO1xIyuNRR9/zGK4KSlpPSTco
6mKzWwCKA7ZbzAIHyxTUCynNkit2jVzpUZ6Df9vyplii1YvcadHOXh5oSdWkRn32fpTOCihNbkf/2Q==
}
DoDisplay
::img::org config -data $imageData
Controller reset
return