Browse code

phylo4d

guangchuang yu authored on 24/11/2016 05:04:08
Showing 3 changed files

... ...
@@ -1,5 +1,7 @@
1 1
 CHANGES IN VERSION 1.7.4
2 2
 ------------------------
3
+ o allow yscale to use data stored in phylo4d object <2016-11-24, Thu>
4
+   + https://github.com/GuangchuangYu/ggtree/issues/98
3 5
  o groupOTU method now accept 'overlap = c("overwrite", "origin", "abandon")' parameter <2016-11-16, Wed>
4 6
    + https://groups.google.com/forum/#!topic/bioc-ggtree/Q4LnwoTf1DM
5 7
 
... ...
@@ -18,7 +18,7 @@ as.binary.phylo <- function(tree, ...) {
18 18
         cat("The input tree is already binary...\n")
19 19
         invisible(tree)
20 20
     }
21
-    
21
+
22 22
     polyNode <- tree$edge[,1] %>% table %>% '>'(2) %>%
23 23
         which %>% names %>% as.numeric
24 24
 
... ...
@@ -35,7 +35,7 @@ as.binary.phylo <- function(tree, ...) {
35 35
             idx <- idx[-1]
36 36
         }
37 37
     }
38
-        
38
+
39 39
     tree$Nnode <- tree$Nnode+ii
40 40
     tree$edge.length <- c(tree$edge.length, rep(0, ii))
41 41
     return(tree)
