#install.packages('googlesheets4')
library(googlesheets4)
library(tidyverse)
library(ggstance)
library(ggbeeswarm)
# make some helpful shortcuts
x.theme.axis.rotate <- theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
standard.textsize <- 10
text.size.within <- (5/14)*(standard.textsize-4)
panel.lab.size <- 10
theme.text.size <- theme(text = element_text(size = standard.textsize))
/ Import googlesheet
gs4_deauth()
#CostaRica_assembly.stats <- read_sheet("https://docs.google.com/spreadsheets/d/1CEDScAVSXuboNu-K_-lZzkPnk9woO_3MFRZ8zgWG3c0/edit?usp=sharing", sheet="Instructor_Testing")
CostaRica_assembly.stats <- read_sheet("https://docs.google.com/spreadsheets/d/1CEDScAVSXuboNu-K_-lZzkPnk9woO_3MFRZ8zgWG3c0/edit#gid=0", sheet="Student_Results")
✔ Reading from WCS_Costa_Rica_2024__Assembly_methods_comparisons.
✔ Range ''Student_Results''.
New names:
• `` -> `...13`
CostaRica_assembly.stats <- CostaRica_assembly.stats %>%
filter(!is.na(`Student Name`))
Create a variable ‘method_full’ that summarises the methods used
CostaRica_assembly.stats <- CostaRica_assembly.stats %>%
mutate(method_full=paste0(`Assembler (Unicycler/Dragonflye)`, "__", `Assembly Type (short/long/hybrid)`, "__", `Number of long reads (if used)`)) %>%
mutate(student_method=paste0(`Student Name`, "_", method_full))
Do some basic plotting
CostaRica_assembly.stats %>%
arrange(desc(`# contigs`)) %>%
mutate(method_full=factor(method_full, levels=unique(method_full))) %>%
ggplot(aes(y=method_full, x=`# contigs`, color=`Assembly Type (short/long/hybrid)`)) +
geom_quasirandom(width=0.4, alpha=0.75, groupOnX=F) +
theme_bw() + theme(legend.position = 'none') +
theme.text.size +
labs(y="Method", x="# Contigs", title="# Contigs for each method")
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`
ggsave(paste0("Assembly.Methods.by.Contig.count.png"), units='mm', width=120, height=70, device='png', dpi=300)
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`

CostaRica_assembly.stats %>%
arrange((`N50`)) %>%
mutate(method_full=factor(method_full, levels=unique(method_full))) %>%
ggplot(aes(y=method_full, x=`N50`, color=`Assembly Type (short/long/hybrid)`)) +
geom_quasirandom(width=0.4, alpha=0.75, groupOnX=F) +
theme_bw() + theme(legend.position = 'none') +
theme.text.size +
labs(y="Method", x="N50", title="N50 for each method")
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`
ggsave(paste0("Assembly.Methods.by.N50.png"), units='mm', width=120, height=70, device='png', dpi=300)
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`

CostaRica_assembly.stats %>%
arrange(desc(`# misassemblies`)) %>%
mutate(method_full=factor(method_full, levels=unique(method_full))) %>%
ggplot(aes(y=method_full, x=`# misassemblies`, color=`Assembly Type (short/long/hybrid)`)) +
geom_quasirandom(width=0.4, alpha=0.75, groupOnX=F) +
theme_bw() + theme(legend.position = 'none') +
theme.text.size +
labs(y="Method", x="# Misassemblies", title="# Misassemblies for each method")
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`
ggsave(paste0("Assembly.Methods.by.Missassembly.count.png"), units='mm', width=120, height=70, device='png', dpi=300)
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`

Do some more analyses by technique
CostaRica_assembly.stats %>%
arrange((`N50`)) %>%
mutate(method_full=factor(`Assembly Type (short/long/hybrid)`, levels=unique(`Assembly Type (short/long/hybrid)`))) %>%
ggplot(aes(y=method_full, x=`N50`, color=`Assembler (Unicycler/Dragonflye)`)) +
geom_quasirandom(width=0.4, alpha=0.75, groupOnX=F) +
theme_bw() + theme(legend.position = 'bottom') +
theme.text.size +
labs(y="Assembly Type", x="N50", title="N50 for each Assembly Type")
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`
ggsave(paste0("Assembly.Type.by.N50.png"), units='mm', width=120, height=60, device='png', dpi=300)
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`

