Quick summary about SlamSeq:
- Only 3’ UTRs are sequenced
- A modified Uracial called 4-Thiouridine (4SU) is added to the sample. If 4SU is present during transcription there is a certain change (e.g. 2%) that a 4SU is incorporated into the mRNA Instead of a unmodified Uracil.
- 4SU alone has no effect and acts like an unmodified Uracil
- However, when the samples are treated with Iodoacetamide (IAA), which is done after extraction, 4SUs are alkylated (4SU*)
- Alkylated 4SUs are converted to Cytosin druing reverse transcription which is required for sequencing.
- In summary, if a mRNA molecule was transcribed while 4SU was present, reads from this transcript will have a certain rate of T->C mutations (e.g. 2%), if 4SU was not present, no T->C mutations will be visible in the mapped data.
Important terms:
- T->C conversion rate: incorporation rate of 4SU during transcription
- Labeling rate: Looking at all the mRNA molecules for a specific gene that are present at a specific time point, how many of those contain 4SUs (T->C conversions)
Simulation and Evaluation
So far I have simulated data sets for a set of 1000 randomly chosen 3’ UTRs from the mouse annotation set we are using for the real data-sets.
I simulated data sets for all combinations of the following parameters:
- Read length: 38, 88, 138
- Coverage: 25, 50, 75, 100, 150, 200
- T->C conversion rate: 0.024, 0.07
- Labeling rates: between 0.0 and 1.0 in steps of 0.05
For all data sets I compared the simulated labeling rate to the recovered labeling rates by computing:
- Absolut error: simulated - recovered
- Relative error: (simulated - recovered) / simulated
- Log2 error: log2(simulated / recovered)
Based on this I tried visualizing the effect of read length, coverage, T->C rate and labeling rates on the performance of SlamSeq/SlamDunk
Reading data from file
library(dplyr)
library(tidyr)
library(ggplot2)
tcs = c(0.024, 0.07)
covs = c(25, 50, 75, 100, 150, 200)
rls = c(38, 88, 138)
reps = c(1)
# Read data
data = read.table("~/Dropbox/Slamdunk/Data/mesc_1k_random_expressed_eval.tsv", sep = '\t')
dataUnique = read.table("~/Dropbox/Slamdunk/Data/mesc_1k_random_expressed_eval_unique.tsv", sep = '\t')
#data = read.table("~/Dropbox/Slamdunk/Data/golden_list.tsv", sep = '\t')
#dataUnique = read.table("~/Dropbox/Slamdunk/Data/golden_list_unique.tsv", sep = '\t')
Probability to see a T->C mutation in a “labeled” read of length R, given a T->C conversion rate of tcRatePerPosition
readLength = 38
tcRatePerPosition = 0.024
1 - dbinom(0, round(readLength / 4), tcRatePerPosition)
[1] 0.2156712
Relative error for all combinations of read length and coverage
Absolut error for all combinations of read lengths and coverage
Log2 error for all combinations of read lengths and coverage
Relative error for labeling rate bins
Scatter plots: simulated vs recovered labeling rates
LS0tCnRpdGxlOiAiU2xhbUR1bmsgcGFwZXIgc2ltdWxhdGlvbiBub3RlYm9vayIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKCiMjI1F1aWNrIHN1bW1hcnkgYWJvdXQgU2xhbVNlcToKCiogT25seSAzJyBVVFJzIGFyZSBzZXF1ZW5jZWQKKiBBIG1vZGlmaWVkIFVyYWNpYWwgY2FsbGVkIDQtVGhpb3VyaWRpbmUgKDRTVSkgaXMgYWRkZWQgdG8gdGhlIHNhbXBsZS4gSWYgNFNVIGlzIHByZXNlbnQgZHVyaW5nIHRyYW5zY3JpcHRpb24gdGhlcmUgaXMgYSBjZXJ0YWluIGNoYW5nZSAoZS5nLiAyJSkgdGhhdCBhIDRTVSBpcyBpbmNvcnBvcmF0ZWQgaW50byB0aGUgbVJOQSBJbnN0ZWFkIG9mIGEgdW5tb2RpZmllZCBVcmFjaWwuCiogNFNVIGFsb25lIGhhcyBubyBlZmZlY3QgYW5kIGFjdHMgbGlrZSBhbiB1bm1vZGlmaWVkIFVyYWNpbAoqIEhvd2V2ZXIsIHdoZW4gdGhlIHNhbXBsZXMgYXJlIHRyZWF0ZWQgd2l0aCBJb2RvYWNldGFtaWRlIChJQUEpLCB3aGljaCBpcyBkb25lIGFmdGVyIGV4dHJhY3Rpb24sIDRTVXMgYXJlIGFsa3lsYXRlZCAoNFNVKikKKiBBbGt5bGF0ZWQgNFNVcyBhcmUgY29udmVydGVkIHRvIEN5dG9zaW4gZHJ1aW5nIHJldmVyc2UgdHJhbnNjcmlwdGlvbiB3aGljaCBpcyByZXF1aXJlZCBmb3Igc2VxdWVuY2luZy4KKiBJbiBzdW1tYXJ5LCBpZiBhIG1STkEgbW9sZWN1bGUgd2FzIHRyYW5zY3JpYmVkIHdoaWxlIDRTVSB3YXMgcHJlc2VudCwgcmVhZHMgZnJvbSB0aGlzIHRyYW5zY3JpcHQgd2lsbCBoYXZlIGEgY2VydGFpbiByYXRlIG9mIFQtPkMgbXV0YXRpb25zIChlLmcuIDIlKSwgaWYgNFNVIHdhcyBub3QgcHJlc2VudCwgbm8gVC0+QyBtdXRhdGlvbnMgd2lsbCBiZSB2aXNpYmxlIGluIHRoZSBtYXBwZWQgZGF0YS4KCgojIyNJbXBvcnRhbnQgdGVybXM6CgoqIFQtPkMgY29udmVyc2lvbiByYXRlOiBpbmNvcnBvcmF0aW9uIHJhdGUgb2YgNFNVIGR1cmluZyB0cmFuc2NyaXB0aW9uCiogTGFiZWxpbmcgcmF0ZTogTG9va2luZyBhdCBhbGwgdGhlIG1STkEgbW9sZWN1bGVzIGZvciBhIHNwZWNpZmljIGdlbmUgdGhhdCBhcmUgcHJlc2VudCBhdCBhIHNwZWNpZmljIHRpbWUgcG9pbnQsIGhvdyBtYW55IG9mIHRob3NlIGNvbnRhaW4gNFNVcyAoVC0+QyBjb252ZXJzaW9ucykKCiMjIyBTaW11bGF0aW9uIGFuZCBFdmFsdWF0aW9uClNvIGZhciBJIGhhdmUgc2ltdWxhdGVkIGRhdGEgc2V0cyBmb3IgYSBzZXQgb2YgMTAwMCByYW5kb21seSBjaG9zZW4gMycgVVRScyBmcm9tIHRoZSBtb3VzZSBhbm5vdGF0aW9uIHNldCB3ZSBhcmUgdXNpbmcgZm9yIHRoZSByZWFsIGRhdGEtc2V0cy4KCkkgc2ltdWxhdGVkIGRhdGEgc2V0cyBmb3IgYWxsIGNvbWJpbmF0aW9ucyBvZiB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6CgoqIFJlYWQgbGVuZ3RoOiAzOCwgODgsIDEzOAoqIENvdmVyYWdlOiAyNSwgNTAsIDc1LCAxMDAsIDE1MCwgMjAwCiogVC0+QyBjb252ZXJzaW9uIHJhdGU6IDAuMDI0LCAwLjA3CiogTGFiZWxpbmcgcmF0ZXM6IGJldHdlZW4gMC4wIGFuZCAxLjAgaW4gc3RlcHMgb2YgMC4wNQoKRm9yIGFsbCBkYXRhIHNldHMgSSBjb21wYXJlZCB0aGUgc2ltdWxhdGVkIGxhYmVsaW5nIHJhdGUgdG8gdGhlIHJlY292ZXJlZCBsYWJlbGluZyByYXRlcyBieSBjb21wdXRpbmc6CgoqIEFic29sdXQgZXJyb3I6IHNpbXVsYXRlZCAtIHJlY292ZXJlZAoqIFJlbGF0aXZlIGVycm9yOiAoc2ltdWxhdGVkIC0gcmVjb3ZlcmVkKSAvIHNpbXVsYXRlZAoqIExvZzIgZXJyb3I6IGxvZzIoc2ltdWxhdGVkIC8gcmVjb3ZlcmVkKQoKQmFzZWQgb24gdGhpcyBJIHRyaWVkIHZpc3VhbGl6aW5nIHRoZSBlZmZlY3Qgb2YgcmVhZCBsZW5ndGgsIGNvdmVyYWdlLCBULT5DIHJhdGUgYW5kIGxhYmVsaW5nIHJhdGVzIG9uIHRoZSBwZXJmb3JtYW5jZSBvZiBTbGFtU2VxL1NsYW1EdW5rCgoKCiMjIyBSZWFkaW5nIGRhdGEgZnJvbSBmaWxlCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCgp0Y3MgPSBjKDAuMDI0LCAwLjA3KQpjb3ZzID0gYygyNSwgNTAsIDc1LCAxMDAsIDE1MCwgMjAwKQpybHMgPSBjKDM4LCA4OCwgMTM4KQpyZXBzID0gYygxKQoKIyBSZWFkIGRhdGEKZGF0YSA9IHJlYWQudGFibGUoIn4vRHJvcGJveC9TbGFtZHVuay9EYXRhL21lc2NfMWtfcmFuZG9tX2V4cHJlc3NlZF9ldmFsLnRzdiIsIHNlcCA9ICdcdCcpCmRhdGFVbmlxdWUgPSByZWFkLnRhYmxlKCJ+L0Ryb3Bib3gvU2xhbWR1bmsvRGF0YS9tZXNjXzFrX3JhbmRvbV9leHByZXNzZWRfZXZhbF91bmlxdWUudHN2Iiwgc2VwID0gJ1x0JykKCiNkYXRhID0gcmVhZC50YWJsZSgifi9Ecm9wYm94L1NsYW1kdW5rL0RhdGEvZ29sZGVuX2xpc3QudHN2Iiwgc2VwID0gJ1x0JykKI2RhdGFVbmlxdWUgPSByZWFkLnRhYmxlKCJ+L0Ryb3Bib3gvU2xhbWR1bmsvRGF0YS9nb2xkZW5fbGlzdF91bmlxdWUudHN2Iiwgc2VwID0gJ1x0JykKCmBgYAoKCiMjIyMgUHJvYmFiaWxpdHkgdG8gc2VlIGEgVC0+QyBtdXRhdGlvbiBpbiBhICJsYWJlbGVkIiByZWFkIG9mIGxlbmd0aCBSLCBnaXZlbiBhIFQtPkMgY29udmVyc2lvbiByYXRlIG9mIHRjUmF0ZVBlclBvc2l0aW9uCgpgYGB7cn0KcmVhZExlbmd0aCA9IDM4CnRjUmF0ZVBlclBvc2l0aW9uID0gMC4wMjQKMSAtIGRiaW5vbSgwLCByb3VuZChyZWFkTGVuZ3RoIC8gNCksIHRjUmF0ZVBlclBvc2l0aW9uKQoKYGBgCgoKIyMjIyBSZWxhdGl2ZSBlcnJvciBmb3IgYWxsIGNvbWJpbmF0aW9ucyBvZiByZWFkIGxlbmd0aCBhbmQgY292ZXJhZ2UKYGBge3IsIGVjaG89RkFMU0V9CiMgUmVsYXRpdmUgZXJyb3IgCnAxID0gZGF0YSAlPiUgZmlsdGVyKHJsPT0zOCkgJT4lIGdncGxvdCguLCBhZXMoZmFjdG9yKGNvdiksIHJlbF9lcnJvcikpICsgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKyBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTEwMCwxMDApKSArIHlsYWIoInJlbGF0aXZlIGVycm9yIFslXSIpICsgeGxhYigiQ292ZXJhZ2UiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlPSJkYXNoZWQiKSArIGdndGl0bGUoIjM4IGJwIHJlYWRzIikKcHJpbnQocDEpCnAyID0gZGF0YSAlPiUgZmlsdGVyKHJsPT04OCkgJT4lIGdncGxvdCguLCBhZXMoZmFjdG9yKGNvdiksIHJlbF9lcnJvcikpICsgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKyBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTEwMCwxMDApKSArIHlsYWIoInJlbGF0aXZlIGVycm9yIFslXSIpICsgeGxhYigiQ292ZXJhZ2UiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlPSJkYXNoZWQiKSArIGdndGl0bGUoIjg4IGJwIHJlYWRzIikKcHJpbnQocDIpCnAzID0gZGF0YSAlPiUgZmlsdGVyKHJsPT0xMzgpICU+JSBnZ3Bsb3QoLiwgYWVzKGZhY3Rvcihjb3YpLCByZWxfZXJyb3IpKSArIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEpICsgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0xMDAsMTAwKSkgKyB5bGFiKCJyZWxhdGl2ZSBlcnJvciBbJV0iKSArIHhsYWIoIkNvdmVyYWdlIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZT0iZGFzaGVkIikgKyBnZ3RpdGxlKCIxMzggYnAgcmVhZHMiKQpwcmludChwMykKI211bHRpcGxvdChwMSwgcDIsIHAzLCBjb2xzPTIpCmBgYAoKIyMjIyBBYnNvbHV0IGVycm9yIGZvciBhbGwgY29tYmluYXRpb25zIG9mIHJlYWQgbGVuZ3RocyBhbmQgY292ZXJhZ2UKYGBge3IsIGVjaG89RkFMU0V9CnAxID0gZGF0YSAlPiUgZmlsdGVyKHJsPT0zOCkgJT4lIGdncGxvdCguLCBhZXMoZmFjdG9yKGNvdiksIGFic19lcnJvcikpICsgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKyBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTAuNCwwLjQpKSArIHlsYWIoImFic29sdXRlIGVycm9yIFslXSIpICsgeGxhYigiQ292ZXJhZ2UiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlPSJkYXNoZWQiKSArIGdndGl0bGUoIjM4IGJwIHJlYWRzIikKcHJpbnQocDEpCnAyID0gZGF0YSAlPiUgZmlsdGVyKHJsPT04OCkgJT4lIGdncGxvdCguLCBhZXMoZmFjdG9yKGNvdiksIGFic19lcnJvcikpICsgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKyBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTAuNCwwLjQpKSArIHlsYWIoImFic29sdXRlIGVycm9yIFslXSIpICsgeGxhYigiQ292ZXJhZ2UiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlPSJkYXNoZWQiKSArIGdndGl0bGUoIjg4IGJwIHJlYWRzIikKcHJpbnQocDIpCnAzID0gZGF0YSAlPiUgZmlsdGVyKHJsPT0xMzgpICU+JSBnZ3Bsb3QoLiwgYWVzKGZhY3Rvcihjb3YpLCBhYnNfZXJyb3IpKSArIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEpICsgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0wLjQsMC40KSkgKyB5bGFiKCJhYnNvbHV0ZSBlcnJvciBbJV0iKSArIHhsYWIoIkNvdmVyYWdlIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZT0iZGFzaGVkIikgKyBnZ3RpdGxlKCIxMzggYnAgcmVhZHMiKQpwcmludChwMykKCiNtdWx0aXBsb3QocDEsIHAyLCBwMywgY29scz0yKQpgYGAKCiMjIyMgTG9nMiBlcnJvciBmb3IgYWxsIGNvbWJpbmF0aW9ucyBvZiByZWFkIGxlbmd0aHMgYW5kIGNvdmVyYWdlCmBgYHtyLCBlY2hvPUZBTFNFfQojIExvZzIgZXJyb3IKcDEgPSBkYXRhICU+JSBmaWx0ZXIocmw9PTM4KSAlPiUgZ2dwbG90KC4sIGFlcyhmYWN0b3IoY292KSwgbG9nMl9lcnJvcikpICsgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKyBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTEsMSkpICsgeWxhYigicmVsYXRpdmUgZXJyb3IgWyVdIikgKyB4bGFiKCJDb3ZlcmFnZSIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGU9ImRhc2hlZCIpICsgZ2d0aXRsZSgiMzggYnAgcmVhZHMiKQpwcmludChwMSkKcDIgPSBkYXRhICU+JSBmaWx0ZXIocmw9PTg4KSAlPiUgZ2dwbG90KC4sIGFlcyhmYWN0b3IoY292KSwgbG9nMl9lcnJvcikpICsgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKyBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTEsMSkpICsgeWxhYigicmVsYXRpdmUgZXJyb3IgWyVdIikgKyB4bGFiKCJDb3ZlcmFnZSIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGU9ImRhc2hlZCIpICsgZ2d0aXRsZSgiODggYnAgcmVhZHMiKQpwcmludChwMikKcDMgPSBkYXRhICU+JSBmaWx0ZXIocmw9PTEzOCkgJT4lIGdncGxvdCguLCBhZXMoZmFjdG9yKGNvdiksIGxvZzJfZXJyb3IpKSArIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEpICsgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0xLDEpKSArIHlsYWIoInJlbGF0aXZlIGVycm9yIFslXSIpICsgeGxhYigiQ292ZXJhZ2UiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlPSJkYXNoZWQiKSArIGdndGl0bGUoIjEzOCBicCByZWFkcyIpCnByaW50KHAzKQoKI211bHRpcGxvdChwMSwgcDIsIHAzLCBjb2xzPTIpCmBgYAoKIyMjIFJlbGF0aXZlIGVycm9yIGZvciBsYWJlbGluZyByYXRlIGJpbnMKYGBge3IsIGVjaG89RkFMU0V9Cm91dGxpZXJzID0gTkEKI3Bsb3RMaXN0ID0gbGlzdCgpCmZvcihjIGluIGNvdnMpIHsKICBmb3IociBpbiBybHMpIHsKICAgIHAgPSBkYXRhICU+JSBmaWx0ZXIoY292PT1jLCBybD09cikgJT4lIGdncGxvdCguLCBhZXMoZmFjdG9yKG5hbWUpLCByZWxfZXJyb3IpKSArIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gb3V0bGllcnMpICsgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0xMDAsMTAwKSkgKyAgICAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZT0iZGFzaGVkIikgKyB5bGFiKCJyZWxhdGl2ZSBlcnJvciBbJV0iKSArIHhsYWIoIkNvdmVyYWdlIikgKyBnZ3RpdGxlKHBhc3RlMChyLCAiIGJwIHJlYWRzLCAiLCBjLCAiWCBjb3ZlcmFnZSIpKQogICAgcHJpbnQocCkKICAjcGxvdExpc3RbW2xlbmd0aChwbG90TGlzdCkrMV1dID0gcAogIH0KfQojbXVsdGlwbG90KHBsb3RsaXN0ID0gcGxvdExpc3QsIGNvbHM9MikKYGBgCgojIyMjIFNjYXR0ZXIgcGxvdHM6IHNpbXVsYXRlZCB2cyByZWNvdmVyZWQgbGFiZWxpbmcgcmF0ZXMKCmBgYHtyLCBlY2hvPUZBTFNFfQpvdXRsaWVycyA9IE5BCiNwbG90TGlzdCA9IGxpc3QoKQpmb3IociBpbiBjKDM4LCA4OCkpIHsKICBmb3IoYyBpbiBjKDI1LCAxMDApKSB7CiAgCiAgICBwID0gZGF0YSAlPiUgZmlsdGVyKGNvdj09Yywgcmw9PXIpICU+JSBnZ3Bsb3QoLiwgYWVzKHg9c2ltdWxhdGVkLCB5PXNsYW1kdW5rKSkgICsgCiAgICAgIGdlb21fcG9pbnQoc2hhcGU9MSkgKyAKICAgICAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCAgbGluZXR5cGU9ImRhc2hlZCIpICsgCiAgICAgIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLDEpLCB4bGltPWMoMCwxKSkgKwogICAgICB5bGFiKCJTbGFtZHVuayIpICsgeGxhYigiU2ltdWxhdGVkIikgKyBnZ3RpdGxlKHBhc3RlMChyLCAiIGJwIHJlYWRzLCAiLCBjLCAiWCBjb3ZlcmFnZSIpKQogICAgcHJpbnQocCkKICAgICNwbG90TGlzdFtbbGVuZ3RoKHBsb3RMaXN0KSsxXV0gPSBwCiAgfQp9CiNtdWx0aXBsb3QocGxvdGxpc3QgPSBwbG90TGlzdCwgY29scz0yKQpgYGAKCiMjIyMgTWVkaWFuIHJlbGF0aXZlIGVycm9yCmBgYHtyfQoKZm9yKHIgaW4gcmxzKSB7CiAgcCA9IGRhdGEgJT4lIGZpbHRlcihybD09cikgJT4lIGdncGxvdCguLCBhZXMoeD1jb3YsIHk9cmVsX2Vycm9yKSkgKyAKICAgIHN0YXRfc3VtbWFyeShmdW4ueSA9IG1lZGlhbiwgZ2VvbSA9ICJwb2ludCIpICsKICAgIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLDIwKSkgKwogICAgeWxhYigicmVsYXRpdmUgZXJyb3IgWyVdIikgKyB4bGFiKCJDb3ZlcmFnZSIpICsgZ2d0aXRsZShwYXN0ZTAociwgIiBicCByZWFkcyIpKQogIHByaW50KHApCn0KCmBgYAoKYGBge3IsIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmNvdmVyYWdlID0gcmVhZC50YWJsZSgiL3Byb2plY3QvbmdzL3BoaWxpcHAvc2xhbWR1bmstYW5hbHlzaXMvcGFwZXIvcGFwZXJfcnVuc19jb3ZlcmFnZS8zNDM1OV9BbjMxMl93dC0ybl9tUk5BLXNsYW1zZXEtYXV0b3F1YW50XzFoLVIzX3RyaW1tZWQuZnFfc2xhbWR1bmtfbWFwcGVkX2ZpbHRlcmVkX211bHRpY292LmJlZCIpCgpjb3ZlcmFnZSRjb3YgPSAoY292ZXJhZ2UkVjcgKiAzOCkgLyAoY292ZXJhZ2UkVjMgLSBjb3ZlcmFnZSRWMikKaGlzdChjb3ZlcmFnZVtjb3ZlcmFnZSRjb3YgPCAxMDAgJiBjb3ZlcmFnZSRWNyA+IDEwLF0kY292LCBicmVha3M9c2VxKDAsMTAxLGJ5PTUpKQpgYGAKCgpgYGB7cn0KCmRhdGEgJT4lIGdyb3VwX2J5KHNpbXVsYXRlZCwgY292LCBybCkgJT4lIGNvdW50KHJlbF9lcnJvciA8IDIwKQoKZGF0YSAlPiUgZmlsdGVyKHJsID09IDg4LCBjb3YgPT0gMTAwKSAlPiUgZ3JvdXBfYnkoc2ltdWxhdGVkLCBjb3YsIHJsKSAlPiUgY291bnQoYWJzX2Vycm9yIDwgMC4wNSkKCmRhdGEgJT4lIGZpbHRlcihybCA9PSA4OCwgY292ID09IDEwMCkgJT4lIGNvdW50KGFic19lcnJvciA8IDAuMDUpCmRhdGFVbmlxdWUgJT4lIGZpbHRlcihybCA9PSA4OCwgY292ID09IDEwMCkgJT4lIGNvdW50KGFic19lcnJvciA8IDAuMDUpCgpmb3IocmwgaW4gYygzOCwgODgsIDEzOCkpIHsKICBmb3IoY292IGluIGMoNTAsIDEwMCwgMjAwKSkgewoKICAgIGRhdGEgJT4lIGZpbHRlcihybCA9PSBybCwgY292ID09IGNvdikgJT4lIGdncGxvdCguLCBhZXMoYWJzX2Vycm9yKSkgKyB4bGltKC0xLCAxKSArIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4wMSkKICAgIAogIH0KfQoKIyBBIGhpc3RvZ3JhbSBvZiBiaWxsIHNpemVzCmRhdGEgJT4lIGZpbHRlcihybCwgY292ID09IDUwIHwgY292ID09IDEwMCB8IGNvdiA9PSAyMDApICU+JSBnZ3Bsb3QoLiwgYWVzKHg9YWJzX2Vycm9yKSkgKyB4bGltKC0wLjI1LCAwLjI1KSArIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4wMSkgKyBmYWNldF9ncmlkKHJsIH4gY292KQoKZGF0YSAlPiUgZmlsdGVyKHJsLCBjb3YgPT0gNTAgfCBjb3YgPT0gMTAwIHwgY292ID09IDIwMCkgJT4lIGdncGxvdCguLCBhZXMoeD1yZWxfZXJyb3IpKSArIHhsaW0oLTI1LCAyNSkgKyBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsgZmFjZXRfZ3JpZChybCB+IGNvdikKCgpgYGAKCmBgYHtyfQoKCgpgYGAKCgpgYGB7cn0KCnN0YXRzID0gcmVhZC50YWJsZSgiL3Byb2plY3QvbmdzL3BoaWxpcHAvc2xhbWR1bmstYW5hbHlzaXMvcGFwZXIvcGFwZXJfcnVucy9zbGFtZHVua19tRVNDX2Z1bGxfdGltZWNvdXJzZV8xL3N1bW1hcnkudHh0IiwgaGVhZGVyPVQpCgpzdGF0cyRtYXBwZWRfcGVyYyA9IHN0YXRzJE1hcHBlZCAvIHN0YXRzJFNlcXVlbmNlZAoKc3RhdHNbc3RhdHMkU2FtcGxlVHlwZSA9PSAiY2hhc2UiLF0kU2FtcGxlVGltZSA9IDE0NDAgLSBzdGF0c1tzdGF0cyRTYW1wbGVUeXBlID09ICJjaGFzZSIsXSRTYW1wbGVUaW1lCgpwbG90KHN0YXRzJG1hcHBlZF9wZXJjIH4gc3RhdHMkU2FtcGxlVGltZSkKY29yKHN0YXRzJG1hcHBlZF9wZXJjLCBzdGF0cyRTYW1wbGVUaW1lKQoKYGBgCgo=