... ...
@@ -44,23 +44,23 @@ as.binary.phylo <- function(tree, ...) {
44 44
 
45 45
 ##' remove singleton
46 46
 ##'
47
-##' 
47
+##'
48 48
 ##' @title rm.singleton.newick
49 49
 ##' @param nwk newick file
50
-##' @param outfile output newick file 
50
+##' @param outfile output newick file
51 51
 ##' @return tree text
52 52
 ##' @importFrom magrittr %<>%
53 53
 ##' @importFrom magrittr add
54 54
 ##' @importFrom ape write.tree
55 55
 ##' @author Guangchuang Yu \url{http://ygc.name}
56
-rm.singleton.newick <- function(nwk, outfile = NULL) {    
56
+rm.singleton.newick <- function(nwk, outfile = NULL) {
57 57
     tree <- readLines(nwk)
58 58
 
59 59
     ## remove singleton of tips
60 60
     nodePattern <- "\\w+:[\\.0-9Ee\\+\\-]+"
61 61
     singletonPattern.with.nodename <- paste0(".*(\\(", nodePattern, "\\)\\w+:[\\.0-9Ee\\+\\-]+).*")
62 62
     singletonPattern.wo.nodename <- paste0(".*(\\(", nodePattern, "\\):[\\.0-9Ee\\+\\-]+).*")
63
-    
63
+
64 64
     while(length(grep("\\([^,]+\\)", tree)) > 0) {
65 65
         singleton <- gsub(singletonPattern.with.nodename, "\\1", tree)
66 66
         if (singleton == tree) {
... ...
@@ -71,11 +71,11 @@ rm.singleton.newick <- function(nwk, outfile = NULL) {
71 71
         }
72 72
 
73 73
         tip <- gsub("\\((\\w+).*", "\\1", singleton)
74
-        
74
+
75 75
         len1 <- gsub(".*[^\\.0-9Ee\\+\\-]+([\\.0-9Ee\\+\\-]+)", "\\1", singleton)
76 76
         len2 <- gsub(".*:([\\.0-9Ee\\+\\-]+)\\).*", "\\1", singleton)
77 77
         len <- as.numeric(len1) + as.numeric(len2)
78
-        
78
+
79 79
         tree <- gsub(singleton, paste0(tip, ":", len), tree, fixed = TRUE)
80 80
     }
81 81
 
... ...
@@ -95,7 +95,7 @@ rm.singleton.newick <- function(nwk, outfile = NULL) {
95 95
         tree$edge.length[sidx] %<>% add(., tree$edge.length[idx])
96 96
         tree$edge.length <- tree$edge.length[-idx]
97 97
     }
98
-    
98
+
99 99
     if (!is.null(outfile)) {
100 100
         write.tree(tree, file=outfile)
101 101
     }
... ...
@@ -117,12 +117,12 @@ fortify.beast <- function(model, data,
117 117
 
118 118
     df    <- fortify(phylo, layout=layout, branch.length=branch.length,
119 119
                      ladderize=ladderize, right=right, mrsd = mrsd, ...)
120
-    
120
+
121 121
     stats <- model@stats
122 122
 
123 123
     scn <- colnames(stats)
124 124
     scn <- scn[scn != 'node']
125
-    
125
+
126 126
     for (cn in scn) {
127 127
         if (cn %in% colnames(df)) {
128 128
             colnames(stats)[colnames(stats) == cn] <- paste0(cn, "_")
... ...
@@ -151,7 +151,7 @@ fortify.beast <- function(model, data,
151 151
             }
152 152
             next
153 153
         }
154
-        
154
+
155 155
         len <- sapply(stats[,ii], length)
156 156
         if ( all(len == 1) ) {
157 157
             stats[, ii] %<>% unlist %>% as.character %>% as.numeric
... ...
@@ -181,31 +181,31 @@ fortify.beast <- function(model, data,
181 181
                 } else {
182 182
                     return(paste0('{', paste0(y, collapse = ','), '}'))
183 183
                 }
184
-            })  
184
+            })
185 185
         }
186 186
     }
187
-            
188
-      
187
+
188
+
189 189
     cn <- colnames(stats)
190 190
     lo <- cn[grep("_lower", cn)]
191 191
     hi <- gsub("lower$", "upper", lo)
192 192
     rid <- gsub("_lower$", "", lo)
193
-    
193
+
194 194
     for (i in seq_along(rid)) {
195 195
         stats[, rid[i]] <- paste0("[", stats[, lo[i]], ",", stats[, hi[i]], "]")
196 196
         stats[is.na(stats[, lo[i]]), rid[i]] <- NA
197 197
     }
198
-    
198
+
199 199
     idx   <- match(df$node, stats$node)
200 200
     stats <- stats[idx,]
201 201
     cn_stats <- colnames(stats)
202 202
     stats <- stats[, cn_stats != "node"]
203
-    
203
+
204 204
     df <- cbind(df, stats)
205 205
     if (is(stats, "data.frame") == FALSE) {
206 206
         colnames(df)[colnames(df) == "stats"] <- cn_stats[cn_stats != "node"]
207 207
     }
208
-    
208
+
209 209
     df <- scaleY(phylo, df, yscale, layout, ...)
210 210
 
211 211
     append_extraInfo(df, model)
... ...
@@ -235,7 +235,7 @@ fortify.codeml <- function(model, data,
235 235
                           "rst.branch.length",
236 236
                           colnames(dNdS)[-c(1,2)])
237 237
                         )
238
-    
238
+
239 239
     if (length == "rst.branch.length") {
240 240
         phylo <- get.tree(model@rst)
241 241
     } else {
... ...
@@ -244,14 +244,14 @@ fortify.codeml <- function(model, data,
244 244
         }
245 245
         phylo <- set_branch_length(model@mlc, length)
246 246
     }
247
-    
247
+
248 248
     df <- fortify(phylo, data, layout, ladderize, right,
249 249
                   branch.length=length, mrsd=mrsd, ...)
250
-    
250
+
251 251
     res <- merge_phylo_anno.codeml_mlc(df, dNdS, ndigits)
252 252
     df <- merge_phylo_anno.paml_rst(res, model@rst)
253 253
     df <- scaleY(phylo, df, yscale, layout, ...)
254
-    
254
+
255 255
     append_extraInfo(df, model)
256 256
 }
257 257
 
