fdata6 = read.delim("jun10_2016_fdata6.txt",
    stringsAsFactors = F,
    check.names = F)
    
  noness = filter(fdata6, fdata6$essential == 0)
  noness = noness %>% arrange(strain)

preprocessing for low cnts – 1. count matrix 2. filter count matrix for ALL rows < 50 3. filter count matrix for all CTRLS < 50

example, SC dropouts hom samples


xbar= as.matrix(read.delim('aug6_2016_hom_barseq.txt',header = T,stringsAsFactors =F,check.names = F,strip.white = T))

p11 = read.delim("oct2_phsbar.txt",header = T,stringsAsFactors = F,check.names = F)

w11 = which(p11$type == 'ctrl')
lp11 = p11[-w11,]
#filter out essential strains
wnebar = which(noness$strain %in% rownames(xbar))

cat(paste0(' # of rows before filtering: ',nrow(xbar)))

hsbar = myall_less50(xbar[noness$strain[wnebar],p11$name])

cat(paste0(' # of rows after filtering for ALL cnts < 50: ',nrow(hsbar)))

hsbar = mymin50(hsbar,w11)

cat(paste0(' # of rows after filtering cnts less 50 in ANY control: ',nrow(hsbar)))

retrieve normalized counts from edgeR and DESeq2, and normalizing by count w/out package

group = model factor

ref = reference condition

hsbar = hsbar[,p11$name]

p11$cond = factor(p11$cond)
p11$cond = relevel(p11$cond,ref='sc')
hdds = mydds(hsbar,groups = p11$cond)

hedge = myedgeR(hsbar,group = p11$cond,ref = 'sc')

mysumtags = sum counts from up and down tags

mysumcond = sum counts from each condition

post processing normalized count matrix collapse matrix dimensions by:

  1. sum up and downtags
  2. summing replicate condtions
hdds2 = myproc_normcounts(hdds,p11$cond)

hedge2 = myproc_normcounts(hedge,p11$cond)

compare this to same data generated by arrays

x11= as.matrix(read.delim('x11.txt',header = T,stringsAsFactors =F,check.names = F,strip.white = T))

x111 = mymixEMctrl(x11,w11)
btst = myBesttag(x111,bgThresh = 6.3)
hbat = ComBat(btst,mod = model.matrix(~cond,p11),batch = p11$pcr)
tsw = mysweep(hbat)

hsum = mysumm(tsw[,-w11],lp11$cond)

comparison to normalizing by counts/experiment without an R package

tst = mybarnorm(hsbar)

tst2 = myproc_normcounts(tst,p11$cond)

noRpkg = tst2[,colnames(hsum)]

plot comparisions

YPD oliver and hom

get barseq ypd data

xobar= as.matrix(read.delim('count_matrix_aug4_noctrl_celnames.txt',
header = T,stringsAsFactors = F,sep = "\t",row.names = 1,check.names = F,as.is=TRUE))

perica = read.delim("jun10_2016_pfinal_erica.txt",header = T,stringsAsFactors=F, check.names = F)

w= which(perica$celfile %in% colnames(xobar))

pbar = perica[w,]

xobar = xobar[which(rownames(xobar) %in% noness$strain),pbar$celfile]

colnames(xobar)=pbar$name

#pjen = data.frame(name= colnames(xobar)[grep('Jen',colnames(xobar))])

phybar = pbar %>% filter(pool == 'hom',media == 'ypd')
poybar = pbar %>% filter(pool == 'oliver',media == 'ypd')
phybar = phybar %>% arrange(type,cond,pcr)
poybar = poybar %>% arrange(type,cond,pcr)

woybar = which(poybar$type == 'ctrl')
whybar = which(phybar$type == 'ctrl')

filter as above for low counts

dds and edge evaluation for ypd – check out the FEB17 0083 outlier for hom ypd


hydds = mydds(hybar,phybar$cond)
oydds = mydds(oybar,poybar$cond)
hyedge = myedgeR(hybar,phybar$cond,ref = 'ypd')
oyedge = myedgeR(oybar,poybar$cond,ref = 'ypd')
hyd = myproc_normcounts(hydds,phybar$cond)
oyd = myproc_normcounts(oydds,poybar$cond)

hyj = myproc_normcounts(hyedge,phybar$cond)
oyj = myproc_normcounts(oyedge,poybar$cond)

ypd array datag


xochip= as.matrix(read.delim(
"xochip.txt",header = T,stringsAsFactors = F,check.names = F))

omix = xochip[,poybar$name]
omix = mymixEMctrl(omix,woybar)
omix = medShift.updn(omix)
omin = min(apply(omix[,woybar],1,median))

