### Start ref-cache Server Source: https://www.htslib.org/doc/ref-cache.html Create directories for cache and logs, then start the ref-cache server in the background listening on port 8080 with a specified upstream source. ```bash mkdir cached_refs mkdir logs ref-cache -b -d cached_refs -l logs -p 8080 -u https://www.ebi.ac.uk/ena/cram/md5/ ``` -------------------------------- ### Example Samtools Checksum Output Source: https://www.htslib.org/doc/samtools-checksum.html This example shows the typical output format for samtools checksums, including header information and the checksum table for different read groups and QC statuses. ```text # Checksum for file: NA12892.chrom20.ILLUMINA.bwa.CEU.high_coverage.bam # Aux tags: BC,FI,QT,RT,TC # BAM flags: PAIRED,READ1,READ2 # Group QC count flag+seq +name +qual +aux combined all all 42890086 71169bbb 633fd9f7 2a2e693f 71169bbb 09d03ed4 SRR010946 all 262249 2957df86 3b6dcbc9 66be71f7 2957df86 58e89c25 SRR002165 all 97846 47ff17e0 6ff8fc7b 58366bf5 47ff17e0 796eecb0 [...cut...] ``` -------------------------------- ### HAP/SAMPLE to VCF Conversion Examples Source: https://www.htslib.org/doc/bcftools.html Demonstrates the format of .hap files when using the --vcf-ids option and the default format for the --hapsample2vcf command. ```text .hap (with --vcf-ids) --------------------- 1:111485207_G_A rsID1 111485207 G A 0 1 0 0 1:111495231_A__111495784 rsID3 111495231 A 0 0 1 0 .hap (the default) ------------------ 1 1:111485207_G_A 111485207 G A 0 1 0 0 1 1:111495231_A__111495784 111495231 A 0 0 1 0 ``` -------------------------------- ### Bcftools String Comparison Examples Source: https://www.htslib.org/doc/bcftools.html Demonstrates case-insensitive string comparisons and OR logic for comma-separated values. ```bash -i 'TAG="hello,world"' -i 'TAG="hello" || TAG="world"' -i 'TAG="hello" && TAG="world"' ``` -------------------------------- ### INFO and FORMAT Tags Source: https://www.htslib.org/doc/bcftools.html Examples of how to reference INFO and FORMAT tags, including common column names. ```plaintext INFO/DP or DP FORMAT/DV, FMT/DV, or DV FILTER, QUAL, ID, CHROM, POS, REF, ALT[0] ``` -------------------------------- ### samtools flagstat default output example Source: https://www.htslib.org/doc/samtools-flagstat.html Example of the default output format for samtools flagstat, showing total reads and specific categories with percentages. ```text 122 + 28 in total (QC-passed reads + QC-failed reads) 32 + 0 mapped (94.12% : N/A) ``` -------------------------------- ### Bcftools Vector Query Examples Source: https://www.htslib.org/doc/bcftools.html Illustrates querying multiple values in a vector using OR logic and specific index access. ```bash -i 'TAG[*]=1' .. true, the record will be printed -i 'TAG[*]!=1' .. true -e 'TAG[*]=1' .. false, the record will be discarded -e 'TAG[*]!=1' .. false -i 'TAG[0]=1' .. true -i 'TAG[0]!=1' .. false -e 'TAG[0]=1' .. false -e 'TAG[0]!=1' .. true ``` -------------------------------- ### Compress and Index a GFF File Source: https://www.htslib.org/doc/1.2.1/tabix.html This example demonstrates how to compress a GFF file using bgzip and then index it with tabix for efficient querying. It first filters and sorts the GFF content before compression. ```bash (grep ^"#" in.gff; grep -v ^"#" in.gff | sort -k1,1 -k4,4n) | bgzip > sorted.gff.gz; ``` ```bash tabix -p gff sorted.gff.gz; ``` -------------------------------- ### HAP/LEGEND/SAMPLE Conversion Examples Source: https://www.htslib.org/doc/bcftools.html Shows the expected format for .hap, .legend, and .sample files when converting to/from VCF using IMPUTE2/SHAPEIT formats. ```text .hap ----- 0 1 0 0 1 0 0 1 0 0 0 1 .legend ------- id position a0 a1 1:111485207_G_A 111485207 G A 1:111494194_C_T 111494194 C T .sample ------- sample population group sex sample1 sample1 sample1 2 sample2 sample2 sample2 2 ``` -------------------------------- ### Split and Checksum BAM Files Source: https://www.htslib.org/doc/samtools-checksum.html This example demonstrates how to split a BAM file, compute checksums for the original and split files, and then compare them to verify data integrity. It uses shell commands to manage the process. ```bash samtools split -u /tmp/split/noRG.bam -f '/tmp/split/%!.%.' in.cram samtools checksum -a in.cram -o in.chksum s=$(for i in /tmp/split/*.bam;do echo "<("samtools checksum -a $i")";done) eval samtools checksum -m $s -o split.chksum diff in.chksum split.chksum ``` -------------------------------- ### Get Plugin Usage Information Source: https://www.htslib.org/doc/bcftools.html Displays detailed usage information for a specific plugin, such as 'dosage'. ```bash bcftools +dosage -h ``` -------------------------------- ### Sex Column Format Example Source: https://www.htslib.org/doc/bcftools.html Illustrates the required format for the sex file used with the --sex option. ```text MaleSample M FemaleSample F ``` -------------------------------- ### Example Primer BED File Format Source: https://www.htslib.org/doc/samtools-ampliconstats.html Specifies primer locations for amplicons. Each line defines a region with LEFT and RIGHT primers. ```bed MN908947.3 1875 1897 nCoV-2019_7_LEFT 60 + MN908947.3 1868 1890 nCoV-2019_7_LEFT_alt0 60 + MN908947.3 2247 2269 nCoV-2019_7_RIGHT 60 - MN908947.3 2242 2264 nCoV-2019_7_RIGHT_alt5 60 - MN908947.3 2181 2205 nCoV-2019_8_LEFT 60 + MN908947.3 2568 2592 nCoV-2019_8_RIGHT 60 - ``` -------------------------------- ### Minimal GFF3 example for bcftools csq Source: https://www.htslib.org/doc/bcftools.html This example demonstrates the minimal structure required for a GFF3 file to be used with bcftools csq. It includes gene, transcript, UTR, and CDS features with necessary attributes. ```plaintext # The program looks for "CDS", "exon", "three_prime_UTR" and "five_prime_UTR" lines, # looks up their parent transcript (determined from the "Parent=transcript:" attribute), # the gene (determined from the transcript's "Parent=gene:" attribute), and the biotype # (the most interesting is "protein_coding"). # # Empty and commented lines are skipped, the following GFF columns are required # 1. chromosome # 2. IGNORED # 3. type (CDS, exon, three_prime_UTR, five_prime_UTR, gene, transcript, etc.) # 4. start of the feature (1-based) # 5. end of the feature (1-based) # 6. IGNORED # 7. strand (+ or -) # 8. phase (0, 1, 2 or .) # 9. semicolon-separated attributes (see below) # # Attributes required for # gene lines: # - ID=gene: # - biotype= # - Name= [optional] # # transcript lines: # - ID=transcript: # - Parent=gene: # - biotype= # # other lines (CDS, exon, five_prime_UTR, three_prime_UTR): # - Parent=transcript: # # Supported biotypes: # - see the function gff_parse_biotype() in bcftools/csq.c 1 ignored_field gene 21 2148 . - . ID=gene:GeneId;biotype=protein_coding;Name=GeneName 1 ignored_field transcript 21 2148 . - . ID=transcript:TranscriptId;Parent=gene:GeneId;biotype=protein_coding 1 ignored_field three_prime_UTR 21 2054 . - . Parent=transcript:TranscriptId 1 ignored_field exon 21 2148 . - . Parent=transcript:TranscriptId 1 ignored_field CDS 21 2148 . - 1 Parent=transcript:TranscriptId 1 ignored_field five_prime_UTR 210 2148 . - . Parent=transcript:TranscriptId ``` -------------------------------- ### TSV to VCF Conversion Example 2 Source: https://www.htslib.org/doc/bcftools.html Converts a tab-delimited file into a sites-only VCF, ignoring the first column and specifying REF and ALT alleles. ```bash bcftools convert -c -,CHROM,POS,REF,ALT -f ref.fa --tsv2vcf calls.txt -o out.bcf ``` -------------------------------- ### Specify Allowed Client Networks Source: https://www.htslib.org/doc/ref-cache.html Use the -m option to define the allowed client networks for the ref-cache server. This example allows connections from a specific CIDR block and the default private ranges. ```bash ref-cache -m 192.0.2.0/24 -m default ... ``` -------------------------------- ### Define Header Lines for Annotations Source: https://www.htslib.org/doc/bcftools.html Provides examples of custom header lines for INFO tags, specifying their ID, Number, Type, and Description. ```vcf ##INFO= ##INFO= ``` -------------------------------- ### Sample Annotation File Format Source: https://www.htslib.org/doc/bcftools.html This is an example of a tab-delimited annotation file. It includes columns for CHROM, POS, a string tag, and a numeric tag. Ensure your annotation file matches the expected format for bcftools annotate. ```text # Sample annotation file with columns CHROM, POS, STRING_TAG, NUMERIC_TAG 1 752566 SomeString 5 1 798959 SomeOtherString 6 ``` -------------------------------- ### Set output format for pipeline usage Source: https://www.htslib.org/doc/samtools-reset.html Demonstrates setting the output format to BAM with compression level 0 for use in a pipeline. This example chains samtools collate, samtools reset, and a hypothetical aligner. ```bash samtools collate -O -u input.cram | samtools reset --output-fmt BAM,level=0 | myaligner -I bam -o out.bam ``` -------------------------------- ### Annotate TSV with Header Mapping and Special Annotations Source: https://www.htslib.org/doc/annot-tsv.html This example demonstrates transferring fields and adding special annotations ('nbp', 'cnt') by mapping columns using header names from the target file. The output includes original fields and new annotations. ```bash annot-tsv -s src.txt.gz -t tgt_hdr.txt.gz -c chr,beg,end:chrom,from,to -m sample -f type,qual -a nbp,cnt:pair,count ``` -------------------------------- ### Specify Sample List Source: https://www.htslib.org/doc/bcftools.html Provide a list of sample names to include or exclude. Refer to 'Common Options' for details. ```bash -s, --samples LIST list of sample names. See **Common Options** ``` -------------------------------- ### Run a Plugin Source: https://www.htslib.org/doc/bcftools.html Executes a specified plugin with an input VCF file. ```bash bcftools plugin counts in.vcf ``` -------------------------------- ### BCSQ Annotation Example: Stop Gained Variant Source: https://www.htslib.org/doc/bcftools.html Provides an example of BCSQ annotation for a stop gained variant, specifying the consequence type, gene name, transcript ID, and the specific variant causing the stop gain. ```plaintext BCSQ=stop_gained|C2orf83|ENST00000264387|-|141W>141*|228476140C>T ``` -------------------------------- ### List Available Plugins Source: https://www.htslib.org/doc/bcftools.html Lists all plugins that are currently available for use with bcftools. ```bash bcftools plugin -l ``` -------------------------------- ### Annotate Output with FORMAT/INFO Tags Source: https://www.htslib.org/doc/bcftools.html Specify FORMAT and INFO tags to include in the output. Use '?' to list available tags. ```bash -a, --annotate LIST Comma-separated list of FORMAT and INFO tags to output. (case-insensitive, the "FORMAT/" prefix is optional, and use "?" to list available annotations on the command line) [null]: ``` FORMAT/AD .. Allelic depth (Number=R,Type=Integer) FORMAT/ADF .. Allelic depths on the forward strand (Number=R,Type=Integer) FORMAT/ADR .. Allelic depths on the reverse strand (Number=R,Type=Integer) FORMAT/DP .. Number of high-quality bases (Number=1,Type=Integer) FORMAT/SP .. Phred-scaled strand bias P-value (Number=1,Type=Integer) FORMAT/SCR .. Number of soft-clipped reads (Number=1,Type=Integer) INFO/AD .. Total allelic depth (Number=R,Type=Integer) INFO/ADF .. Total allelic depths on the forward strand (Number=R,Type=Integer) INFO/ADR .. Total allelic depths on the reverse strand (Number=R,Type=Integer) INFO/SCR .. Number of soft-clipped reads (Number=1,Type=Integer) FORMAT/DV .. Deprecated in favor of FORMAT/AD; Number of high-quality non-reference bases, (Number=1,Type=Integer) FORMAT/DP4 .. Deprecated in favor of FORMAT/ADF and FORMAT/ADR; Number of high-quality ref-forward, ref-reverse, alt-forward and alt-reverse bases (Number=4,Type=Integer) FORMAT/DPR .. Deprecated in favor of FORMAT/AD; Number of high-quality bases for each observed allele (Number=R,Type=Integer) INFO/DPR .. Deprecated in favor of INFO/AD; Number of high-quality bases for each observed allele (Number=R,Type=Integer) ``` ``` -------------------------------- ### Prepopulating Reference Cache with FASTA Files Source: https://www.htslib.org/doc/reference_seqs.html Use the seq_cache_populate.pl script to pre-populate a local reference cache from FASTA files. This is useful for cloud environments to ensure local network access. ```bash seq_cache_populate.pl -root=/local/refs -subdirs 2 *.fa ``` -------------------------------- ### BCFtools Filter Expression Source: https://www.htslib.org/doc/bcftools.html Example of filtering VCF records using an expression with BCFtools. Expressions should be quoted to prevent shell interpretation. ```shell bcftools view -i 'ID!="." & MAF[0]<0.01' ``` -------------------------------- ### Samtools mpileup to Show All Alignments Source: https://www.htslib.org/doc/samtools-mpileup.html Use options like --count-orphans, --no-BAQ, --max-depth 0, --min-BQ 0, --excl-flags 0, and --disable-overlap-removal to display all possible alignments without filtering or modification. ```bash samtools mpileup --count-orphans --no-BAQ --max-depth 0 --fasta-ref ref_file.fa \ --min-BQ 0 --excl-flags 0 --disable-overlap-removal in.sam ``` ```bash samtools mpileup -A -B -d 0 -f ref_file.fa -Q 0 --ff 0 -x in.sam ``` -------------------------------- ### Sample Filtering with File Source: https://www.htslib.org/doc/bcftools.html Demonstrates filtering based on sample names provided in an external file. ```plaintext GT[@samples.txt]="het" & binom(AD)<0.01 ``` -------------------------------- ### Get CRAM File Size Information Source: https://www.htslib.org/doc/samtools.html Retrieves verbose size information for a CRAM file. Useful for understanding compression efficiency. ```bash samtools cram-size -v -o out.size in.cram ``` -------------------------------- ### Remove comment lines from header Source: https://www.htslib.org/doc/samtools-reheader.html Use the `-c` option with `grep` to filter out lines starting with `@CO` from the header. This is useful for cleaning up header information. ```bash samtools reheader -c 'grep -v ^@CO' in.bam ``` -------------------------------- ### BCSQ Annotation Example: Downstream Stop Variant Source: https://www.htslib.org/doc/bcftools.html Demonstrates the BCSQ annotation for a variant downstream from a stop codon, where the consequence type is prefixed with an asterisk (*). ```plaintext BCSQ=*missense|PER3|ENST00000361923|+|1028M>1028T|7890117T>C ``` -------------------------------- ### List Common Plugin Options Source: https://www.htslib.org/doc/bcftools.html Lists options that are common to all bcftools plugins. ```bash bcftools plugin ``` -------------------------------- ### Specify Sample File Source: https://www.htslib.org/doc/bcftools.html Use a file containing sample names for inclusion or exclusion (prefix with '^'). This file can also be used for renaming samples. ```bash -S, --samples-file FILE file of sample names to include or exclude if prefixed with "^". One sample per line. This file can also be used to rename samples by giving the new sample name as a second white-space-separated column, like this: "old_name new_name". If a sample name contains spaces, the spaces can be escaped using the backslash character, for example "Not\ a\ good\ sample\ name". ``` -------------------------------- ### Samtools mpileup with Range Specification Source: https://www.htslib.org/doc/samtools-mpileup.html Use the -r option to specify a region for processing. Index files can be implicit or explicit. ```bash samtools mpileup in1.bam in2.sam.gz -r chr10:100000-200000 ``` ```bash samtools mpileup in1.bam in2.sam.gz idx/in1.csi idx/in2.csi -X -r chr10:100000-200000 ``` ```bash samtools mpileup -b fofn -r chr10:100000-200000 ``` -------------------------------- ### TSV to VCF Conversion Example 1 Source: https://www.htslib.org/doc/bcftools.html Converts 23andme results into VCF format, specifying column order, sample name, and reference FASTA file. ```bash bcftools convert -c ID,CHROM,POS,AA -s SampleName -f 23andme-ref.fa --tsv2vcf 23andme.txt -o out.vcf.gz ``` -------------------------------- ### Create and Index a GFF File with Tabix Source: https://www.htslib.org/doc/tabix.html This snippet demonstrates how to sort, compress, and index a GFF file using standard Unix tools and tabix. It first filters and sorts the GFF file, then compresses it with bgzip, and finally creates a tabix index. ```bash (grep "^#" in.gff; grep -v "^#" in.gff | sort -t"`printf '\t'`" -k1,1 -k4,4n) | bgzip > sorted.gff.gz; tabix -p gff sorted.gff.gz ``` -------------------------------- ### Index Allele Frequency File with Tabix Source: https://www.htslib.org/doc/bcftools.html Indexes the prepared allele frequency file (AFs.tab.gz) for efficient lookup by bcftools annotate. Requires tabix to be installed. ```bash tabix -s1 -b2 -e2 AFs.tab.gz ``` -------------------------------- ### Sample-level Functions in Bcftools Source: https://www.htslib.org/doc/bcftools.html Use SMPL_ prefixed functions to evaluate per-sample values on FORMAT tags for site selection. ```bash SMPL_MAX, SMPL_MIN, SMPL_AVG, SMPL_MEAN, SMPL_MEDIAN, SMPL_STDEV, SMPL_SUM, SMPL_COUNT, sMAX, sMIN, sAVG, sMEAN, sMEDIAN, sSTDEV, sSUM, sCOUNT ``` -------------------------------- ### Indexing a BGZF-compressed file with tabix Source: https://www.htslib.org/doc/bcftools.html This command indexes a BGZF-compressed file for use with tabix. It specifies the chromosome column, start position column, and end position column. ```bash tabix -s1 -b2 -e3 file.gz ``` -------------------------------- ### Basic bcftools csq Usage Source: https://www.htslib.org/doc/bcftools.html This snippet shows the basic command structure for running bcftools csq, specifying the reference FASTA, GFF annotation file, input VCF, and output BCF file. ```bash bcftools csq -f hs37d5.fa -g Homo_sapiens.GRCh37.82.gff3.gz in.vcf -Ob -o out.bcf ``` -------------------------------- ### BCSQ Annotation Example: Frameshift Insertion Source: https://www.htslib.org/doc/bcftools.html Shows the BCSQ annotation for an inframe insertion, resulting from a frame-restoring combination of two frameshift insertions. It includes the position of the full annotation. ```plaintext BCSQ=@46115084 BCSQ=inframe_insertion|COPZ2|ENST00000006101|-|18AGRGP>18AQAGGP|46115072C>CG+46115084T>TGG ``` -------------------------------- ### Run a Plugin with Abbreviated Notation Source: https://www.htslib.org/doc/bcftools.html Runs a plugin using the shorthand '+' notation, which is equivalent to the full 'plugin' command. ```bash bcftools +counts in.vcf ``` -------------------------------- ### Print Samples with Custom BAI Index Files Source: https://www.htslib.org/doc/samtools-samples.html Uses custom .bai index files to determine the indexing status of BAM files. This is helpful when index files are named differently or located separately. ```bash $ samtools samples -i -h -X S1.bam S2.bam S1.bam.bai S2.bam.bai #SM PATH INDEX S1 S1.bam Y S2 S2.bam Y ``` -------------------------------- ### Atomize Variants with '.' Overlap Source: https://www.htslib.org/doc/bcftools.html This example shows how to decompose complex variants into simpler ones using bcftools norm with the --atomize option and setting overlapping variants to missing ('.'). ```bash bcftools norm -a --atom-overlaps . file.vcf.gz ``` -------------------------------- ### Include customized index file location Source: https://www.htslib.org/doc/samtools-merge.html This example shows how to specify custom locations for index files when merging BAM files, particularly when the index files are not in the default data folder. ```bash samtools merge [options] -X [ ... ] [ ... ] ``` -------------------------------- ### Print Samples with Header Source: https://www.htslib.org/doc/samtools-samples.html Extracts sample names from BAM/SAM files and includes a header. Useful when sample names are present in the @RG line. ```bash $ samtools samples -h S*.bam *.sam #SM PATH S1 S1.bam S2 S2.bam S3 S3.bam S4 S4.bam S5 S5.bam . example.sam ``` -------------------------------- ### Text Alignment Viewer Source: https://www.htslib.org/doc/samtools.html Launches a text-based alignment viewer using the ncurses library. Press '?' for help and 'g' to jump to a region. ```bash samtools tview ["-p" _chr:pos_] ["-s" _STR_] ["-d" _display_] [ref.fasta] ``` -------------------------------- ### Create BED File Format Source: https://www.htslib.org/doc/bcftools.html Generates a BED file format (chromosome, 0-based start position, 1-based end position, and ID) from VCF/BCF data. This is useful for genomic interval representation. ```bash # Make a BED file: chr, pos (0-based), end pos (1-based), id bcftools query -f'%CHROM\t%POS0\t%END\t%ID\n' file.bcf ``` -------------------------------- ### Filter Samples by FORMAT/DP Value (OR Operator) Source: https://www.htslib.org/doc/bcftools.html Prints sample, genotype, and DP for all samples at sites where at least one sample has DP equal to 1 or 2. This example uses the logical OR operator `||`. ```bash # Print all samples at sites where at least one sample has DP=1 or DP=2. In the second case # print only samples with DP=1 or DP=2, the difference is in the logical operator used, || vs |. bcftools query -f '[%SAMPLE %GT %DP\n]' -i 'FMT/DP=1 || FMT/DP=2' file.vcf ``` -------------------------------- ### Atomize Variants with Escaped '*' Overlap Source: https://www.htslib.org/doc/bcftools.html This example shows decomposing complex variants using bcftools norm with --atomize and setting overlapping variants to the star allele ('*'), using shell escaping for the asterisk. ```bash bcftools norm -a --atom-overlaps \* file.vcf.gz ``` -------------------------------- ### Atomize Variants with '*' Overlap Source: https://www.htslib.org/doc/bcftools.html This example demonstrates decomposing complex variants using bcftools norm with --atomize and setting overlapping variants to the star allele ('*'). Note the need to quote or escape the asterisk. ```bash bcftools norm -a --atom-overlaps '*' file.vcf.gz ``` -------------------------------- ### Display Beginning of BAM File Source: https://www.htslib.org/doc/samtools.html Displays the first few records of a BAM file. Useful for a quick inspection of file content. ```bash samtools head in.bam ``` -------------------------------- ### Navigate to a specific position with samtools tview Source: https://www.htslib.org/doc/samtools-tview.html Use the -p option to specify an initial position for the alignment viewer. The position can be in 'chr:pos' format. ```bash samtools tview -p 1:234567 in.bam ``` -------------------------------- ### Filter Samples by FORMAT/DP Value (Single Pipe Operator) Source: https://www.htslib.org/doc/bcftools.html Prints sample, genotype, and DP for all samples at sites where at least one sample has DP equal to 1 or 2. This example uses the logical OR operator `|`. ```bash bcftools query -f '[%SAMPLE %GT %DP\n]' -i 'FMT/DP=1 | FMT/DP=2' file.vcf ``` -------------------------------- ### Index FASTQ File Source: https://www.htslib.org/doc/samtools.html Creates an index for a FASTQ file. This allows for faster random access to sequences within the FASTQ file. ```bash samtools fqidx ref.fastq ``` -------------------------------- ### Filter indel clusters with bcftools Source: https://www.htslib.org/doc/bcftools.html Use --IndelGap to filter clusters of indels separated by a specified number of base pairs, allowing only one to pass. The example demonstrates the filtering logic for indel clusters. ```bash bcftools filter --IndelGap 2 file.vcf ``` -------------------------------- ### Create Sequence Dictionary Source: https://www.htslib.org/doc/samtools.html Creates a sequence dictionary (a FASTA index file) for a reference FASTA file. Requires reference name and assembly attributes. ```bash samtools dict -a GRCh38 -s "Homo sapiens" ref.fasta ``` -------------------------------- ### Discard PG entries from a specific ID onwards Source: https://www.htslib.org/doc/samtools-reset.html Removes Program Group (PG) lines from the header starting with the specified ID ('bwa_index') and all subsequent PG lines. Use this to clean up header information from specific aligners. ```bash samtools reset -o out.sam --reject-PG=bwa_index ```