CostaRica_assembly.stats %>%
arrange((`N50`)) %>%
mutate(method_full=factor(`Assembly Type (short/long/hybrid)`, levels=unique(`Assembly Type (short/long/hybrid)`))) %>%
filter(!is.na(N50)) %>%
ggplot(aes(y=method_full, x=`N50`, color=factor(`Number of long reads (if used)`))) +
#ggplot(aes(y=method_full, x=`N50`)) +
geom_quasirandom(width=0.4, alpha=0.75, groupOnX=F) +
theme_bw() + theme(legend.position = 'bottom') +
theme.text.size +
facet_grid(`Assembler (Unicycler/Dragonflye)`~.) +
labs(y="Assembly Type", x="N50", title="N50 for each Assembly Type", color="# Long Reads")
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`
ggsave(paste0("Assembly.Type.+.readinput.by.N50.png"), units='mm', width=120, height=90, device='png', dpi=300)
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`

Plot N50 by person
CostaRica_assembly.stats %>%
arrange((`N50`)) %>%
#filter(method_full=="Unicycler__hybrid__10000") %>%
mutate(`student_method`=factor(`student_method`, levels=unique(`student_method`))) %>%
ggplot(aes(y=`student_method`, x=`N50`, color=`Student Name`)) +
geom_quasirandom(width=0.4, alpha=0.75, groupOnX=F) +
#geom_barh(width=0.5, stat='identity') +
theme_bw() + theme(legend.position = 'none') +
theme.text.size +
geom_text(aes((N50+500000), `student_method`,label=`Student Name`), size=2.5) +
labs(y="Student", x="N50", title="N50 for each Student")
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`
ggsave(paste0("Student.by.N50.png"), units='mm', width=110, height=140, device='png', dpi=900)
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`