hmix = xochip[,phybar$name]
hmix = mymixEMctrl(hmix,whybar)
hmin = min(apply(hmix[,whybar],1,median))

bomix = myBesttag(omix,bgThresh=omin)

bhmix = myBesttag(hmix,bgThresh=hmin)

#before batch correction
mydendy(bhmix,phybar$pcr)

bhybat = ComBat(bhmix,mod=model.matrix(~cond,phybar),batch=phybar$pcr)
#after batch correction
mydendy(bhybat,phybar$cond)

#oliver before batch correction
mydendy(bomix,poybar$cond)
boybat = ComBat(bomix,mod=model.matrix(~cond,poybar),batch=poybar$pcr)

#oliver after batch correction
mydendy(boybat,poybar$cond)

hysw= mysweep(bhybat)
lphybar = phybar[-whybar,]
#summarize chip data
hysum = mysumm(hysw[,lphybar$name],lphybar$cond)

oysw= mysweep(boybat)
lpoybar = poybar[-woybar,]
oysum = mysumm(oysw[,lpoybar$name],lpoybar$cond)

normalize YPD data by count

noRhy = mybarnorm(hybar)

noRhy3 = myproc_normcounts(noRhy,phybar$cond)

noRhy3 = noRhy3[,colnames(hysum)]

noRoy = mybarnorm(oybar)

noRoy3 = myproc_normcounts(noRoy,poybar$cond)

noRoy3 = noRoy3[,colnames(oysum),drop=F]

plot YPD results

hom YPD


opar <- par(pch=19,mfrow=c(1,2),mar=c(2.2,2,1.4,1),cex=1.2)
for (i in 1:ncol(hysum)) { 
  
  p1(hysum,i)
  p1(noRhy3,i)
  p1(hyj,i)
  p1(hyd,i)
  
}

oliver YPD


opar <- par(pch=19,mfrow=c(1,2),mar=c(2.2,2,1.4,1),cex=1.2)
for (i in 1:ncol(oysum)) { 
  
  p1(oysum,i)
  p1(noRoy3,i,sig =0.7)
  p1(oyj,i,sig =0.7)
  p1(oyd,i,sig =0.7)
  
}

compare to combining biological replicates with standard edge:

  1. up and downtags separately, collapsed by summation after dispersion estimates

hs_std_edge = mydfedge(hsbar,p11$cond,ref= 'sc')
mhs_std = as.matrix(hs_std_edge[,1:5])
rownames(mhs_std) = hs_std_edge$strain

hs_sumtags = mysumtags(mybarnorm(hsbar))
hs_std_sumtags = mydfedge(hs_sumtags,p11$cond,ref= 'sc')
mhs_std_sumtags = as.matrix(hs_std_sumtags[,1:5])
rownames(mhs_std_sumtags) = hs_std_sumtags$strain
mhs_std_sumtags= mhs_std_sumtags[order(rownames(mhs_std_sumtags)),]



hy_std_edge = mydfedge(hybar,phybar$cond,ref= 'ypd')
mhy_std = as.matrix(hy_std_edge[,1:4])
rownames(mhy_std) = hy_std_edge$strain


hy_sumtags = mysumtags(mybarnorm(hybar))

hy_std_sumtags = mydfedge(hy_sumtags,phybar$cond,ref= 'ypd')
mhy_std_sumtags = as.matrix(hy_std_sumtags[,1:4])
rownames(mhy_std_sumtags) = hy_std_sumtags$strain
mhy_std_sumtags= mhy_std_sumtags[order(rownames(mhy_std_sumtags)),]
  1. normalize up and downtags separately before combining, predispersion

plot standard edge, pre-summed up and downtags

opar <- par(pch=19,mfrow=c(1,2),mar=c(2.2,2,1.4,1),cex=1.2)
for (i in 1:3)
psig(-mhs_std_sumtags,hedge2,i)

