Introduction
This is a short tutorial for fun on how to customise your R profile,
which shows in the console every time you load R. You should end up with
a console that looks something like this:
Part 1, install packages
Before you start you will need to install the following packages:
usethis - helper functions for package development
praise - fun package to give user praise
lubridate - package for working with dates
purrr - package for doing iteration
cli - tools for building attractive command line interfaces (https://github.com/r-lib/cli)
install.packages(c("usethis", "praise",
"lubridate", "purrr",
"cli"))
Once they are installed you can move to part 2.
Part 2, access your r profile
In order to change your rprofile, you will first need to get access
to it. This is where the usethis package comes in, which has the very
helpful function edit_r_profile()
.
Run the code chunk below to open up your r profile.
# run to open your r profile
usethis::edit_r_profile()
Great, your .Rprofile should now be loaded so we can move to part
3.
Part 3, add code to your profile
The below code chunk contains the code to make your rprofile a bit
more exciting! To use it, copy and paste the code into .Rprofile. Save
it, then restart R. When loaded look at your console and you’ll see the
new console take effect!
if(interactive()) {
# set up welcome
name <- 'Andrew'
hour <- format(Sys.time(), format = '%H') |> as.numeric() |> as.character()
morning <- 0:11
afternoon <- 12:16
evening <- c(17:23)
day_hrs <- rep(
x = c('Morning', 'Afternoon', 'Evening'),
times = c(length(morning), length(afternoon), length(evening))
)
names(day_hrs) <- as.character(0:23)
# clear screen
cat("\014")
cli::cli_text("")
# call r version
cli::cli_text(R.version$version.string)
cli::cli_text("")
# customise the prompt
prompt::set_prompt(function(...){
branch <- (purrr::safely(gert::git_branch))()
if(is.null(branch$result)) return("> ")
return(paste0("[", branch$result, "] > "))
})
# usethis options
options(usethis.protocol = "ssh")
options(usethis.full_name = "Andrew Peter Moles")
# bias against scientific notation
options(scipen = 4)
# speed up package install with Ncpus (parallel installation)
options(Ncpus = 6)
# increase install packages timeout
options(timeout=300)
# R compile speed up - https://twitter.com/grant_mcdermott/status/1493400952878952448
options(collapse_mask = "manip")
# hey, welcome to r
cli::cli_text(
cli::col_yellow(paste0(
'Good ', day_hrs[hour], ', ', name, '!'
))
)
cli::cli_text(
cli::col_br_magenta(paste0(
paste0("Welcome to R and RStudio! ",
intToUtf8(127758), intToUtf8(129429), intToUtf8(129430),
intToUtf8(127794), intToUtf8(128029))
))
)
cli::cli_text("")
# been using and learning r for x days
cli::cli_alert_success(
paste0(
"Using and learning R for ",
lubridate::today() - lubridate::dmy("1 may 16"),
" days ", intToUtf8(129504), intToUtf8(128187)
)
)
# give yourself some praise
cli::cli_alert_success(praise::praise("${exclamation}! You are doing a ${adjective} job, keep up the ${adjective} work!"))
cli::cli_alert_success(praise::praise("${exclamation}! I've been ${adverb} ${creating} R materials since 2018, how ${adjective}"))
cli::cli_text("")
cli::cli_rule(center = '#rstats')
# emoji references:
# list of emoji
# https://unicode.org/emoji/charts/full-emoji-list.html
# add code to search to find html entity
# https://www.compart.com/en/unicode
# Hadley quote to finish
cli::cli_blockquote(
quote = paste0(
'R is not a language driven by the purity of its philosophy; ',
'R is a language designed to get shit done.'
),
citation = '@hadleywickham, rstudioconf2022.'
)
}
Part 4, edit the script to suit you
Using the script, change parts of it to suit you. You can change when
you first started learning R, edit the welcome message or more!
To help you, below are some details on what is happening in
the script:
The first section clears the console screen so you have a blank slate
to work with.
The second section adds the prompt to tell you how long you’ve been
learning R for: it uses a combination of paste0 and lubridate. To change
this to when you started learning R, change the date from 1 may 16 to
whenever your first R experience was. You can add other achievements (or
failures using cli::cli_alert_warning()
) here too, like
when you graduated or learned to drive.
The third section tells you what git branch you are in. This is very
helpful if you are using git with R. If you are not using git you will
just get the default console setting.
The next section uses paste and praise to add welcome messages. If
you want to find out more about the praise package, check out it’s github repo.
You will notice within paste we have a function with a six digit
code: intToUtf8(129429)
. We are taking a html entity code
and converting it, which provides us with an emoji. How do we get this?
First, you need to use this list of
emojis to find the emoji you want and copy the code. For example,
the code U+1F995
is for a sauropod. We then search for that
code in a unicode
converter, pasting the code in the search menu. You should get a
page up with the emoji and other information; you’ll want the
html entity part, which for the sauropod is
129429
. You only need the digits. Take them and add them to
the intToUtf8()
function and you’ll get your emoji!
The final section adds options. I’ve added Ncpus = 6
,
this effects the install.packages
function, and using
Ncpus = 6
means it will use 6 cores rather than the default
2 cores; this means it will install packages much faster!
That’s it! Enjoy editing and making a welcoming rprofile.
LS0tCnRpdGxlOiAiQ2hhbmdpbmcgeW91ciAuUnByb2ZpbGUgdHV0b3JpYWwiCmF1dGhvcjoKICAgLSBuYW1lOiBBbmRyZXcgTW9sZXMKICAgICBhZmZpbGlhdGlvbjogTGVhcm5pbmcgRGV2ZWxvcGVyLCBEaWdpdGFsIFNraWxscyBMYWIKZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6IAogICAgdGhlbWU6IHJlYWRhYmxlCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzCiAgICBrZWVwX21kOiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKIyBJbnRyb2R1Y3Rpb24KClRoaXMgaXMgYSBzaG9ydCB0dXRvcmlhbCBmb3IgZnVuIG9uIGhvdyB0byBjdXN0b21pc2UgeW91ciBSIHByb2ZpbGUsIHdoaWNoIHNob3dzIGluIHRoZSBjb25zb2xlIGV2ZXJ5IHRpbWUgeW91IGxvYWQgUi4gWW91IHNob3VsZCBlbmQgdXAgd2l0aCBhIGNvbnNvbGUgdGhhdCBsb29rcyBzb21ldGhpbmcgbGlrZSB0aGlzOgoKIVtdKHJwcm9maWxlLnBuZyl7d2lkdGg9IjYwMyJ9CgojIFBhcnQgMSwgaW5zdGFsbCBwYWNrYWdlcwoKQmVmb3JlIHlvdSBzdGFydCB5b3Ugd2lsbCBuZWVkIHRvIGluc3RhbGwgdGhlIGZvbGxvd2luZyBwYWNrYWdlczoKCi0gICB1c2V0aGlzIC0gaGVscGVyIGZ1bmN0aW9ucyBmb3IgcGFja2FnZSBkZXZlbG9wbWVudAoKLSAgIHByYWlzZSAtIGZ1biBwYWNrYWdlIHRvIGdpdmUgdXNlciBwcmFpc2UKCi0gICBsdWJyaWRhdGUgLSBwYWNrYWdlIGZvciB3b3JraW5nIHdpdGggZGF0ZXMKCi0gICBwdXJyciAtIHBhY2thZ2UgZm9yIGRvaW5nIGl0ZXJhdGlvbgoKLSAgIGNsaSAtIHRvb2xzIGZvciBidWlsZGluZyBhdHRyYWN0aXZlIGNvbW1hbmQgbGluZSBpbnRlcmZhY2VzICg8aHR0cHM6Ly9naXRodWIuY29tL3ItbGliL2NsaT4pCgpgYGB7ciBldmFsPUZBTFNFfQppbnN0YWxsLnBhY2thZ2VzKGMoInVzZXRoaXMiLCAicHJhaXNlIiwgCiAgICAgICAgICAgICAgICAgICAibHVicmlkYXRlIiwgInB1cnJyIiwKICAgICAgICAgICAgICAgICAgICJjbGkiKSkKYGBgCgpPbmNlIHRoZXkgYXJlIGluc3RhbGxlZCB5b3UgY2FuIG1vdmUgdG8gcGFydCAyLgoKIyBQYXJ0IDIsIGFjY2VzcyB5b3VyIHIgcHJvZmlsZQoKSW4gb3JkZXIgdG8gY2hhbmdlIHlvdXIgcnByb2ZpbGUsIHlvdSB3aWxsIGZpcnN0IG5lZWQgdG8gZ2V0IGFjY2VzcyB0byBpdC4gVGhpcyBpcyB3aGVyZSB0aGUgdXNldGhpcyBwYWNrYWdlIGNvbWVzIGluLCB3aGljaCBoYXMgdGhlIHZlcnkgaGVscGZ1bCBmdW5jdGlvbiBgZWRpdF9yX3Byb2ZpbGUoKWAuCgpSdW4gdGhlIGNvZGUgY2h1bmsgYmVsb3cgdG8gb3BlbiB1cCB5b3VyIHIgcHJvZmlsZS4KCmBgYHtyIGV2YWw9RkFMU0V9CiMgcnVuIHRvIG9wZW4geW91ciByIHByb2ZpbGUKdXNldGhpczo6ZWRpdF9yX3Byb2ZpbGUoKQpgYGAKCkdyZWF0LCB5b3VyIC5ScHJvZmlsZSBzaG91bGQgbm93IGJlIGxvYWRlZCBzbyB3ZSBjYW4gbW92ZSB0byBwYXJ0IDMuCgojIFBhcnQgMywgYWRkIGNvZGUgdG8geW91ciBwcm9maWxlCgpUaGUgYmVsb3cgY29kZSBjaHVuayBjb250YWlucyB0aGUgY29kZSB0byBtYWtlIHlvdXIgcnByb2ZpbGUgYSBiaXQgbW9yZSBleGNpdGluZyEgVG8gdXNlIGl0LCBjb3B5IGFuZCBwYXN0ZSB0aGUgY29kZSBpbnRvIC5ScHJvZmlsZS4gU2F2ZSBpdCwgdGhlbiByZXN0YXJ0IFIuIFdoZW4gbG9hZGVkIGxvb2sgYXQgeW91ciBjb25zb2xlIGFuZCB5b3UnbGwgc2VlIHRoZSBuZXcgY29uc29sZSB0YWtlIGVmZmVjdCEKCmBgYHtyIGV2YWw9RkFMU0V9CmlmKGludGVyYWN0aXZlKCkpIHsKICAKICAjIHNldCB1cCB3ZWxjb21lCiAgbmFtZSA8LSAnQW5kcmV3JwogIGhvdXIgPC0gZm9ybWF0KFN5cy50aW1lKCksIGZvcm1hdCA9ICclSCcpIHw+IGFzLm51bWVyaWMoKSB8PiBhcy5jaGFyYWN0ZXIoKQogIAogIG1vcm5pbmcgPC0gMDoxMQogIGFmdGVybm9vbiA8LSAxMjoxNgogIGV2ZW5pbmcgPC0gYygxNzoyMykKICAKICBkYXlfaHJzIDwtIHJlcCgKICAgIHggPSBjKCdNb3JuaW5nJywgJ0FmdGVybm9vbicsICdFdmVuaW5nJyksIAogICAgdGltZXMgPSBjKGxlbmd0aChtb3JuaW5nKSwgbGVuZ3RoKGFmdGVybm9vbiksIGxlbmd0aChldmVuaW5nKSkKICApCiAgCiAgbmFtZXMoZGF5X2hycykgPC0gYXMuY2hhcmFjdGVyKDA6MjMpCiAgCiAgIyBjbGVhciBzY3JlZW4KICBjYXQoIlwwMTQiKSAKICBjbGk6OmNsaV90ZXh0KCIiKQogICMgY2FsbCByIHZlcnNpb24KICBjbGk6OmNsaV90ZXh0KFIudmVyc2lvbiR2ZXJzaW9uLnN0cmluZykgCiAgY2xpOjpjbGlfdGV4dCgiIikKICAKICAjIGN1c3RvbWlzZSB0aGUgcHJvbXB0CiAgcHJvbXB0OjpzZXRfcHJvbXB0KGZ1bmN0aW9uKC4uLil7CiAgICBicmFuY2ggPC0gKHB1cnJyOjpzYWZlbHkoZ2VydDo6Z2l0X2JyYW5jaCkpKCkKICAgIGlmKGlzLm51bGwoYnJhbmNoJHJlc3VsdCkpIHJldHVybigiPiAiKQogICAgcmV0dXJuKHBhc3RlMCgiWyIsIGJyYW5jaCRyZXN1bHQsICJdID4gIikpCiAgfSkKICAKICAjIHVzZXRoaXMgb3B0aW9ucwogIG9wdGlvbnModXNldGhpcy5wcm90b2NvbCA9ICJzc2giKQogIG9wdGlvbnModXNldGhpcy5mdWxsX25hbWUgPSAiQW5kcmV3IFBldGVyIE1vbGVzIikKICAKICAjIGJpYXMgYWdhaW5zdCBzY2llbnRpZmljIG5vdGF0aW9uCiAgb3B0aW9ucyhzY2lwZW4gPSA0KQogIAogICMgc3BlZWQgdXAgcGFja2FnZSBpbnN0YWxsIHdpdGggTmNwdXMgKHBhcmFsbGVsIGluc3RhbGxhdGlvbikKICBvcHRpb25zKE5jcHVzID0gNikKICAKICAjIGluY3JlYXNlIGluc3RhbGwgcGFja2FnZXMgdGltZW91dCAKICBvcHRpb25zKHRpbWVvdXQ9MzAwKQogIAogICMgUiBjb21waWxlIHNwZWVkIHVwIC0gaHR0cHM6Ly90d2l0dGVyLmNvbS9ncmFudF9tY2Rlcm1vdHQvc3RhdHVzLzE0OTM0MDA5NTI4Nzg5NTI0NDgKICBvcHRpb25zKGNvbGxhcHNlX21hc2sgPSAibWFuaXAiKQogIAogICMgaGV5LCB3ZWxjb21lIHRvIHIKICBjbGk6OmNsaV90ZXh0KAogICAgY2xpOjpjb2xfeWVsbG93KHBhc3RlMCgKICAgICAgJ0dvb2QgJywgZGF5X2hyc1tob3VyXSwgJywgJywgbmFtZSwgJyEnCiAgICApKQogICkKICBjbGk6OmNsaV90ZXh0KAogICAgY2xpOjpjb2xfYnJfbWFnZW50YShwYXN0ZTAoCiAgICAgIHBhc3RlMCgiV2VsY29tZSB0byBSIGFuZCBSU3R1ZGlvISAiLCAKICAgICAgICAgICAgIGludFRvVXRmOCgxMjc3NTgpLCBpbnRUb1V0ZjgoMTI5NDI5KSwgaW50VG9VdGY4KDEyOTQzMCksIAogICAgICAgICAgICAgaW50VG9VdGY4KDEyNzc5NCksIGludFRvVXRmOCgxMjgwMjkpKQogICAgKSkKICApCiAgY2xpOjpjbGlfdGV4dCgiIikKICAjIGJlZW4gdXNpbmcgYW5kIGxlYXJuaW5nIHIgZm9yIHggZGF5cwogIGNsaTo6Y2xpX2FsZXJ0X3N1Y2Nlc3MoCiAgICBwYXN0ZTAoCiAgICAgICJVc2luZyBhbmQgbGVhcm5pbmcgUiBmb3IgIiwKICAgICAgbHVicmlkYXRlOjp0b2RheSgpIC0gbHVicmlkYXRlOjpkbXkoIjEgbWF5IDE2IiksCiAgICAgICIgZGF5cyAiLCBpbnRUb1V0ZjgoMTI5NTA0KSwgaW50VG9VdGY4KDEyODE4NykKICAgICkKICApCiAgIyBnaXZlIHlvdXJzZWxmIHNvbWUgcHJhaXNlCiAgY2xpOjpjbGlfYWxlcnRfc3VjY2VzcyhwcmFpc2U6OnByYWlzZSgiJHtleGNsYW1hdGlvbn0hIFlvdSBhcmUgZG9pbmcgYSAke2FkamVjdGl2ZX0gam9iLCBrZWVwIHVwIHRoZSAke2FkamVjdGl2ZX0gd29yayEiKSkKICBjbGk6OmNsaV9hbGVydF9zdWNjZXNzKHByYWlzZTo6cHJhaXNlKCIke2V4Y2xhbWF0aW9ufSEgSSd2ZSBiZWVuICR7YWR2ZXJifSAke2NyZWF0aW5nfSBSIG1hdGVyaWFscyBzaW5jZSAyMDE4LCBob3cgJHthZGplY3RpdmV9IikpCiAgY2xpOjpjbGlfdGV4dCgiIikKICAKICBjbGk6OmNsaV9ydWxlKGNlbnRlciA9ICcjcnN0YXRzJykKICAKICAjIGVtb2ppIHJlZmVyZW5jZXM6CiAgIyBsaXN0IG9mIGVtb2ppCiAgIyBodHRwczovL3VuaWNvZGUub3JnL2Vtb2ppL2NoYXJ0cy9mdWxsLWVtb2ppLWxpc3QuaHRtbAogICMgYWRkIGNvZGUgdG8gc2VhcmNoIHRvIGZpbmQgaHRtbCBlbnRpdHkKICAjIGh0dHBzOi8vd3d3LmNvbXBhcnQuY29tL2VuL3VuaWNvZGUgCiAgCiAgIyBIYWRsZXkgcXVvdGUgdG8gZmluaXNoCiAgY2xpOjpjbGlfYmxvY2txdW90ZSgKICAgIHF1b3RlID0gcGFzdGUwKAogICAgICAnUiBpcyBub3QgYSBsYW5ndWFnZSBkcml2ZW4gYnkgdGhlIHB1cml0eSBvZiBpdHMgcGhpbG9zb3BoeTsgJywgCiAgICAgICdSIGlzIGEgbGFuZ3VhZ2UgZGVzaWduZWQgdG8gZ2V0IHNoaXQgZG9uZS4nCiAgICApLCAKICAgIAogICAgY2l0YXRpb24gPSAnQGhhZGxleXdpY2toYW0sIHJzdHVkaW9jb25mMjAyMi4nCiAgKQp9CmBgYAoKIyBQYXJ0IDQsIGVkaXQgdGhlIHNjcmlwdCB0byBzdWl0IHlvdQoKVXNpbmcgdGhlIHNjcmlwdCwgY2hhbmdlIHBhcnRzIG9mIGl0IHRvIHN1aXQgeW91LiBZb3UgY2FuIGNoYW5nZSB3aGVuIHlvdSBmaXJzdCBzdGFydGVkIGxlYXJuaW5nIFIsIGVkaXQgdGhlIHdlbGNvbWUgbWVzc2FnZSBvciBtb3JlIQoKKipUbyBoZWxwIHlvdSwgYmVsb3cgYXJlIHNvbWUgZGV0YWlscyBvbiB3aGF0IGlzIGhhcHBlbmluZyBpbiB0aGUgc2NyaXB0OioqCgpUaGUgZmlyc3Qgc2VjdGlvbiBjbGVhcnMgdGhlIGNvbnNvbGUgc2NyZWVuIHNvIHlvdSBoYXZlIGEgYmxhbmsgc2xhdGUgdG8gd29yayB3aXRoLgoKVGhlIHNlY29uZCBzZWN0aW9uIGFkZHMgdGhlIHByb21wdCB0byB0ZWxsIHlvdSBob3cgbG9uZyB5b3UndmUgYmVlbiBsZWFybmluZyBSIGZvcjogaXQgdXNlcyBhIGNvbWJpbmF0aW9uIG9mIHBhc3RlMCBhbmQgbHVicmlkYXRlLiBUbyBjaGFuZ2UgdGhpcyB0byB3aGVuIHlvdSBzdGFydGVkIGxlYXJuaW5nIFIsIGNoYW5nZSB0aGUgZGF0ZSBmcm9tIDEgbWF5IDE2IHRvIHdoZW5ldmVyIHlvdXIgZmlyc3QgUiBleHBlcmllbmNlIHdhcy4gWW91IGNhbiBhZGQgb3RoZXIgYWNoaWV2ZW1lbnRzIChvciBmYWlsdXJlcyB1c2luZyBgY2xpOjpjbGlfYWxlcnRfd2FybmluZygpYCkgaGVyZSB0b28sIGxpa2Ugd2hlbiB5b3UgZ3JhZHVhdGVkIG9yIGxlYXJuZWQgdG8gZHJpdmUuCgpUaGUgdGhpcmQgc2VjdGlvbiB0ZWxscyB5b3Ugd2hhdCBnaXQgYnJhbmNoIHlvdSBhcmUgaW4uIFRoaXMgaXMgdmVyeSBoZWxwZnVsIGlmIHlvdSBhcmUgdXNpbmcgZ2l0IHdpdGggUi4gSWYgeW91IGFyZSBub3QgdXNpbmcgZ2l0IHlvdSB3aWxsIGp1c3QgZ2V0IHRoZSBkZWZhdWx0IGNvbnNvbGUgc2V0dGluZy4KClRoZSBuZXh0IHNlY3Rpb24gdXNlcyBwYXN0ZSBhbmQgcHJhaXNlIHRvIGFkZCB3ZWxjb21lIG1lc3NhZ2VzLiBJZiB5b3Ugd2FudCB0byBmaW5kIG91dCBtb3JlIGFib3V0IHRoZSBwcmFpc2UgcGFja2FnZSwgY2hlY2sgb3V0IGl0J3MgW2dpdGh1YiByZXBvXShodHRwczovL2dpdGh1Yi5jb20vcmxhZGllcy9wcmFpc2UpLgoKWW91IHdpbGwgbm90aWNlIHdpdGhpbiBwYXN0ZSB3ZSBoYXZlIGEgZnVuY3Rpb24gd2l0aCBhIHNpeCBkaWdpdCBjb2RlOiBgaW50VG9VdGY4KDEyOTQyOSlgLiBXZSBhcmUgdGFraW5nIGEgaHRtbCBlbnRpdHkgY29kZSBhbmQgY29udmVydGluZyBpdCwgd2hpY2ggcHJvdmlkZXMgdXMgd2l0aCBhbiBlbW9qaS4gSG93IGRvIHdlIGdldCB0aGlzPyBGaXJzdCwgeW91IG5lZWQgdG8gdXNlIHRoaXMgW2xpc3Qgb2YgZW1vamlzXShodHRwczovL3VuaWNvZGUub3JnL2Vtb2ppL2NoYXJ0cy9mdWxsLWVtb2ppLWxpc3QuaHRtbCkgdG8gZmluZCB0aGUgZW1vamkgeW91IHdhbnQgYW5kIGNvcHkgdGhlIGNvZGUuIEZvciBleGFtcGxlLCB0aGUgY29kZSBgVSsxRjk5NWAgaXMgZm9yIGEgc2F1cm9wb2QuIFdlIHRoZW4gc2VhcmNoIGZvciB0aGF0IGNvZGUgaW4gYSBbdW5pY29kZSBjb252ZXJ0ZXJdKGh0dHBzOi8vd3d3LmNvbXBhcnQuY29tL2VuL3VuaWNvZGUpLCBwYXN0aW5nIHRoZSBjb2RlIGluIHRoZSBzZWFyY2ggbWVudS4gWW91IHNob3VsZCBnZXQgYSBwYWdlIHVwIHdpdGggdGhlIGVtb2ppIGFuZCBvdGhlciBpbmZvcm1hdGlvbjsgeW91J2xsIHdhbnQgdGhlICoqKmh0bWwgZW50aXR5KioqIHBhcnQsIHdoaWNoIGZvciB0aGUgc2F1cm9wb2QgaXMgYDEyOTQyOWAuIFlvdSBvbmx5IG5lZWQgdGhlIGRpZ2l0cy4gVGFrZSB0aGVtIGFuZCBhZGQgdGhlbSB0byB0aGUgYGludFRvVXRmOCgpYCBmdW5jdGlvbiBhbmQgeW91J2xsIGdldCB5b3VyIGVtb2ppIQoKVGhlIGZpbmFsIHNlY3Rpb24gYWRkcyBvcHRpb25zLiBJJ3ZlIGFkZGVkIGBOY3B1cyA9IDZgLCB0aGlzIGVmZmVjdHMgdGhlIGBpbnN0YWxsLnBhY2thZ2VzYCBmdW5jdGlvbiwgYW5kIHVzaW5nIGBOY3B1cyA9IDZgIG1lYW5zIGl0IHdpbGwgdXNlIDYgY29yZXMgcmF0aGVyIHRoYW4gdGhlIGRlZmF1bHQgMiBjb3JlczsgdGhpcyBtZWFucyBpdCB3aWxsIGluc3RhbGwgcGFja2FnZXMgbXVjaCBmYXN0ZXIhCgpUaGF0J3MgaXQhIEVuam95IGVkaXRpbmcgYW5kIG1ha2luZyBhIHdlbGNvbWluZyBycHJvZmlsZS4K