CostaRica_assembly.stats %>%
arrange(desc(`# contigs`)) %>%
#filter(method_full=="Unicycler__hybrid__10000") %>%
mutate(student_method=factor(`student_method`, levels=unique(`student_method`))) %>%
ggplot(aes(y=`student_method`, x=`# contigs`, color=`Student Name`)) +
#geom_quasirandom(width=0.4, alpha=0.75, groupOnX=F) +
geom_quasirandom() +
#geom_barh(width=0.5, stat='identity') +
theme_bw() + theme(legend.position = 'none') +
theme.text.size +
geom_text(aes((`# contigs`+80), `student_method`,label=`Student Name`), size=2.5) +
labs(y="Student", x="# Contigs", title="# Contigs for each Student") +
#coord_cartesian(xlim=c(1,500)) #+ scale_x_log10() +
NULL
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`
ggsave(paste0("Student.by.Contig.count.png"), units='mm', width=110, height=140, device='png', dpi=900)
Orientation inferred to be along y-axis; override with
`position_quasirandom(orientation = 'x')`

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayAtIEFzc2VtYmx5IG1ldHJpY3MgIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCdnb29nbGVzaGVldHM0JykKbGlicmFyeShnb29nbGVzaGVldHM0KQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3N0YW5jZSkKbGlicmFyeShnZ2JlZXN3YXJtKQoKIyBtYWtlIHNvbWUgaGVscGZ1bCBzaG9ydGN1dHMKeC50aGVtZS5heGlzLnJvdGF0ZSA8LSB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSwgaGp1c3Q9MSkpCgpzdGFuZGFyZC50ZXh0c2l6ZSA8LSAxMAp0ZXh0LnNpemUud2l0aGluIDwtICg1LzE0KSooc3RhbmRhcmQudGV4dHNpemUtNCkKcGFuZWwubGFiLnNpemUgPC0gMTAKCnRoZW1lLnRleHQuc2l6ZSA8LSB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSBzdGFuZGFyZC50ZXh0c2l6ZSkpCgpgYGAKCgovIApJbXBvcnQgZ29vZ2xlc2hlZXQgCmBgYHtyfQpnczRfZGVhdXRoKCkKI0Nvc3RhUmljYV9hc3NlbWJseS5zdGF0cyA8LSByZWFkX3NoZWV0KCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xQ0VEU2NBVlNYdWJvTnUtS18tbFp6a1Buazl3b09fM01GUlo4emdXRzNjMC9lZGl0P3VzcD1zaGFyaW5nIiwgc2hlZXQ9Ikluc3RydWN0b3JfVGVzdGluZyIpCgpDb3N0YVJpY2FfYXNzZW1ibHkuc3RhdHMgPC0gcmVhZF9zaGVldCgiaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMUNFRFNjQVZTWHVib051LUtfLWxaemtQbms5d29PXzNNRlJaOHpnV0czYzAvZWRpdCNnaWQ9MCIsIHNoZWV0PSJTdHVkZW50X1Jlc3VsdHMiKQoKQ29zdGFSaWNhX2Fzc2VtYmx5LnN0YXRzIDwtIENvc3RhUmljYV9hc3NlbWJseS5zdGF0cyAlPiUKICBmaWx0ZXIoIWlzLm5hKGBTdHVkZW50IE5hbWVgKSkKYGBgClwKQ3JlYXRlIGEgdmFyaWFibGUgJ21ldGhvZF9mdWxsJyB0aGF0IHN1bW1hcmlzZXMgdGhlIG1ldGhvZHMgdXNlZApgYGB7cn0KQ29zdGFSaWNhX2Fzc2VtYmx5LnN0YXRzIDwtIENvc3RhUmljYV9hc3NlbWJseS5zdGF0cyAlPiUKICBtdXRhdGUobWV0aG9kX2Z1bGw9cGFzdGUwKGBBc3NlbWJsZXIgKFVuaWN5Y2xlci9EcmFnb25mbHllKWAsICJfXyIsIGBBc3NlbWJseSBUeXBlIChzaG9ydC9sb25nL2h5YnJpZClgLCAiX18iLCBgTnVtYmVyIG9mIGxvbmcgcmVhZHMgKGlmIHVzZWQpYCkpICU+JQogIG11dGF0ZShzdHVkZW50X21ldGhvZD1wYXN0ZTAoYFN0dWRlbnQgTmFtZWAsICJfIiwgbWV0aG9kX2Z1bGwpKQoKYGBgCgpcCkRvIHNvbWUgYmFzaWMgcGxvdHRpbmcKYGBge3J9CkNvc3RhUmljYV9hc3NlbWJseS5zdGF0cyAlPiUKICBhcnJhbmdlKGRlc2MoYCMgY29udGlnc2ApKSAlPiUKICBtdXRhdGUobWV0aG9kX2Z1bGw9ZmFjdG9yKG1ldGhvZF9mdWxsLCBsZXZlbHM9dW5pcXVlKG1ldGhvZF9mdWxsKSkpICU+JQogIGdncGxvdChhZXMoeT1tZXRob2RfZnVsbCwgeD1gIyBjb250aWdzYCwgY29sb3I9YEFzc2VtYmx5IFR5cGUgKHNob3J0L2xvbmcvaHlicmlkKWApKSArCiAgZ2VvbV9xdWFzaXJhbmRvbSh3aWR0aD0wLjQsIGFscGhhPTAuNzUsIGdyb3VwT25YPUYpICsKICB0aGVtZV9idygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSArIAogIHRoZW1lLnRleHQuc2l6ZSArIAogIGxhYnMoeT0iTWV0aG9kIiwgeD0iIyBDb250aWdzIiwgdGl0bGU9IiMgQ29udGlncyBmb3IgZWFjaCBtZXRob2QiKQpnZ3NhdmUocGFzdGUwKCJBc3NlbWJseS5NZXRob2RzLmJ5LkNvbnRpZy5jb3VudC5wbmciKSwgdW5pdHM9J21tJywgd2lkdGg9MTIwLCBoZWlnaHQ9NzAsIGRldmljZT0ncG5nJywgZHBpPTMwMCkKCgpDb3N0YVJpY2FfYXNzZW1ibHkuc3RhdHMgJT4lCiAgYXJyYW5nZSgoYE41MGApKSAlPiUKICBtdXRhdGUobWV0aG9kX2Z1bGw9ZmFjdG9yKG1ldGhvZF9mdWxsLCBsZXZlbHM9dW5pcXVlKG1ldGhvZF9mdWxsKSkpICU+JQogIGdncGxvdChhZXMoeT1tZXRob2RfZnVsbCwgeD1gTjUwYCwgY29sb3I9YEFzc2VtYmx5IFR5cGUgKHNob3J0L2xvbmcvaHlicmlkKWApKSArCiAgZ2VvbV9xdWFzaXJhbmRvbSh3aWR0aD0wLjQsIGFscGhhPTAuNzUsIGdyb3VwT25YPUYpICsKICB0aGVtZV9idygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSArIAogIHRoZW1lLnRleHQuc2l6ZSArCiAgbGFicyh5PSJNZXRob2QiLCB4PSJONTAiLCB0aXRsZT0iTjUwIGZvciBlYWNoIG1ldGhvZCIpCmdnc2F2ZShwYXN0ZTAoIkFzc2VtYmx5Lk1ldGhvZHMuYnkuTjUwLnBuZyIpLCB1bml0cz0nbW0nLCB3aWR0aD0xMjAsIGhlaWdodD03MCwgZGV2aWNlPSdwbmcnLCBkcGk9MzAwKQoKQ29zdGFSaWNhX2Fzc2VtYmx5LnN0YXRzICU+JQogIGFycmFuZ2UoZGVzYyhgIyBtaXNhc3NlbWJsaWVzYCkpICU+JQogIG11dGF0ZShtZXRob2RfZnVsbD1mYWN0b3IobWV0aG9kX2Z1bGwsIGxldmVscz11bmlxdWUobWV0aG9kX2Z1bGwpKSkgJT4lCiAgZ2dwbG90KGFlcyh5PW1ldGhvZF9mdWxsLCB4PWAjIG1pc2Fzc2VtYmxpZXNgLCBjb2xvcj1gQXNzZW1ibHkgVHlwZSAoc2hvcnQvbG9uZy9oeWJyaWQpYCkpICsKICBnZW9tX3F1YXNpcmFuZG9tKHdpZHRoPTAuNCwgYWxwaGE9MC43NSwgZ3JvdXBPblg9RikgKwogIHRoZW1lX2J3KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAnbm9uZScpICsgCiAgdGhlbWUudGV4dC5zaXplICsKICBsYWJzKHk9Ik1ldGhvZCIsIHg9IiMgTWlzYXNzZW1ibGllcyIsIHRpdGxlPSIjIE1pc2Fzc2VtYmxpZXMgZm9yIGVhY2ggbWV0aG9kIikKZ2dzYXZlKHBhc3RlMCgiQXNzZW1ibHkuTWV0aG9kcy5ieS5NaXNzYXNzZW1ibHkuY291bnQucG5nIiksIHVuaXRzPSdtbScsIHdpZHRoPTEyMCwgaGVpZ2h0PTcwLCBkZXZpY2U9J3BuZycsIGRwaT0zMDApCgpgYGAKClwKRG8gc29tZSBtb3JlIGFuYWx5c2VzIGJ5IHRlY2huaXF1ZQpgYGB7cn0KQ29zdGFSaWNhX2Fzc2VtYmx5LnN0YXRzICU+JQogIGFycmFuZ2UoKGBONTBgKSkgJT4lCiAgbXV0YXRlKG1ldGhvZF9mdWxsPWZhY3RvcihgQXNzZW1ibHkgVHlwZSAoc2hvcnQvbG9uZy9oeWJyaWQpYCwgbGV2ZWxzPXVuaXF1ZShgQXNzZW1ibHkgVHlwZSAoc2hvcnQvbG9uZy9oeWJyaWQpYCkpKSAlPiUKICBnZ3Bsb3QoYWVzKHk9bWV0aG9kX2Z1bGwsIHg9YE41MGAsIGNvbG9yPWBBc3NlbWJsZXIgKFVuaWN5Y2xlci9EcmFnb25mbHllKWApKSArCiAgZ2VvbV9xdWFzaXJhbmRvbSh3aWR0aD0wLjQsIGFscGhhPTAuNzUsIGdyb3VwT25YPUYpICsKICB0aGVtZV9idygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ2JvdHRvbScpICsgCiAgdGhlbWUudGV4dC5zaXplICsKICBsYWJzKHk9IkFzc2VtYmx5IFR5cGUiLCB4PSJONTAiLCB0aXRsZT0iTjUwIGZvciBlYWNoIEFzc2VtYmx5IFR5cGUiKQpnZ3NhdmUocGFzdGUwKCJBc3NlbWJseS5UeXBlLmJ5Lk41MC5wbmciKSwgdW5pdHM9J21tJywgd2lkdGg9MTIwLCBoZWlnaHQ9NjAsIGRldmljZT0ncG5nJywgZHBpPTMwMCkKCgpDb3N0YVJpY2FfYXNzZW1ibHkuc3RhdHMgJT4lCiAgYXJyYW5nZSgoYE41MGApKSAlPiUKICBtdXRhdGUobWV0aG9kX2Z1bGw9ZmFjdG9yKGBBc3NlbWJseSBUeXBlIChzaG9ydC9sb25nL2h5YnJpZClgLCBsZXZlbHM9dW5pcXVlKGBBc3NlbWJseSBUeXBlIChzaG9ydC9sb25nL2h5YnJpZClgKSkpICU+JQogIGZpbHRlcighaXMubmEoTjUwKSkgJT4lCiAgZ2dwbG90KGFlcyh5PW1ldGhvZF9mdWxsLCB4PWBONTBgLCBjb2xvcj1mYWN0b3IoYE51bWJlciBvZiBsb25nIHJlYWRzIChpZiB1c2VkKWApKSkgKwogICNnZ3Bsb3QoYWVzKHk9bWV0aG9kX2Z1bGwsIHg9YE41MGApKSArCiAgZ2VvbV9xdWFzaXJhbmRvbSh3aWR0aD0wLjQsIGFscGhhPTAuNzUsIGdyb3VwT25YPUYpICsKICB0aGVtZV9idygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ2JvdHRvbScpICsgCiAgdGhlbWUudGV4dC5zaXplICsgCiAgZmFjZXRfZ3JpZChgQXNzZW1ibGVyIChVbmljeWNsZXIvRHJhZ29uZmx5ZSlgfi4pICsKICBsYWJzKHk9IkFzc2VtYmx5IFR5cGUiLCB4PSJONTAiLCB0aXRsZT0iTjUwIGZvciBlYWNoIEFzc2VtYmx5IFR5cGUiLCBjb2xvcj0iIyBMb25nIFJlYWRzIikKZ2dzYXZlKHBhc3RlMCgiQXNzZW1ibHkuVHlwZS4rLnJlYWRpbnB1dC5ieS5ONTAucG5nIiksIHVuaXRzPSdtbScsIHdpZHRoPTEyMCwgaGVpZ2h0PTkwLCBkZXZpY2U9J3BuZycsIGRwaT0zMDApCmBgYApcClwKClBsb3QgTjUwIGJ5IHBlcnNvbgpgYGB7cn0KQ29zdGFSaWNhX2Fzc2VtYmx5LnN0YXRzICU+JQogIGFycmFuZ2UoKGBONTBgKSkgJT4lCiAgI2ZpbHRlcihtZXRob2RfZnVsbD09IlVuaWN5Y2xlcl9faHlicmlkX18xMDAwMCIpICU+JQogIG11dGF0ZShgc3R1ZGVudF9tZXRob2RgPWZhY3Rvcihgc3R1ZGVudF9tZXRob2RgLCBsZXZlbHM9dW5pcXVlKGBzdHVkZW50X21ldGhvZGApKSkgJT4lCiAgZ2dwbG90KGFlcyh5PWBzdHVkZW50X21ldGhvZGAsIHg9YE41MGAsIGNvbG9yPWBTdHVkZW50IE5hbWVgKSkgKwogIGdlb21fcXVhc2lyYW5kb20od2lkdGg9MC40LCBhbHBoYT0wLjc1LCBncm91cE9uWD1GKSArCiAgI2dlb21fYmFyaCh3aWR0aD0wLjUsIHN0YXQ9J2lkZW50aXR5JykgKyAKICB0aGVtZV9idygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSArIAogIHRoZW1lLnRleHQuc2l6ZSArIAogIGdlb21fdGV4dChhZXMoKE41MCs1MDAwMDApLCBgc3R1ZGVudF9tZXRob2RgLGxhYmVsPWBTdHVkZW50IE5hbWVgKSwgc2l6ZT0yLjUpICsKICBsYWJzKHk9IlN0dWRlbnQiLCB4PSJONTAiLCB0aXRsZT0iTjUwIGZvciBlYWNoIFN0dWRlbnQiKQoKZ2dzYXZlKHBhc3RlMCgiU3R1ZGVudC5ieS5ONTAucG5nIiksIHVuaXRzPSdtbScsIHdpZHRoPTExMCwgaGVpZ2h0PTE0MCwgZGV2aWNlPSdwbmcnLCBkcGk9OTAwKQoKCkNvc3RhUmljYV9hc3NlbWJseS5zdGF0cyAlPiUKICBhcnJhbmdlKGRlc2MoYCMgY29udGlnc2ApKSAlPiUKICAjZmlsdGVyKG1ldGhvZF9mdWxsPT0iVW5pY3ljbGVyX19oeWJyaWRfXzEwMDAwIikgJT4lCiAgbXV0YXRlKHN0dWRlbnRfbWV0aG9kPWZhY3Rvcihgc3R1ZGVudF9tZXRob2RgLCBsZXZlbHM9dW5pcXVlKGBzdHVkZW50X21ldGhvZGApKSkgJT4lCiAgZ2dwbG90KGFlcyh5PWBzdHVkZW50X21ldGhvZGAsIHg9YCMgY29udGlnc2AsIGNvbG9yPWBTdHVkZW50IE5hbWVgKSkgKwogICNnZW9tX3F1YXNpcmFuZG9tKHdpZHRoPTAuNCwgYWxwaGE9MC43NSwgZ3JvdXBPblg9RikgKwogIGdlb21fcXVhc2lyYW5kb20oKSArCiAgI2dlb21fYmFyaCh3aWR0aD0wLjUsIHN0YXQ9J2lkZW50aXR5JykgKyAKICB0aGVtZV9idygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSArIAogIHRoZW1lLnRleHQuc2l6ZSArIAogIGdlb21fdGV4dChhZXMoKGAjIGNvbnRpZ3NgKzgwKSwgYHN0dWRlbnRfbWV0aG9kYCxsYWJlbD1gU3R1ZGVudCBOYW1lYCksIHNpemU9Mi41KSArCiAgbGFicyh5PSJTdHVkZW50IiwgeD0iIyBDb250aWdzIiwgdGl0bGU9IiMgQ29udGlncyBmb3IgZWFjaCBTdHVkZW50IikgKwogICNjb29yZF9jYXJ0ZXNpYW4oeGxpbT1jKDEsNTAwKSkgIysgc2NhbGVfeF9sb2cxMCgpICsKTlVMTAoKZ2dzYXZlKHBhc3RlMCgiU3R1ZGVudC5ieS5Db250aWcuY291bnQucG5nIiksIHVuaXRzPSdtbScsIHdpZHRoPTExMCwgaGVpZ2h0PTE0MCwgZGV2aWNlPSdwbmcnLCBkcGk9OTAwKQoKYGBgCgoK