1 Kallisto Alignment

1.1 Getting sequencing reads

cd ../data 
wget --recursive --no-parent --no-directories \
--accept '*001.fastq.gz' \
https://gannet.fish.washington.edu/seashell/bu-github/nb-2023/Cgigas/data/nopp/
cd ../data 
/home/shared/FastQC/fastqc *fastq.gz -o ../output
eval "$(/opt/anaconda/anaconda3/bin/conda shell.bash hook)"
conda activate
which multiqc

cd ../output

multiqc .

1.2 Obtain the reference

cd ../data
curl -O https://gannet.fish.washington.edu/seashell/bu-github/nb-2023/Cgigas/data/rna.fna

1.3 Index Reference

#!/bin/bash

# run kallisto to index the transcriptome
/home/shared/kallisto/kallisto \

# index the transcriptome
index -i \

# specify the output file name
../data/cgigas_roslin_rna.index \

# specify the input file name
../data/rna.fna

1.4 Align reads

mkdir ../output/kallisto_01

find ../data/*_L001_R1_001.fastq.gz \
| xargs basename -s _L001_R1_001.fastq.gz | xargs -I{} /home/shared/kallisto/kallisto \
quant -i ../data/cgigas_roslin_rna.index \
-o ../output/kallisto_01/{} \
-t 40 \
--single -l 100 -s 10 ../data/{}_L001_R1_001.fastq.gz

1.5 Merge quant data

perl /home/shared/trinityrnaseq-v2.12.0/util/abundance_estimates_to_matrix.pl \
--est_method kallisto \
    --gene_trans_map none \
    --out_prefix ../output/kallisto_01 \
    --name_sample_by_basedir \
    ../output/kallisto_01/D54_S145/abundance.tsv \
    ../output/kallisto_01/D56_S136/abundance.tsv \
    ../output/kallisto_01/D58_S144/abundance.tsv \
    ../output/kallisto_01/M45_S140/abundance.tsv \
    ../output/kallisto_01/M48_S137/abundance.tsv \
    ../output/kallisto_01/M89_S138/abundance.tsv \
    ../output/kallisto_01/D55_S146/abundance.tsv \
    ../output/kallisto_01/D57_S143/abundance.tsv \
    ../output/kallisto_01/D59_S142/abundance.tsv \
    ../output/kallisto_01/M46_S141/abundance.tsv \
    ../output/kallisto_01/M49_S139/abundance.tsv \
    ../output/kallisto_01/M90_S147/abundance.tsv \
    ../output/kallisto_01/N48_S194/abundance.tsv \
    ../output/kallisto_01/N50_S187/abundance.tsv \
    ../output/kallisto_01/N52_S184/abundance.tsv \
    ../output/kallisto_01/N54_S193/abundance.tsv \
    ../output/kallisto_01/N56_S192/abundance.tsv \
    ../output/kallisto_01/N58_S195/abundance.tsv \
    ../output/kallisto_01/N49_S185/abundance.tsv \
    ../output/kallisto_01/N51_S186/abundance.tsv \
    ../output/kallisto_01/N53_S188/abundance.tsv \
    ../output/kallisto_01/N55_S190/abundance.tsv \
    ../output/kallisto_01/N57_S191/abundance.tsv \
    ../output/kallisto_01/N59_S189/abundance.tsv

2 DESeq2

countmatrix <- read.delim("../output/kallisto_01.isoform.counts.matrix", header = TRUE, sep = '\t')
rownames(countmatrix) <- countmatrix$X
countmatrix <- countmatrix[,-1]
head(countmatrix)
countmatrix <- round(countmatrix, 0)
str(countmatrix)
dim(countmatrix)
dim(deseq2.colData)
length(colnames(data))
deseq2.colData <- data.frame(condition=factor(c(rep("control", 12), rep("desicated", 12))), 
                             type=factor(rep("single-read", 24)))
rownames(deseq2.colData) <- colnames(countmatrix)
deseq2.dds <- DESeqDataSetFromMatrix(countData = countmatrix,
                                     colData = deseq2.colData, 
                                     design = ~ condition)
deseq2.dds <- DESeq(deseq2.dds)
deseq2.res <- results(deseq2.dds)
deseq2.res <- deseq2.res[order(rownames(deseq2.res)), ]
vsd <- vst(deseq2.dds, blind = FALSE)
plotPCA(vsd, intgroup = "condition")
# Select top 50 differentially expressed genes
res <- results(deseq2.dds)
res_ordered <- res[order(res$padj), ]
top_genes <- row.names(res_ordered)[1:50]

# Extract counts and normalize
counts <- counts(deseq2.dds, normalized = TRUE)
counts_top <- counts[top_genes, ]

# Log-transform counts
log_counts_top <- log2(counts_top + 1)

# Generate heatmap
pheatmap(log_counts_top, scale = "row")
head(deseq2.res)
# Count number of hits with adjusted p-value less then 0.05
dim(deseq2.res[!is.na(deseq2.res$padj) & deseq2.res$padj <= 0.05, ])
tmp <- deseq2.res
# The main plot
plot(tmp$baseMean, tmp$log2FoldChange, pch=20, cex=0.45, ylim=c(-3, 3), log="x", col="darkgray",
     main="DEG Dessication  (pval <= 0.05)",
     xlab="mean of normalized counts",
     ylab="Log2 Fold Change")
# Getting the significant points and plotting them again so they're a different color
tmp.sig <- deseq2.res[!is.na(deseq2.res$padj) & deseq2.res$padj <= 0.05, ]
points(tmp.sig$baseMean, tmp.sig$log2FoldChange, pch=20, cex=0.45, col="red")
# 2 FC lines
abline(h=c(-1,1), col="blue")
# Prepare the data for plotting
res_df <- as.data.frame(deseq2.res)
res_df$gene <- row.names(res_df)

# Create volcano plot
volcano_plot <- ggplot(res_df, aes(x = log2FoldChange, y = -log10(padj), color = padj < 0.05)) +
  geom_point(alpha = 0.6, size = 1.5) +
  scale_color_manual(values = c("grey", "red")) +
  labs(title = "Volcano Plot",
       x = "Log2 Fold Change",
       y = "-Log10 Adjusted P-value",
       color = "Significantly\nDifferentially Expressed") +
  theme_minimal() +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        legend.position = "top")

print(volcano_plot)
write.table(tmp.sig, "../output/DEGlist.tab", sep = '\t', row.names = T)
deglist <- read.csv("../output/DEGlist.tab", sep = '\t', header = TRUE)
deglist$RowName <- rownames(deglist)
deglist2 <- deglist[, c("RowName", "pvalue")] # Optionally, reorder the columns
datatable(deglist)

3 Annotation?

cg_sp <- read.csv("https://raw.githubusercontent.com/sr320/nb-2022/main/C_gigas/analyses/CgR-blastp-sp.tab", header = FALSE, sep="\t")  %>%
  distinct(V1, .keep_all = TRUE)
loc <- read.csv("https://raw.githubusercontent.com/sr320/nb-2022/main/C_gigas/analyses/LOC_Acc.tab", sep = " ", header = FALSE)
comb <- left_join(loc, cg_sp, by = c("V2" = "V1")) %>%
  left_join(deglist, by = c("V1" = "RowName"))

4 Gene Enrichment Analysis

gene_deg_status <- res_df %>%
  mutate(degstaus = ifelse(padj < 0.05, 1, 0)) 
# Read the FASTA file
fasta_data <- readDNAStringSet("../data/rna.fna")

# Calculate gene lengths
gene_lengths <- width(fasta_data)


# Extract gene names/IDs from sequence IDs
gene_names <- sapply(names(fasta_data), function(x) strsplit(x, " ")[[1]][1])

# Create a data frame with gene IDs and lengths
gene_lengths_df <- data.frame(geneID = gene_names, length = gene_lengths)

4.1 Need GO Mappings

pwf <- nullp(gene_data, bias.data = gene_lengths)

GO_analysis <- goseq(pwf, gene2cat = "your_organism_GO_mapping")
LS0tCnRpdGxlOiAiUk5BLXNlcSIKYXV0aG9yOiBTdGV2ZW4gUm9iZXJ0cwpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiICAKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IHJlYWRhYmxlCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4KICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoREVTZXEyKQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KERUKQpsaWJyYXJ5KEJpb3N0cmluZ3MpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0gVFJVRSwgICAgICAgICAjIERpc3BsYXkgY29kZSBjaHVua3MKICBldmFsID0gRkFMU0UsICAgICAgICAgIyBFdmFsdWF0ZSBjb2RlIGNodW5rcwogIHdhcm5pbmcgPSBGQUxTRSwgICAgICMgSGlkZSB3YXJuaW5ncwogIG1lc3NhZ2UgPSBGQUxTRSwgICAgICMgSGlkZSBtZXNzYWdlcwogIGZpZy53aWR0aCA9IDYsICAgICAgICMgU2V0IHBsb3Qgd2lkdGggaW4gaW5jaGVzCiAgZmlnLmhlaWdodCA9IDQsICAgICAgIyBTZXQgcGxvdCBoZWlnaHQgaW4gaW5jaGVzCiAgZmlnLmFsaWduID0gImNlbnRlciIgIyBBbGlnbiBwbG90cyB0byB0aGUgY2VudGVyCikKYGBgCiMgS2FsbGlzdG8gQWxpZ25tZW50CiMjIEdldHRpbmcgc2VxdWVuY2luZyByZWFkcwoKYGBge3IgcHVsbCwgZW5naW5lPSdiYXNoJ30KY2QgLi4vZGF0YSAKd2dldCAtLXJlY3Vyc2l2ZSAtLW5vLXBhcmVudCAtLW5vLWRpcmVjdG9yaWVzIFwKLS1hY2NlcHQgJyowMDEuZmFzdHEuZ3onIFwKaHR0cHM6Ly9nYW5uZXQuZmlzaC53YXNoaW5ndG9uLmVkdS9zZWFzaGVsbC9idS1naXRodWIvbmItMjAyMy9DZ2lnYXMvZGF0YS9ub3BwLwpgYGAKYGBge3IgZmFzdHFjLCBlbmdpbmU9J2Jhc2gnfQpjZCAuLi9kYXRhIAovaG9tZS9zaGFyZWQvRmFzdFFDL2Zhc3RxYyAqZmFzdHEuZ3ogLW8gLi4vb3V0cHV0CmBgYAoKYGBge2Jhc2h9CmV2YWwgIiQoL29wdC9hbmFjb25kYS9hbmFjb25kYTMvYmluL2NvbmRhIHNoZWxsLmJhc2ggaG9vaykiCmNvbmRhIGFjdGl2YXRlCndoaWNoIG11bHRpcWMKCmNkIC4uL291dHB1dAoKbXVsdGlxYyAuCmBgYAojIyBPYnRhaW4gdGhlIHJlZmVyZW5jZQpgYGB7ciBwdWxscmVmLCBlbmdpbmU9J2Jhc2gnfQpjZCAuLi9kYXRhCmN1cmwgLU8gaHR0cHM6Ly9nYW5uZXQuZmlzaC53YXNoaW5ndG9uLmVkdS9zZWFzaGVsbC9idS1naXRodWIvbmItMjAyMy9DZ2lnYXMvZGF0YS9ybmEuZm5hCmBgYAojIyBJbmRleCBSZWZlcmVuY2UKYGBge3Iga2FsbGlzdG8sIGVuZ2luZT0nYmFzaCd9CiMhL2Jpbi9iYXNoCgojIHJ1biBrYWxsaXN0byB0byBpbmRleCB0aGUgdHJhbnNjcmlwdG9tZQovaG9tZS9zaGFyZWQva2FsbGlzdG8va2FsbGlzdG8gXAoKIyBpbmRleCB0aGUgdHJhbnNjcmlwdG9tZQppbmRleCAtaSBcCgojIHNwZWNpZnkgdGhlIG91dHB1dCBmaWxlIG5hbWUKLi4vZGF0YS9jZ2lnYXNfcm9zbGluX3JuYS5pbmRleCBcCgojIHNwZWNpZnkgdGhlIGlucHV0IGZpbGUgbmFtZQouLi9kYXRhL3JuYS5mbmEKCmBgYAojIyBBbGlnbiByZWFkcwpgYGB7ciBrYWxsaXN0by1hbGlnbiwgZW5naW5lPSdiYXNoJ30KbWtkaXIgLi4vb3V0cHV0L2thbGxpc3RvXzAxCgpmaW5kIC4uL2RhdGEvKl9MMDAxX1IxXzAwMS5mYXN0cS5neiBcCnwgeGFyZ3MgYmFzZW5hbWUgLXMgX0wwMDFfUjFfMDAxLmZhc3RxLmd6IHwgeGFyZ3MgLUl7fSAvaG9tZS9zaGFyZWQva2FsbGlzdG8va2FsbGlzdG8gXApxdWFudCAtaSAuLi9kYXRhL2NnaWdhc19yb3NsaW5fcm5hLmluZGV4IFwKLW8gLi4vb3V0cHV0L2thbGxpc3RvXzAxL3t9IFwKLXQgNDAgXAotLXNpbmdsZSAtbCAxMDAgLXMgMTAgLi4vZGF0YS97fV9MMDAxX1IxXzAwMS5mYXN0cS5negpgYGAKIyMgTWVyZ2UgcXVhbnQgZGF0YQpgYGB7ciBtYXRyaXgsIGVuZ2luZT0nYmFzaCd9CnBlcmwgL2hvbWUvc2hhcmVkL3RyaW5pdHlybmFzZXEtdjIuMTIuMC91dGlsL2FidW5kYW5jZV9lc3RpbWF0ZXNfdG9fbWF0cml4LnBsIFwKLS1lc3RfbWV0aG9kIGthbGxpc3RvIFwKICAgIC0tZ2VuZV90cmFuc19tYXAgbm9uZSBcCiAgICAtLW91dF9wcmVmaXggLi4vb3V0cHV0L2thbGxpc3RvXzAxIFwKICAgIC0tbmFtZV9zYW1wbGVfYnlfYmFzZWRpciBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvRDU0X1MxNDUvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvRDU2X1MxMzYvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvRDU4X1MxNDQvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTTQ1X1MxNDAvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTTQ4X1MxMzcvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTTg5X1MxMzgvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvRDU1X1MxNDYvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvRDU3X1MxNDMvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvRDU5X1MxNDIvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTTQ2X1MxNDEvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTTQ5X1MxMzkvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTTkwX1MxNDcvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjQ4X1MxOTQvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjUwX1MxODcvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjUyX1MxODQvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjU0X1MxOTMvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjU2X1MxOTIvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjU4X1MxOTUvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjQ5X1MxODUvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjUxX1MxODYvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjUzX1MxODgvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjU1X1MxOTAvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjU3X1MxOTEvYWJ1bmRhbmNlLnRzdiBcCiAgICAuLi9vdXRwdXQva2FsbGlzdG9fMDEvTjU5X1MxODkvYWJ1bmRhbmNlLnRzdgpgYGAKIyBERVNlcTIKYGBge3IsIGV2YWw9RkFMU0V9CmNvdW50bWF0cml4IDwtIHJlYWQuZGVsaW0oIi4uL291dHB1dC9rYWxsaXN0b18wMS5pc29mb3JtLmNvdW50cy5tYXRyaXgiLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAnXHQnKQpyb3duYW1lcyhjb3VudG1hdHJpeCkgPC0gY291bnRtYXRyaXgkWApjb3VudG1hdHJpeCA8LSBjb3VudG1hdHJpeFssLTFdCmhlYWQoY291bnRtYXRyaXgpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KY291bnRtYXRyaXggPC0gcm91bmQoY291bnRtYXRyaXgsIDApCnN0cihjb3VudG1hdHJpeCkKYGBgCgoKYGBge3IsZXZhbD1GQUxTRX0KZGltKGNvdW50bWF0cml4KQpkaW0oZGVzZXEyLmNvbERhdGEpCmBgYApgYGB7cixldmFsPUZBTFNFfQpsZW5ndGgoY29sbmFtZXMoZGF0YSkpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CmRlc2VxMi5jb2xEYXRhIDwtIGRhdGEuZnJhbWUoY29uZGl0aW9uPWZhY3RvcihjKHJlcCgiY29udHJvbCIsIDEyKSwgcmVwKCJkZXNpY2F0ZWQiLCAxMikpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1mYWN0b3IocmVwKCJzaW5nbGUtcmVhZCIsIDI0KSkpCnJvd25hbWVzKGRlc2VxMi5jb2xEYXRhKSA8LSBjb2xuYW1lcyhjb3VudG1hdHJpeCkKZGVzZXEyLmRkcyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50RGF0YSA9IGNvdW50bWF0cml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YSA9IGRlc2VxMi5jb2xEYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2lnbiA9IH4gY29uZGl0aW9uKQpgYGAKYGBge3IsIGV2YWw9RkFMU0UsIGNhY2hlPUZBTFNFfQpkZXNlcTIuZGRzIDwtIERFU2VxKGRlc2VxMi5kZHMpCmRlc2VxMi5yZXMgPC0gcmVzdWx0cyhkZXNlcTIuZGRzKQpkZXNlcTIucmVzIDwtIGRlc2VxMi5yZXNbb3JkZXIocm93bmFtZXMoZGVzZXEyLnJlcykpLCBdCmBgYApgYGB7ciBQQ0EsIGV2YWw9RkFMU0V9CnZzZCA8LSB2c3QoZGVzZXEyLmRkcywgYmxpbmQgPSBGQUxTRSkKcGxvdFBDQSh2c2QsIGludGdyb3VwID0gImNvbmRpdGlvbiIpCmBgYAoKYGBge3IgaGVhdG1hcCwgZXZhbD1GQUxTRX0KIyBTZWxlY3QgdG9wIDUwIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcwpyZXMgPC0gcmVzdWx0cyhkZXNlcTIuZGRzKQpyZXNfb3JkZXJlZCA8LSByZXNbb3JkZXIocmVzJHBhZGopLCBdCnRvcF9nZW5lcyA8LSByb3cubmFtZXMocmVzX29yZGVyZWQpWzE6NTBdCgojIEV4dHJhY3QgY291bnRzIGFuZCBub3JtYWxpemUKY291bnRzIDwtIGNvdW50cyhkZXNlcTIuZGRzLCBub3JtYWxpemVkID0gVFJVRSkKY291bnRzX3RvcCA8LSBjb3VudHNbdG9wX2dlbmVzLCBdCgojIExvZy10cmFuc2Zvcm0gY291bnRzCmxvZ19jb3VudHNfdG9wIDwtIGxvZzIoY291bnRzX3RvcCArIDEpCgojIEdlbmVyYXRlIGhlYXRtYXAKcGhlYXRtYXAobG9nX2NvdW50c190b3AsIHNjYWxlID0gInJvdyIpCmBgYCAKYGBge3IsIGV2YWw9RkFMU0V9CmhlYWQoZGVzZXEyLnJlcykKYGBgCgoKCmBgYHtyLCBldmFsPUZBTFNFfQojIENvdW50IG51bWJlciBvZiBoaXRzIHdpdGggYWRqdXN0ZWQgcC12YWx1ZSBsZXNzIHRoZW4gMC4wNQpkaW0oZGVzZXEyLnJlc1shaXMubmEoZGVzZXEyLnJlcyRwYWRqKSAmIGRlc2VxMi5yZXMkcGFkaiA8PSAwLjA1LCBdKQpgYGAKYGBge3IsIGV2YWw9RkFMU0V9CnRtcCA8LSBkZXNlcTIucmVzCiMgVGhlIG1haW4gcGxvdApwbG90KHRtcCRiYXNlTWVhbiwgdG1wJGxvZzJGb2xkQ2hhbmdlLCBwY2g9MjAsIGNleD0wLjQ1LCB5bGltPWMoLTMsIDMpLCBsb2c9IngiLCBjb2w9ImRhcmtncmF5IiwKICAgICBtYWluPSJERUcgRGVzc2ljYXRpb24gIChwdmFsIDw9IDAuMDUpIiwKICAgICB4bGFiPSJtZWFuIG9mIG5vcm1hbGl6ZWQgY291bnRzIiwKICAgICB5bGFiPSJMb2cyIEZvbGQgQ2hhbmdlIikKIyBHZXR0aW5nIHRoZSBzaWduaWZpY2FudCBwb2ludHMgYW5kIHBsb3R0aW5nIHRoZW0gYWdhaW4gc28gdGhleSdyZSBhIGRpZmZlcmVudCBjb2xvcgp0bXAuc2lnIDwtIGRlc2VxMi5yZXNbIWlzLm5hKGRlc2VxMi5yZXMkcGFkaikgJiBkZXNlcTIucmVzJHBhZGogPD0gMC4wNSwgXQpwb2ludHModG1wLnNpZyRiYXNlTWVhbiwgdG1wLnNpZyRsb2cyRm9sZENoYW5nZSwgcGNoPTIwLCBjZXg9MC40NSwgY29sPSJyZWQiKQojIDIgRkMgbGluZXMKYWJsaW5lKGg9YygtMSwxKSwgY29sPSJibHVlIikKYGBgCmBgYHtyIG5ld3Bsb3QsIGV2YWw9RkFMU0V9CiMgUHJlcGFyZSB0aGUgZGF0YSBmb3IgcGxvdHRpbmcKcmVzX2RmIDwtIGFzLmRhdGEuZnJhbWUoZGVzZXEyLnJlcykKcmVzX2RmJGdlbmUgPC0gcm93Lm5hbWVzKHJlc19kZikKCiMgQ3JlYXRlIHZvbGNhbm8gcGxvdAp2b2xjYW5vX3Bsb3QgPC0gZ2dwbG90KHJlc19kZiwgYWVzKHggPSBsb2cyRm9sZENoYW5nZSwgeSA9IC1sb2cxMChwYWRqKSwgY29sb3IgPSBwYWRqIDwgMC4wNSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBzaXplID0gMS41KSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImdyZXkiLCAicmVkIikpICsKICBsYWJzKHRpdGxlID0gIlZvbGNhbm8gUGxvdCIsCiAgICAgICB4ID0gIkxvZzIgRm9sZCBDaGFuZ2UiLAogICAgICAgeSA9ICItTG9nMTAgQWRqdXN0ZWQgUC12YWx1ZSIsCiAgICAgICBjb2xvciA9ICJTaWduaWZpY2FudGx5XG5EaWZmZXJlbnRpYWxseSBFeHByZXNzZWQiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIpCgpwcmludCh2b2xjYW5vX3Bsb3QpCmBgYApgYGB7ciwgZXZhbD1GQUxTRX0Kd3JpdGUudGFibGUodG1wLnNpZywgIi4uL291dHB1dC9ERUdsaXN0LnRhYiIsIHNlcCA9ICdcdCcsIHJvdy5uYW1lcyA9IFQpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CmRlZ2xpc3QgPC0gcmVhZC5jc3YoIi4uL291dHB1dC9ERUdsaXN0LnRhYiIsIHNlcCA9ICdcdCcsIGhlYWRlciA9IFRSVUUpCmRlZ2xpc3QkUm93TmFtZSA8LSByb3duYW1lcyhkZWdsaXN0KQpkZWdsaXN0MiA8LSBkZWdsaXN0WywgYygiUm93TmFtZSIsICJwdmFsdWUiKV0gIyBPcHRpb25hbGx5LCByZW9yZGVyIHRoZSBjb2x1bW5zCmBgYAoKCmBgYHtyLCBldmFsPUZBTFNFfQpkYXRhdGFibGUoZGVnbGlzdCkKYGBgCiMgQW5ub3RhdGlvbj8KYGBge3IsIGV2YWw9RkFMU0V9CmNnX3NwIDwtIHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vc3IzMjAvbmItMjAyMi9tYWluL0NfZ2lnYXMvYW5hbHlzZXMvQ2dSLWJsYXN0cC1zcC50YWIiLCBoZWFkZXIgPSBGQUxTRSwgc2VwPSJcdCIpICAlPiUKICBkaXN0aW5jdChWMSwgLmtlZXBfYWxsID0gVFJVRSkKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KbG9jIDwtIHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vc3IzMjAvbmItMjAyMi9tYWluL0NfZ2lnYXMvYW5hbHlzZXMvTE9DX0FjYy50YWIiLCBzZXAgPSAiICIsIGhlYWRlciA9IEZBTFNFKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQpjb21iIDwtIGxlZnRfam9pbihsb2MsIGNnX3NwLCBieSA9IGMoIlYyIiA9ICJWMSIpKSAlPiUKICBsZWZ0X2pvaW4oZGVnbGlzdCwgYnkgPSBjKCJWMSIgPSAiUm93TmFtZSIpKQpgYGAKCgojIEdlbmUgRW5yaWNobWVudCBBbmFseXNpcwpgYGB7ciwgZXZhbD1GQUxTRX0KZ2VuZV9kZWdfc3RhdHVzIDwtIHJlc19kZiAlPiUKICBtdXRhdGUoZGVnc3RhdXMgPSBpZmVsc2UocGFkaiA8IDAuMDUsIDEsIDApKSAKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyBSZWFkIHRoZSBGQVNUQSBmaWxlCmZhc3RhX2RhdGEgPC0gcmVhZEROQVN0cmluZ1NldCgiLi4vZGF0YS9ybmEuZm5hIikKCiMgQ2FsY3VsYXRlIGdlbmUgbGVuZ3RocwpnZW5lX2xlbmd0aHMgPC0gd2lkdGgoZmFzdGFfZGF0YSkKCgojIEV4dHJhY3QgZ2VuZSBuYW1lcy9JRHMgZnJvbSBzZXF1ZW5jZSBJRHMKZ2VuZV9uYW1lcyA8LSBzYXBwbHkobmFtZXMoZmFzdGFfZGF0YSksIGZ1bmN0aW9uKHgpIHN0cnNwbGl0KHgsICIgIilbWzFdXVsxXSkKCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIGdlbmUgSURzIGFuZCBsZW5ndGhzCmdlbmVfbGVuZ3Roc19kZiA8LSBkYXRhLmZyYW1lKGdlbmVJRCA9IGdlbmVfbmFtZXMsIGxlbmd0aCA9IGdlbmVfbGVuZ3RocykKCmBgYAoKIyMgIE5lZWQgR08gTWFwcGluZ3MKYGBge3IsIGV2YWw9RkFMU0V9CnB3ZiA8LSBudWxscChnZW5lX2RhdGEsIGJpYXMuZGF0YSA9IGdlbmVfbGVuZ3RocykKCkdPX2FuYWx5c2lzIDwtIGdvc2VxKHB3ZiwgZ2VuZTJjYXQgPSAieW91cl9vcmdhbmlzbV9HT19tYXBwaW5nIikKCmBgYAo=