for (i in 1:2)
psig(-mhy_std_sumtags,hyj,i)
LS0tCnRpdGxlOiAiY2hpcF9iYXJzZXEuUm1kIgphdXRob3I6ICJnZ2lhZXZlciIKZGF0ZTogIjAyLzEwLzIwMTYiCm91dHB1dDogaHRtbF9ub3RlYm9vawpjc3M6IGNvbXBsZXgtY3NzLmNzcwotLS0KCgpgYGB7ciBzZXR1cCBsaWJyYXJpZXMsaW5jbHVkZT1GfQpsaWJyYXJ5KGtuaXRyKQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFQpCmxpYnJhcnkoZHBseXIpCiMgIyBsaWJyYXJ5KHJlc2hhcGUyKQojIGxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShzdmEpCiMgbGlicmFyeShERVNlcTIpCiMgCmxpYnJhcnkoUkNvbG9yQnJld2VyKQojIGxpYnJhcnkoZWRnZVIpCnBhbGV0dGUoYnJld2VyLnBhbCg4LCdTZXQyJykpCgojIG15Y29sb3JzID0gYygiZGFya29yYW5nZSIgLCJkb2RnZXJibHVlIiwibGltZWdyZWVuIiwibmF2eSIsImhvdHBpbmsiLCAgICAicGx1bTQiLCJibHVlIiAsICJtYWdlbnRhMiIsIm1lZGl1bXB1cnBsZSIgICwgICJmaXJlYnJpY2siICwiZGFya29saXZlZ3JlZW40Iiwicm95YWxibHVlMyIpCiMgcGFsZXR0ZShteWNvbG9ycykKI3NvdXJjZSgiMDcxMzE2X2Z1bmNzX2VyaWNhLlIiKQpvcGFyIDwtIHBhcihwY2g9MTksbWZyb3c9YygxLDEpLG1hcj1jKDIuMiwyLDEuNCwxKSxjZXg9MSkKCnNvdXJjZSgiYXVnMTVfd29ya2luZ19jaGlwX3Byb2Nlc3NpbmcuUiIpCnNvdXJjZSgiYmFyc2VxX2Z1bmN0aW9ucy5SIikKCmBgYAoKYGBge3IgZ2V0IGdlbmUgaW5mb30KICBmZGF0YTYgPSByZWFkLmRlbGltKCJqdW4xMF8yMDE2X2ZkYXRhNi50eHQiLAogICAgc3RyaW5nc0FzRmFjdG9ycyA9IEYsCiAgICBjaGVjay5uYW1lcyA9IEYpCiAgICAKICBub25lc3MgPSBmaWx0ZXIoZmRhdGE2LCBmZGF0YTYkZXNzZW50aWFsID09IDApCiAgbm9uZXNzID0gbm9uZXNzICU+JSBhcnJhbmdlKHN0cmFpbikKCmBgYAoKCnByZXByb2Nlc3NpbmcgZm9yIGxvdyBjbnRzIC0tIAoxLiBjb3VudCBtYXRyaXgKMi4gZmlsdGVyIGNvdW50IG1hdHJpeCBmb3IgQUxMIHJvd3MgPCA1MAozLiBmaWx0ZXIgY291bnQgbWF0cml4IGZvciBhbGwgQ1RSTFMgPCA1MAoKI2V4YW1wbGUsIFNDIGRyb3BvdXRzIGhvbSBzYW1wbGVzCmBgYHtyIFNDIGJhcnNlcSBkYXRhfQoKeGJhcj0gYXMubWF0cml4KHJlYWQuZGVsaW0oJ2F1ZzZfMjAxNl9ob21fYmFyc2VxLnR4dCcsaGVhZGVyID0gVCxzdHJpbmdzQXNGYWN0b3JzID1GLGNoZWNrLm5hbWVzID0gRixzdHJpcC53aGl0ZSA9IFQpKQoKcDExID0gcmVhZC5kZWxpbSgib2N0Ml9waHNiYXIudHh0IixoZWFkZXIgPSBULHN0cmluZ3NBc0ZhY3RvcnMgPSBGLGNoZWNrLm5hbWVzID0gRikKCncxMSA9IHdoaWNoKHAxMSR0eXBlID09ICdjdHJsJykKbHAxMSA9IHAxMVstdzExLF0KI2ZpbHRlciBvdXQgZXNzZW50aWFsIHN0cmFpbnMKd25lYmFyID0gd2hpY2gobm9uZXNzJHN0cmFpbiAlaW4lIHJvd25hbWVzKHhiYXIpKQoKY2F0KHBhc3RlMCgnICMgb2Ygcm93cyBiZWZvcmUgZmlsdGVyaW5nOiAnLG5yb3coeGJhcikpKQoKaHNiYXIgPSBteWFsbF9sZXNzNTAoeGJhcltub25lc3Mkc3RyYWluW3duZWJhcl0scDExJG5hbWVdKQoKY2F0KHBhc3RlMCgnICMgb2Ygcm93cyBhZnRlciBmaWx0ZXJpbmcgZm9yIEFMTCBjbnRzIDwgNTA6ICcsbnJvdyhoc2JhcikpKQoKaHNiYXIgPSBteW1pbjUwKGhzYmFyLHcxMSkKCmNhdChwYXN0ZTAoJyAjIG9mIHJvd3MgYWZ0ZXIgZmlsdGVyaW5nIGNudHMgbGVzcyA1MCBpbiBBTlkgY29udHJvbDogJyxucm93KGhzYmFyKSkpCgoKYGBgCnJldHJpZXZlIG5vcm1hbGl6ZWQgY291bnRzIGZyb20gZWRnZVIgYW5kIERFU2VxMiwgYW5kIG5vcm1hbGl6aW5nIGJ5IGNvdW50IHcvb3V0IHBhY2thZ2UKCmdyb3VwID0gbW9kZWwgZmFjdG9yCgpyZWYgPSByZWZlcmVuY2UgY29uZGl0aW9uCmBgYHtyfQpoc2JhciA9IGhzYmFyWyxwMTEkbmFtZV0KCnAxMSRjb25kID0gZmFjdG9yKHAxMSRjb25kKQpwMTEkY29uZCA9IHJlbGV2ZWwocDExJGNvbmQscmVmPSdzYycpCmhkZHMgPSBteWRkcyhoc2Jhcixncm91cHMgPSBwMTEkY29uZCkKCmhlZGdlID0gbXllZGdlUihoc2Jhcixncm91cCA9IHAxMSRjb25kLHJlZiA9ICdzYycpCmBgYAoKbXlzdW10YWdzID0gc3VtIGNvdW50cyBmcm9tIHVwIGFuZCBkb3duIHRhZ3MKCm15c3VtY29uZCA9IHN1bSBjb3VudHMgZnJvbSBlYWNoIGNvbmRpdGlvbgoKcG9zdCBwcm9jZXNzaW5nIG5vcm1hbGl6ZWQgY291bnQgbWF0cml4CmNvbGxhcHNlIG1hdHJpeCBkaW1lbnNpb25zIGJ5OgoKMS4gc3VtIHVwIGFuZCBkb3dudGFncyAKMi4gc3VtbWluZyByZXBsaWNhdGUgY29uZHRpb25zCmBgYHtyIHBvc3Qgbm9ybWFsaXplZCBjbnQgcHJvY2Vzc2luZ30KaGRkczIgPSBteXByb2Nfbm9ybWNvdW50cyhoZGRzLHAxMSRjb25kKQoKaGVkZ2UyID0gbXlwcm9jX25vcm1jb3VudHMoaGVkZ2UscDExJGNvbmQpCmBgYAoKY29tcGFyZSB0aGlzIHRvIHNhbWUgZGF0YSBnZW5lcmF0ZWQgYnkgYXJyYXlzCmBgYHtyIFNDIGhvbSBjaGlwIGRhdGF9CngxMT0gYXMubWF0cml4KHJlYWQuZGVsaW0oJ3gxMS50eHQnLGhlYWRlciA9IFQsc3RyaW5nc0FzRmFjdG9ycyA9RixjaGVjay5uYW1lcyA9IEYsc3RyaXAud2hpdGUgPSBUKSkKCngxMTEgPSBteW1peEVNY3RybCh4MTEsdzExKQpidHN0ID0gbXlCZXN0dGFnKHgxMTEsYmdUaHJlc2ggPSA2LjMpCmhiYXQgPSBDb21CYXQoYnRzdCxtb2QgPSBtb2RlbC5tYXRyaXgofmNvbmQscDExKSxiYXRjaCA9IHAxMSRwY3IpCnRzdyA9IG15c3dlZXAoaGJhdCkKCmhzdW0gPSBteXN1bW0odHN3WywtdzExXSxscDExJGNvbmQpCmBgYAoKCmNvbXBhcmlzb24gdG8gbm9ybWFsaXppbmcgYnkgY291bnRzL2V4cGVyaW1lbnQgd2l0aG91dCBhbiBSIHBhY2thZ2UKYGBge3IgaG9tIFNDIG5vUiBwYWNrYWdlfQp0c3QgPSBteWJhcm5vcm0oaHNiYXIpCgp0c3QyID0gbXlwcm9jX25vcm1jb3VudHModHN0LHAxMSRjb25kKQoKbm9ScGtnID0gdHN0MlssY29sbmFtZXMoaHN1bSldCmBgYAoKcGxvdCBjb21wYXJpc2lvbnMKYGBge3IsIGZpZy53aWR0aD0xMixmaWcuaGVpZ2h0PTYsZWNobyA9IEZ9CmhlZGdlMj1oZWRnZTJbLGNvbG5hbWVzKGhzdW0pXQoKaGRkczI9aGRkczJbLGNvbG5hbWVzKGhzdW0pXQoKY29sbmFtZXMoaHN1bSk9cGFzdGUwKCdjaGlwLicsY29sbmFtZXMoaHN1bSkpCmNvbG5hbWVzKGhlZGdlMik9cGFzdGUwKCdlZGdlLicsY29sbmFtZXMoaGVkZ2UyKSkKY29sbmFtZXMoaGRkczIpPXBhc3RlMCgnZGVzZXEyLicsY29sbmFtZXMoaGRkczIpKQpjb2xuYW1lcyhub1Jwa2cpPXBhc3RlMCgnbm9ScGtnLicsY29sbmFtZXMobm9ScGtnKSkKCm9wYXIgPC0gcGFyKHBjaD0xOSxtZnJvdz1jKDEsMiksbWFyPWMoMi4yLDIsMS40LDEpLGNleD0xLjIpCmhzdW0gPSBoc3VtW29yZGVyKHJvd25hbWVzKGhzdW0pKSxdCgpmb3IgKGkgaW4gMTpuY29sKGhzdW0pKSB7IAogIHAxKGhzdW0saSkKICBwMShub1Jwa2csaSkKICBwMShoZWRnZTIsaSkKICBwMShoZGRzMixpKQp9CmBgYAoKCgoKI1lQRCBvbGl2ZXIgYW5kIGhvbQpnZXQgYmFyc2VxIHlwZCBkYXRhCmBgYHtyLCBnZXQgeXBkIGNoaXBkYXRhfQp4b2Jhcj0gYXMubWF0cml4KHJlYWQuZGVsaW0oJ2NvdW50X21hdHJpeF9hdWc0X25vY3RybF9jZWxuYW1lcy50eHQnLApoZWFkZXIgPSBULHN0cmluZ3NBc0ZhY3RvcnMgPSBGLHNlcCA9ICJcdCIscm93Lm5hbWVzID0gMSxjaGVjay5uYW1lcyA9IEYsYXMuaXM9VFJVRSkpCgpwZXJpY2EgPSByZWFkLmRlbGltKCJqdW4xMF8yMDE2X3BmaW5hbF9lcmljYS50eHQiLGhlYWRlciA9IFQsc3RyaW5nc0FzRmFjdG9ycz1GLCBjaGVjay5uYW1lcyA9IEYpCgp3PSB3aGljaChwZXJpY2EkY2VsZmlsZSAlaW4lIGNvbG5hbWVzKHhvYmFyKSkKCnBiYXIgPSBwZXJpY2FbdyxdCgp4b2JhciA9IHhvYmFyW3doaWNoKHJvd25hbWVzKHhvYmFyKSAlaW4lIG5vbmVzcyRzdHJhaW4pLHBiYXIkY2VsZmlsZV0KCmNvbG5hbWVzKHhvYmFyKT1wYmFyJG5hbWUKCiNwamVuID0gZGF0YS5mcmFtZShuYW1lPSBjb2xuYW1lcyh4b2JhcilbZ3JlcCgnSmVuJyxjb2xuYW1lcyh4b2JhcikpXSkKCnBoeWJhciA9IHBiYXIgJT4lIGZpbHRlcihwb29sID09ICdob20nLG1lZGlhID09ICd5cGQnKQpwb3liYXIgPSBwYmFyICU+JSBmaWx0ZXIocG9vbCA9PSAnb2xpdmVyJyxtZWRpYSA9PSAneXBkJykKcGh5YmFyID0gcGh5YmFyICU+JSBhcnJhbmdlKHR5cGUsY29uZCxwY3IpCnBveWJhciA9IHBveWJhciAlPiUgYXJyYW5nZSh0eXBlLGNvbmQscGNyKQoKd295YmFyID0gd2hpY2gocG95YmFyJHR5cGUgPT0gJ2N0cmwnKQp3aHliYXIgPSB3aGljaChwaHliYXIkdHlwZSA9PSAnY3RybCcpCmBgYAoKZmlsdGVyIGFzIGFib3ZlIGZvciBsb3cgY291bnRzCmBgYHtyIHNhbWUgZGVhbCB5cGQgZGF0YSwgZXZhbCA9IFQsIGluY2x1ZGUgPSBGfQpveWJhciA9IG15YWxsX2xlc3M1MCh4b2JhclsscG95YmFyJG5hbWVdKQpoeWJhciA9IG15YWxsX2xlc3M1MCh4b2JhclsscGh5YmFyJG5hbWVdKQoKcHJpbnQoJ2RpbSBhZnRlciBmaWx0ZXJpbmcgYWxsIGNudHMgbGVzcyA1MCcpCnByaW50KGRpbShoeWJhcikpCnByaW50KGRpbShveWJhcikpCmh5YmFyID0gbXltaW41MChoeWJhcix3aHliYXIpCm95YmFyID0gbXltaW41MChveWJhcix3b3liYXIpCnByaW50KCdkaW0gYWZ0ZXIgZmlsdGVyaW5nIGNudHMgbGVzcyA1MCBvbmx5IGluIGNvbnRybCcpCnByaW50KGRpbShoeWJhcikpCnByaW50KGRpbShveWJhcikpCmBgYAoKZGRzIGFuZCBlZGdlIGV2YWx1YXRpb24gZm9yIHlwZCAtLSBjaGVjayBvdXQgdGhlIEZFQjE3IDAwODMgb3V0bGllciBmb3IgaG9tIHlwZApgYGB7ciBub3JtYWwgY250cywgZXZhbCA9IFQsIGluY2x1ZGUgPSBUfQoKaHlkZHMgPSBteWRkcyhoeWJhcixwaHliYXIkY29uZCkKb3lkZHMgPSBteWRkcyhveWJhcixwb3liYXIkY29uZCkKaHllZGdlID0gbXllZGdlUihoeWJhcixwaHliYXIkY29uZCxyZWYgPSAneXBkJykKb3llZGdlID0gbXllZGdlUihveWJhcixwb3liYXIkY29uZCxyZWYgPSAneXBkJykKCmBgYAoKYGBge3IsIGV2YWwgPSBULCBpbmNsdWRlID0gVH0KaHlkID0gbXlwcm9jX25vcm1jb3VudHMoaHlkZHMscGh5YmFyJGNvbmQpCm95ZCA9IG15cHJvY19ub3JtY291bnRzKG95ZGRzLHBveWJhciRjb25kKQoKaHlqID0gbXlwcm9jX25vcm1jb3VudHMoaHllZGdlLHBoeWJhciRjb25kKQpveWogPSBteXByb2Nfbm9ybWNvdW50cyhveWVkZ2UscG95YmFyJGNvbmQpCgpgYGAKCgp5cGQgYXJyYXkgZGF0YWcKYGBge3IgZ2V0IFlQRCBvbGl2ZXIgYW5kIGhvbSBjaGlwIGRhdGF9Cgp4b2NoaXA9IGFzLm1hdHJpeChyZWFkLmRlbGltKAoieG9jaGlwLnR4dCIsaGVhZGVyID0gVCxzdHJpbmdzQXNGYWN0b3JzID0gRixjaGVjay5uYW1lcyA9IEYpKQoKb21peCA9IHhvY2hpcFsscG95YmFyJG5hbWVdCm9taXggPSBteW1peEVNY3RybChvbWl4LHdveWJhcikKb21peCA9IG1lZFNoaWZ0LnVwZG4ob21peCkKb21pbiA9IG1pbihhcHBseShvbWl4Wyx3b3liYXJdLDEsbWVkaWFuKSkKCmhtaXggPSB4b2NoaXBbLHBoeWJhciRuYW1lXQpobWl4ID0gbXltaXhFTWN0cmwoaG1peCx3aHliYXIpCmhtaW4gPSBtaW4oYXBwbHkoaG1peFssd2h5YmFyXSwxLG1lZGlhbikpCgpib21peCA9IG15QmVzdHRhZyhvbWl4LGJnVGhyZXNoPW9taW4pCgpiaG1peCA9IG15QmVzdHRhZyhobWl4LGJnVGhyZXNoPWhtaW4pCgojYmVmb3JlIGJhdGNoIGNvcnJlY3Rpb24KbXlkZW5keShiaG1peCxwaHliYXIkcGNyKQoKYmh5YmF0ID0gQ29tQmF0KGJobWl4LG1vZD1tb2RlbC5tYXRyaXgofmNvbmQscGh5YmFyKSxiYXRjaD1waHliYXIkcGNyKQojYWZ0ZXIgYmF0Y2ggY29ycmVjdGlvbgpteWRlbmR5KGJoeWJhdCxwaHliYXIkY29uZCkKCiNvbGl2ZXIgYmVmb3JlIGJhdGNoIGNvcnJlY3Rpb24KbXlkZW5keShib21peCxwb3liYXIkY29uZCkKYm95YmF0ID0gQ29tQmF0KGJvbWl4LG1vZD1tb2RlbC5tYXRyaXgofmNvbmQscG95YmFyKSxiYXRjaD1wb3liYXIkcGNyKQoKI29saXZlciBhZnRlciBiYXRjaCBjb3JyZWN0aW9uCm15ZGVuZHkoYm95YmF0LHBveWJhciRjb25kKQoKaHlzdz0gbXlzd2VlcChiaHliYXQpCmxwaHliYXIgPSBwaHliYXJbLXdoeWJhcixdCiNzdW1tYXJpemUgY2hpcCBkYXRhCmh5c3VtID0gbXlzdW1tKGh5c3dbLGxwaHliYXIkbmFtZV0sbHBoeWJhciRjb25kKQoKb3lzdz0gbXlzd2VlcChib3liYXQpCmxwb3liYXIgPSBwb3liYXJbLXdveWJhcixdCm95c3VtID0gbXlzdW1tKG95c3dbLGxwb3liYXIkbmFtZV0sbHBveWJhciRjb25kKQoKYGBgCgoKbm9ybWFsaXplIFlQRCBkYXRhIGJ5IGNvdW50CmBgYHtyIG5vcm0gYnkgY250cyBZUER9Cm5vUmh5ID0gbXliYXJub3JtKGh5YmFyKQoKbm9SaHkzID0gbXlwcm9jX25vcm1jb3VudHMobm9SaHkscGh5YmFyJGNvbmQpCgpub1JoeTMgPSBub1JoeTNbLGNvbG5hbWVzKGh5c3VtKV0KCm5vUm95ID0gbXliYXJub3JtKG95YmFyKQoKbm9Sb3kzID0gbXlwcm9jX25vcm1jb3VudHMobm9Sb3kscG95YmFyJGNvbmQpCgpub1JveTMgPSBub1JveTNbLGNvbG5hbWVzKG95c3VtKSxkcm9wPUZdCmBgYAoKcGxvdCBZUEQgcmVzdWx0cwpgYGB7ciwgZmlnLndpZHRoPTEyLGZpZy5oZWlnaHQ9NixlY2hvID0gRn0Kb3lzdW0gPSBveXN1bVtvcmRlcihyb3duYW1lcyhveXN1bSkpLCxkcm9wPUZdCmh5c3VtID0gaHlzdW1bb3JkZXIocm93bmFtZXMoaHlzdW0pKSwsZHJvcD1GXQpoeWo9aHlqWyxjb2xuYW1lcyhoeXN1bSldCgpoeWQ9aHlkWyxjb2xuYW1lcyhoeXN1bSldCgpjb2xuYW1lcyhoeXN1bSk9cGFzdGUwKCdjaGlwLicsY29sbmFtZXMoaHlzdW0pKQpjb2xuYW1lcyhoeWopPXBhc3RlMCgnZWRnZS4nLGNvbG5hbWVzKGh5aikpCmNvbG5hbWVzKGh5ZCk9cGFzdGUwKCdkZXNlcTIuJyxjb2xuYW1lcyhoeWQpKQpjb2xuYW1lcyhub1JoeTMpPXBhc3RlMCgnbm9ScGtnLicsY29sbmFtZXMobm9SaHkzKSkKCmNvbG5hbWVzKG95c3VtKT1wYXN0ZTAoJ2NoaXAuJyxjb2xuYW1lcyhveXN1bSkpCmNvbG5hbWVzKG95aik9cGFzdGUwKCdlZGdlLicsY29sbmFtZXMob3lqKSkKY29sbmFtZXMob3lkKT1wYXN0ZTAoJ2Rlc2VxMi4nLGNvbG5hbWVzKG95ZCkpCmNvbG5hbWVzKG5vUm95Myk9cGFzdGUwKCdub1Jwa2cuJyxjb2xuYW1lcyhub1JveTMpKQoKYGBgCgpob20gWVBECmBgYHtyLCBmaWcud2lkdGg9MTIsZmlnLmhlaWdodD02fQoKb3BhciA8LSBwYXIocGNoPTE5LG1mcm93PWMoMSwyKSxtYXI9YygyLjIsMiwxLjQsMSksY2V4PTEuMikKZm9yIChpIGluIDE6bmNvbChoeXN1bSkpIHsgCiAgCiAgcDEoaHlzdW0saSkKICBwMShub1JoeTMsaSkKICBwMShoeWosaSkKICBwMShoeWQsaSkKICAKfQoKYGBgCgpvbGl2ZXIgWVBECmBgYHtyIG9saXZlciwgZmlnLndpZHRoPTEyLGZpZy5oZWlnaHQ9Nn0KCm9wYXIgPC0gcGFyKHBjaD0xOSxtZnJvdz1jKDEsMiksbWFyPWMoMi4yLDIsMS40LDEpLGNleD0xLjIpCmZvciAoaSBpbiAxOm5jb2wob3lzdW0pKSB7IAogIAogIHAxKG95c3VtLGkpCiAgcDEobm9Sb3kzLGksc2lnID0wLjcpCiAgcDEob3lqLGksc2lnID0wLjcpCiAgcDEob3lkLGksc2lnID0wLjcpCiAgCn0KYGBgCgpjb21wYXJlIHRvIGNvbWJpbmluZyBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMgd2l0aCBzdGFuZGFyZCBlZGdlOgoKMS4gdXAgYW5kIGRvd250YWdzIHNlcGFyYXRlbHksIGNvbGxhcHNlZCBieSBzdW1tYXRpb24gYWZ0ZXIgZGlzcGVyc2lvbiBlc3RpbWF0ZXMKYGBge3Igc3RhbmRhcmQgZWRnZX0KCmhzX3N0ZF9lZGdlID0gbXlkZmVkZ2UoaHNiYXIscDExJGNvbmQscmVmPSAnc2MnKQptaHNfc3RkID0gYXMubWF0cml4KGhzX3N0ZF9lZGdlWywxOjVdKQpyb3duYW1lcyhtaHNfc3RkKSA9IGhzX3N0ZF9lZGdlJHN0cmFpbgoKaHNfc3VtdGFncyA9IG15c3VtdGFncyhteWJhcm5vcm0oaHNiYXIpKQpoc19zdGRfc3VtdGFncyA9IG15ZGZlZGdlKGhzX3N1bXRhZ3MscDExJGNvbmQscmVmPSAnc2MnKQptaHNfc3RkX3N1bXRhZ3MgPSBhcy5tYXRyaXgoaHNfc3RkX3N1bXRhZ3NbLDE6NV0pCnJvd25hbWVzKG1oc19zdGRfc3VtdGFncykgPSBoc19zdGRfc3VtdGFncyRzdHJhaW4KbWhzX3N0ZF9zdW10YWdzPSBtaHNfc3RkX3N1bXRhZ3Nbb3JkZXIocm93bmFtZXMobWhzX3N0ZF9zdW10YWdzKSksXQoKCgpoeV9zdGRfZWRnZSA9IG15ZGZlZGdlKGh5YmFyLHBoeWJhciRjb25kLHJlZj0gJ3lwZCcpCm1oeV9zdGQgPSBhcy5tYXRyaXgoaHlfc3RkX2VkZ2VbLDE6NF0pCnJvd25hbWVzKG1oeV9zdGQpID0gaHlfc3RkX2VkZ2Ukc3RyYWluCgoKaHlfc3VtdGFncyA9IG15c3VtdGFncyhteWJhcm5vcm0oaHliYXIpKQoKaHlfc3RkX3N1bXRhZ3MgPSBteWRmZWRnZShoeV9zdW10YWdzLHBoeWJhciRjb25kLHJlZj0gJ3lwZCcpCm1oeV9zdGRfc3VtdGFncyA9IGFzLm1hdHJpeChoeV9zdGRfc3VtdGFnc1ssMTo0XSkKcm93bmFtZXMobWh5X3N0ZF9zdW10YWdzKSA9IGh5X3N0ZF9zdW10YWdzJHN0cmFpbgptaHlfc3RkX3N1bXRhZ3M9IG1oeV9zdGRfc3VtdGFnc1tvcmRlcihyb3duYW1lcyhtaHlfc3RkX3N1bXRhZ3MpKSxdCgpgYGAKCjIuIG5vcm1hbGl6ZSB1cCBhbmQgZG93bnRhZ3Mgc2VwYXJhdGVseSBiZWZvcmUgY29tYmluaW5nLCBwcmVkaXNwZXJzaW9uCgpwbG90IHN0YW5kYXJkIGVkZ2UsIHByZS1zdW1tZWQgdXAgYW5kIGRvd250YWdzCgpgYGB7ciBzdGQgZWRnZSwgZmlnLndpZHRoPTEyLGZpZy5oZWlnaHQ9Nn0Kb3BhciA8LSBwYXIocGNoPTE5LG1mcm93PWMoMSwyKSxtYXI9YygyLjIsMiwxLjQsMSksY2V4PTEuMikKZm9yIChpIGluIDE6MykKcHNpZygtbWhzX3N0ZF9zdW10YWdzLGhlZGdlMixpKQoKZm9yIChpIGluIDE6MikKcHNpZygtbWh5X3N0ZF9zdW10YWdzLGh5aixpKQoKYGBgCgoK