... ...
@@ -269,10 +269,10 @@ fortify.codeml_mlc <- function(model, data,
269 269
                                ...) {
270 270
 
271 271
     phylo <- set_branch_length(model, branch.length)
272
-        
272
+
273 273
     df <- fortify(phylo, data, layout, ladderize, right,
274 274
                   branch.length=branch.length, mrsd=mrsd, ...)
275
-    
275
+
276 276
     dNdS <- model@dNdS
277 277
 
278 278
     df <- merge_phylo_anno.codeml_mlc(df, dNdS, ndigits)
... ...
@@ -290,12 +290,12 @@ merge_phylo_anno.codeml_mlc <- function(df, dNdS, ndigits = NULL) {
290 290
             }
291 291
         }
292 292
     }
293
-    
293
+
294 294
     res <- merge(df, dNdS,
295 295
                  by.x  = c("node", "parent"),
296 296
                  by.y  = c("node", "parent"),
297 297
                  all.x = TRUE)
298
-    
298
+
299 299
     res[match(df$node, res$node),]
300 300
 }
301 301
 
... ...
@@ -309,7 +309,7 @@ fortify.codeml_mlc_ <- function(model, data,
309 309
 }
310 310
 
311 311
 
312
-    
312
+
313 313
 ##' @method fortify paml_rst
314 314
 ##' @export
315 315
 fortify.paml_rst <- function(model, data, layout = "rectangular", yscale="none",
... ...
@@ -354,13 +354,13 @@ fortify.jplace <- function(model, data,
354 354
 
355 355
     df <- scaleY(model@phylo, df, yscale, layout, ...)
356 356
 
357
-    append_extraInfo(df, model)    
357
+    append_extraInfo(df, model)
358 358
 }
359 359
 
360 360
 scaleY <- function(phylo, df, yscale, layout, ...) {
361 361
     if (yscale == "none") {
362 362
         return(df)
363
-    } 
363
+    }
364 364
     if (! yscale %in% colnames(df)) {
365 365
         warning("yscale is not available...\n")
366 366
         return(df)
... ...
@@ -375,7 +375,7 @@ scaleY <- function(phylo, df, yscale, layout, ...) {
375 375
     } else {
376 376
         y <- getYcoord_scale_category(phylo, df, yscale, ...)
377 377
     }
378
-    
378
+
379 379
     df[, "y"] <- y
380 380
 
381 381
     return(df)
... ...
@@ -396,9 +396,10 @@ fortify.phylo4 <- function(model, data, layout="rectangular", yscale="none",
396 396
 ##' @export
397 397
 fortify.phylo4d <- function(model, data, layout="rectangular", yscale="none",
398 398
                             ladderize=TRUE, right=FALSE, mrsd=NULL, ...) {
399
-    res <- fortify.phylo4(model, data, layout, yscale, ladderize, right, mrsd, ...)
399
+    res <- fortify.phylo4(model, data, layout, yscale="none", ladderize, right, mrsd, ...) # not apply yscale at this moment
400 400
     tdata <- model@data[match(res$node, rownames(model@data)), , drop=FALSE]
401
-    cbind(res, tdata)
401
+    df <- cbind(res, tdata)
402
+    scaleY(as.phylo.phylo4(model), df, yscale, layout, ...)
402 403
 }
403 404
 
404 405
 as.phylo.phylo4 <- function(phylo4) {
... ...
@@ -411,7 +412,7 @@ as.phylo.phylo4 <- function(phylo4) {
411 412
     phylo <- list(edge = edge,
412 413
                   edge.length = edge.length,
413 414
                   tip.label = tip.label)
414
-    
415
+
415 416
     node.id <- sort(unique(edge[,1]))
416 417
     node.id <- node.id[node.id != 0]
417 418
     node.label <- phylo4@label[node.id]
... ...
@@ -425,7 +426,7 @@ as.phylo.phylo4 <- function(phylo4) {
425 426
 
426 427
 ##' fortify a phylo to data.frame
427 428
 ##'
428
-##' 
429
+##'
429 430
 ##' @rdname fortify
430 431
 ##' @title fortify
431 432
 ##' @param model phylo object
... ...
@@ -442,7 +443,7 @@ as.phylo.phylo4 <- function(phylo4) {
442 443
 ##' @method fortify phylo
443 444
 ##' @export
444 445
 ##' @author Yu Guangchuang
445
-fortify.phylo <- function(model, data, layout="rectangular", 
446
+fortify.phylo <- function(model, data, layout="rectangular",
446 447
                           ladderize=TRUE, right=FALSE, mrsd=NULL, as.Date=FALSE, ...) {
447 448
     if (ladderize == TRUE) {
448 449
         tree <- ladderize(model, right=right)
... ...
@@ -456,7 +457,7 @@ fortify.phylo <- function(model, data, layout="rectangular",
456 457
             tree$edge.length <- NULL
457 458
         }
458 459
     }
459
-    
460
+
460 461
     df <- as.data.frame(tree, layout=layout, ...)
461 462
     idx <- is.na(df$parent)
462 463
     df$parent[idx] <- df$node[idx]
... ...
@@ -477,7 +478,7 @@ fortify.phylo <- function(model, data, layout="rectangular",
477 478
             }
478 479
         }
479 480
     }
480
-    
481
+
481 482
     if (!is.null(mrsd)) {
482 483
         df <- scaleX_by_time_from_mrsd(df, mrsd, as.Date)
483 484
     }
... ...
@@ -486,7 +487,7 @@ fortify.phylo <- function(model, data, layout="rectangular",
486 487
 
487 488
 ##' convert phylo to data.frame
488 489
 ##'
489
-##' 
490
+##'
490 491
 ##' @title as.data.frame
491 492
 ##' @param x phylo object
492 493
 ##' @param row.names omitted here
... ...
@@ -501,7 +502,7 @@ as.data.frame.phylo <- function(x, row.names, optional,
501 502
                                 layout="rectangular", ...) {
502 503
     if (layout == "unrooted") {
503 504
         return(layout.unrooted(x))
504
-    } 
505
+    }
505 506
     as.data.frame.phylo_(x, layout, ...)
506 507
 }
507 508
 
... ...
@@ -510,14 +511,14 @@ as.data.frame.phylo_ <- function(x, layout="rectangular",
510 511
     if (branch.length != 'none') {
511 512
         branch.length = "branch.length"
512 513
     }
513
-    
514
+
514 515
     tip.label <- x[["tip.label"]]
515 516
     Ntip <- length(tip.label)
516 517
     N <- getNodeNum(x)
517
-    
518
+
518 519
     edge <- as.data.frame(x[["edge"]])
519 520
     colnames(edge) <- c("parent", "node")
520
-    
521
+
521 522
     if (! is.null(x$edge.length)) {
522 523
         edge$length <- x$edge.length
523 524
         if (branch.length == "none") {
... ...
@@ -540,7 +541,7 @@ as.data.frame.phylo_ <- function(x, layout="rectangular",
540 541
         xpos <- getXcoord_no_length(x)
541 542
         ypos <- getYcoord(x)
542 543
     }
543
-    
544
+
544 545
     xypos <- data.frame(node=1:N, x=xpos, y=ypos)
545 546
 
546 547
     res <- merge(edge, xypos, by.x="node", by.y="node", all.y=TRUE)
... ...
@@ -588,7 +589,7 @@ fortify.apeBootstrap <- fortify.raxml
588 589
 
589 590
 ##' @method fortify multiPhylo
590 591
 ##' @export
591
-fortify.multiPhylo <-  function(model, data, layout="rectangular", 
592
+fortify.multiPhylo <-  function(model, data, layout="rectangular",
592 593
                                 ladderize=TRUE, right=FALSE, mrsd=NULL, ...) {
593 594
 
594 595
     df.list <- lapply(model, function(x) fortify(x, layout=layout, ladderize=ladderize, right=right, mrsd=mrsd, ...))
... ...
@@ -600,9 +601,9 @@ fortify.multiPhylo <-  function(model, data, layout="rectangular",
600 601
     df <- do.call("rbind", df.list)
601 602
     df$.id <- rep(names(df.list), times=sapply(df.list, nrow))
602 603
     df$.id <- factor(df$.id, levels=names(df.list))
603
-    
604
+
604 605
     ## nNode <- sapply(df.list, nrow)
605
-    ## nNode2 <- cumsum(c(0, nNode[-length(nNode)])) 
606
+    ## nNode2 <- cumsum(c(0, nNode[-length(nNode)]))
606 607
     ## df$parent <- df$parent + rep(nNode2, times=nNode)
607 608
     return(df)
608 609
 }
... ...
@@ -615,7 +616,7 @@ fortify.phylip <- function(model, data, layout="rectangular",
615 616
     trees <- get.tree(model)
616 617
     fortify(trees, layout=layout, ladderize = ladderize, right=right, mrsd=mrsd, ...)
617 618
 }
618
-    
619
+
619 620
 ##' @method fortify r8s
620 621
 ##' @export
621 622
 fortify.r8s <- function(model, data, layout="rectangular",
... ...
@@ -659,7 +660,7 @@ fortify.phyloseq <- function(model, data, layout="rectangular",
659 660
     if ('Abundance' %in% colnames(dd)) {
660 661
         dd <- dd[dd$Abundance > 0, ]
661 662
     }
662
-    
663
+
663 664
     data <- merge(df, dd, by.x="label", by.y="OTU", all.x=TRUE)
664 665
     spacing <- 0.02
665 666
     idx <- with(data, sapply(table(node)[unique(node)], function(i) 1:i)) %>% unlist
... ...
@@ -669,7 +670,7 @@ fortify.phyloseq <- function(model, data, layout="rectangular",
669 670
     data[order(data$node, decreasing = FALSE), ]
670 671
 }
671 672
 
672
-                         
673
+
673 674
 ## fortify.cophylo <- function(model, data, layout="rectangular",
674 675
 ##                             ladderize=TRUE, right=FALSE, mrsd = NULL, ...) {
675 676
 ##     trees <- model$trees
... ...
@@ -2,9 +2,9 @@
2 2
 ggtree: an R package for visualization and annotation of phylogenetic trees with their covariates and other associated data
3 3
 ===========================================================================================================================
4 4
 
5
-[![releaseVersion](https://img.shields.io/badge/release%20version-1.6.4-green.svg?style=flat)](https://bioconductor.org/packages/ggtree) [![develVersion](https://img.shields.io/badge/devel%20version-1.7.3-green.svg?style=flat)](https://github.com/GuangchuangYu/ggtree) [![Bioc](http://www.bioconductor.org/shields/years-in-bioc/ggtree.svg)](https://www.bioconductor.org/packages/devel/bioc/html/ggtree.html#since) [![total](https://img.shields.io/badge/downloads-16443/total-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) [![month](https://img.shields.io/badge/downloads-1621/month-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) <img src="logo.png" align="right" />
5
+[![releaseVersion](https://img.shields.io/badge/release%20version-1.6.4-green.svg?style=flat)](https://bioconductor.org/packages/ggtree) [![develVersion](https://img.shields.io/badge/devel%20version-1.7.4-green.svg?style=flat)](https://github.com/GuangchuangYu/ggtree) [![Bioc](http://www.bioconductor.org/shields/years-in-bioc/ggtree.svg)](https://www.bioconductor.org/packages/devel/bioc/html/ggtree.html#since) [![total](https://img.shields.io/badge/downloads-16878/total-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) [![month](https://img.shields.io/badge/downloads-1621/month-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) <img src="logo.png" align="right" />
6 6
 
7
-[![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active) [![codecov](https://codecov.io/gh/GuangchuangYu/ggtree/branch/master/graph/badge.svg)](https://codecov.io/gh/GuangchuangYu/ggtree) [![Last-changedate](https://img.shields.io/badge/last%20change-2016--11--16-green.svg)](https://github.com/GuangchuangYu/ggtree/commits/master) [![GitHub forks](https://img.shields.io/github/forks/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/network) [![GitHub stars](https://img.shields.io/github/stars/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/stargazers) [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://awesome-r.com/#awesome-r-graphic-displays)
7
+[![Project Status: Active - The project has reached a stable, usable state and is being actively developed.](http://www.repostatus.org/badges/latest/active.svg)](http://www.repostatus.org/#active) [![codecov](https://codecov.io/gh/GuangchuangYu/ggtree/branch/master/graph/badge.svg)](https://codecov.io/gh/GuangchuangYu/ggtree) [![Last-changedate](https://img.shields.io/badge/last%20change-2016--11--24-green.svg)](https://github.com/GuangchuangYu/ggtree/commits/master) [![GitHub forks](https://img.shields.io/github/forks/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/network) [![GitHub stars](https://img.shields.io/github/stars/GuangchuangYu/ggtree.svg)](https://github.com/GuangchuangYu/ggtree/stargazers) [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://awesome-r.com/#awesome-r-graphic-displays)
8 8
 
9 9
 [![platform](http://www.bioconductor.org/shields/availability/devel/ggtree.svg)](https://www.bioconductor.org/packages/devel/bioc/html/ggtree.html#archives) [![Build Status](http://www.bioconductor.org/shields/build/devel/bioc/ggtree.svg)](https://bioconductor.org/checkResults/devel/bioc-LATEST/ggtree/) [![Linux/Mac Travis Build Status](https://img.shields.io/travis/GuangchuangYu/ggtree/master.svg?label=Mac%20OSX%20%26%20Linux)](https://travis-ci.org/GuangchuangYu/ggtree) [![AppVeyor Build Status](https://img.shields.io/appveyor/ci/Guangchuangyu/ggtree/master.svg?label=Windows)](https://ci.appveyor.com/project/GuangchuangYu/ggtree) [![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-green.svg?style=flat)](http://bioconda.github.io/recipes/bioconductor-ggtree/README.html)
10 10
 
... ...
@@ -18,7 +18,7 @@ Please cite the following article when using `ggtree`:
18 18
 
19 19
 **G Yu**, DK Smith, H Zhu, Y Guan, TTY Lam<sup>\*</sup>. ggtree: an R package for visualization and annotation of phylogenetic trees with their covariates and other associated data. ***Methods in Ecology and Evolution***. *accepted*
20 20
 
21
-[![doi](https://img.shields.io/badge/doi-10.1111/2041--210X.12628-green.svg?style=flat)](http://dx.doi.org/10.1111/2041-210X.12628) [![citation](https://img.shields.io/badge/cited%20by-1-green.svg?style=flat)](https://scholar.google.com.hk/scholar?oi=bibs&hl=en&cites=7268358477862164627) [![Altmetric](https://img.shields.io/badge/Altmetric-273-green.svg?style=flat)](https://www.altmetric.com/details/10533079)
21
+[![doi](https://img.shields.io/badge/doi-10.1111/2041--210X.12628-green.svg?style=flat)](http://dx.doi.org/10.1111/2041-210X.12628) [![citation](https://img.shields.io/badge/cited%20by-1-green.svg?style=flat)](https://scholar.google.com.hk/scholar?oi=bibs&hl=en&cites=7268358477862164627) [![Altmetric](https://img.shields.io/badge/Altmetric-272-green.svg?style=flat)](https://www.altmetric.com/details/10533079)
22 22
 
23 23
 ------------------------------------------------------------------------
24 24
 
... ...
@@ -51,7 +51,7 @@ For details, please visit our project website, <https://guangchuangyu.github.io/
51 51
 
52 52
 ### Download stats
53 53
 
54
-[![download](http://www.bioconductor.org/shields/downloads/ggtree.svg)](https://bioconductor.org/packages/stats/bioc/ggtree) [![total](https://img.shields.io/badge/downloads-16443/total-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) [![month](https://img.shields.io/badge/downloads-1621/month-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree)
54
+[![download](http://www.bioconductor.org/shields/downloads/ggtree.svg)](https://bioconductor.org/packages/stats/bioc/ggtree) [![total](https://img.shields.io/badge/downloads-16878/total-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree) [![month](https://img.shields.io/badge/downloads-1621/month-blue.svg?style=flat)](https://bioconductor.org/packages/stats/bioc/ggtree)
55 55
 
56 56
          +------------------------+-----------------------+-----------------------+--------------------+
57 57
          |                                                                                    *        |