Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ───────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.0     ✓ purrr   0.3.3
✓ tibble  2.1.3     ✓ dplyr   0.8.5
✓ tidyr   1.0.2     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ──────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
Parsed with column specification:
cols(
  .default = col_double(),
  playlist_id = col_character(),
  playlist_name = col_character(),
  track_id = col_character(),
  track_explicit = col_logical(),
  track_href = col_character(),
  track_is_local = col_logical(),
  track_name = col_character(),
  track_preview_url = col_character(),
  track_uri = col_character(),
  track_album_id = col_character(),
  track_album_name = col_character(),
  track_album_release_date = col_character(),
  track_album_release_date_precision = col_character(),
  key_name = col_character(),
  mode_name = col_character(),
  key_mode = col_character()
)
See spec(...) for full column specifications.

Os dados

Os dados a serem analisados vem do Spotify. Foram filtradas músicas de playlists selecionadas, e cada música possui vários atributos, como: daceability(danceabilidade?), energia, valence e outras características provavelmente interessantes.
Vejamos os dados:

rr musicas

Análise básica

Vejamos agora a média e mediana da danceability de cada playlist, verificando esses dados a partir de cada música pertencente.

danceability_mean = musicas %>%
  group_by(playlist_name) %>%
  count(danceability_mean = mean(danceability))

danceability_median = musicas %>%
  group_by(playlist_name) %>%
  count(danceability_median = median(danceability))

ggplot() + 
  geom_point(data = musicas,
             mapping = aes(x = danceability, y = playlist_name),
             alpha = .3,
             size = .5) +
  geom_point(data = danceability_mean,
             mapping = aes(x = danceability_mean, y = playlist_name),
             color = "red",
             size = 0.7) + 
  geom_point(data = danceability_median, mapping = aes(x = danceability_median, y = playlist_name),
             color = "blue",
             size = 0.7) +
  labs(x = "Danceability",
       y = "Nome da playlist",
       title = "Danceabilidade x Nome da playlist",
       subtitle = "Ponto azul = Mediana      Ponto vermelho = Média")


#CLASSICOS DO FUNK TEM A MELHOR MEDIA, E APARENTA TER UMA BAIXA DISPERSAO, VAMOS VER...

A playlist Clássicos do Funk possui a maior média e a maior dispersão, ou seja, os dados estão distantes da média.
Olhando para a playlist Bonde do Funk, vemos que a mesma possui a segunda maior média, e o desvio padrão está bem próximo.

Médias em número

rr musicas %>% group_by(playlist_name) %>% summarise(sd_danceability = sd(danceability)) %>% ggplot(aes(x = sd_danceability, y = playlist_name)) + geom_point(size = .7, color = )

rr #A PLAYLIST CLASSICOS DO FUNK POSSUI O MENOR DP E A MAIOR MEDIA DE

rr musicas %>% group_by(playlist_name) %>% summarise(energy_mean = mean(energy)) %>% ggplot(aes(x = energy_mean, y = playlist_name)) + geom_point(color = , size = .5)

rr #A PLAYLIST CLASSICOS DO FUNK TAMBÉM POSSUI UMA DAS MEDIAS DE ENERGIA MAIS ALTAS

rr musicas %>% group_by(playlist_name) %>% summarise(valence_mean = mean(valence)) %>% ggplot(aes(x = valence_mean, y = playlist_name)) + geom_point(color = , size = .7)

rr #A PLAYLIST CLASSICOS DO FUNK TEM UMA DAS MELHORES MEDIAS DE

rr musicas %>% group_by(playlist_name) %>% ggplot(mapping = aes(y = danceability, x = \, color = playlist_name)) + geom_quasirandom(alpha = 0.4)

rr #!!!!!!!!!!!COMO GIRAR O NOME? NO Y FICA RUIM #AS MELHORES MUSICAS SAO DA PLAYLIST CLASSICOS DO FUNK

rr musicas %>% filter(playlist_name == do Funk) %>% summarise(max(danceability, track_name))

rr musicas %>% filter(playlist_name == do Funk) %>% summarise(max(energy, track_name))

rr musicas %>% filter(playlist_name == do Funk) %>% summarise(max(valence, track_name))

rr musicas %>% group_by(playlist_name) %>% ggplot(mapping = aes(x = track_popularity, y = playlist_name, color = playlist_name)) + geom_jitter()

rr #A PLAYLIST POP UP POSSUI AS TRACKS MAIS POPULARES

rr musicas %>% group_by(playlist_name) %>% count(playlistPopularity = mean(track_popularity)) %>% ggplot(mapping = aes(x = playlistPopularity, y = playlist_name)) + geom_point(color = , size = .4)

rr #AQUI, VERIFICA-SE QUE A PLAYLIST POP UP POSSUI A MAIOR POPULARIDADE ENTRE ESSAS PLAYLISTS, POR MEDIA DE POPULARIDADE DE CADA TRACK

rr musicas %>% group_by(playlist_name) %>% ggplot(mapping = aes(y = playlist_name, x = track_popularity, fill = playlist_name)) + geom_boxplot() + geom_jitter(color = , size = 0.5, alpha = 0.5)

rr playlistPopularity = musicas %>% group_by(playlist_name) %>% count(playlistPopularity = mean(track_popularity))

ggplot() + geom_point(data = musicas, mapping = aes(x = track_popularity, y = playlist_name), alpha = 0.3, size = 0.5) + geom_point(data = playlistPopularity, mapping = aes(x = playlistPopularity, y = playlist_name), color = , size = 0.6) + labs(x = nome, y = nome, title = )

rr musicas %>% group_by(playlist_name) %>% summarise(sdPlaylistPopularity = sd(track_popularity)) %>% arrange(sdPlaylistPopularity)

rr musicas %>% ggplot(aes(x = energy, y = valence), color = playlist_name) + geom_point(alpha = .6, size = .5) + facet_wrap(~ playlist_name)

rr musicas %>% group_by(playlist_name) %>% ggplot(mapping = aes(x = valence, y = energy, color = playlist_name)) + geom_point(alpha = 0.8, size = 0.8)

RELACAO POSITIVA E LINEAR. A ENERGIA INFLUENCIA A FELICIDADE QUE A MUSICA TRANSMITE?

rr musicas %>% summarise(coeficiente = cor(valence, energy, method = )) r #APARENTEMENTE NAO APRESENTA UMA CORRELACAO MUITO BOA

APARENTEMENTE NAO APRESENTA UMA CORRELACAO MUITO ALTA.

Uma coisa curiosa a ser analisada é se as tracks com selo EXPLICIT possuem uma maior valencia, energia ou “dançabilidade”. Vejamos:

rr musicas %>% ggplot(mapping = aes(x = , y = energy, color = playlist_name)) + geom_quasirandom() + facet_wrap(~ track_explicit)

rr musicas %>% group_by(track_explicit) %>% summarise(mean = mean(energy), median = median(energy))

Aparentemente as musicas terem selo EXPLICIT não influenciam na energia que a música passa, mas vejamos como se comporta com a valencia:

rr musicas %>% ggplot(mapping = aes(x = , y = valence, color = playlist_name)) + geom_quasirandom() + facet_wrap(~ track_explicit)

rr musicas %>% group_by(track_explicit) %>% summarise(mean = mean(valence), median = median(valence))

As músicas com selo EXPLICIT também não influenciam a felicidade que passam.

rr musicas %>% ggplot(mapping = aes(x = , y = danceability, color = playlist_name)) + geom_quasirandom() + facet_wrap(~ track_explicit)

rr musicas %>% group_by(track_explicit) %>% summarise(mean = mean(danceability), median = median(danceability), sd = sd(danceability))

As musicas com tag EXPLICIT possuem media e mediana levemente maiores que as que não possuem, assim como um desvio padrão menor, então TALVEZ haja alguma relação.

LS0tCnRpdGxlOiAiUXVhbCBhIG1lbGhvciBwbGF5bGlzdCBwcmVzZW50ZSBub3MgZGFkb3M/IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ2JlZXN3YXJtKQptdXNpY2FzID0gcmVhZF9jc3YoImh0dHBzOi8vZ2l0aHViLmNvbS9jaWVuY2lhZGVkYWRvcy11ZmNnL3Zpcy1jYW5jb2VzL3Jhdy9tYXN0ZXIvZGF0YS9wbGF5bGlzdHMtc3BvdGlmeS5jc3YiKQpgYGAKCiMjIyBPcyBkYWRvcyAgCgpPcyBkYWRvcyBhIHNlcmVtIGFuYWxpc2Fkb3MgdmVtIGRvIFNwb3RpZnkuIEZvcmFtIGZpbHRyYWRhcyBtw7pzaWNhcyBkZSBwbGF5bGlzdHMgc2VsZWNpb25hZGFzLCBlIGNhZGEgbcO6c2ljYSBwb3NzdWkgdsOhcmlvcyBhdHJpYnV0b3MsIGNvbW86IGRhY2VhYmlsaXR5KGRhbmNlYWJpbGlkYWRlPyksIGVuZXJnaWEsIHZhbGVuY2UgZSBvdXRyYXMgY2FyYWN0ZXLDrXN0aWNhcyBwcm92YXZlbG1lbnRlIGludGVyZXNzYW50ZXMuICAKVmVqYW1vcyBvcyBkYWRvczoKCmBgYHtyfQptdXNpY2FzCmBgYAoKIyMjIEFuw6FsaXNlIGLDoXNpY2EKClZlamFtb3MgYWdvcmEgYSBtw6lkaWEgZSBtZWRpYW5hIGRhIGRhbmNlYWJpbGl0eSBkZSBjYWRhIHBsYXlsaXN0LCB2ZXJpZmljYW5kbyBlc3NlcyBkYWRvcyBhIHBhcnRpciBkZSBjYWRhIG3DunNpY2EgcGVydGVuY2VudGUuIAoKYGBge3J9CmRhbmNlYWJpbGl0eV9tZWFuID0gbXVzaWNhcyAlPiUKICBncm91cF9ieShwbGF5bGlzdF9uYW1lKSAlPiUKICBjb3VudChkYW5jZWFiaWxpdHlfbWVhbiA9IG1lYW4oZGFuY2VhYmlsaXR5KSkKCmRhbmNlYWJpbGl0eV9tZWRpYW4gPSBtdXNpY2FzICU+JQogIGdyb3VwX2J5KHBsYXlsaXN0X25hbWUpICU+JQogIGNvdW50KGRhbmNlYWJpbGl0eV9tZWRpYW4gPSBtZWRpYW4oZGFuY2VhYmlsaXR5KSkKCmdncGxvdCgpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gbXVzaWNhcywKICAgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IGRhbmNlYWJpbGl0eSwgeSA9IHBsYXlsaXN0X25hbWUpLAogICAgICAgICAgICAgYWxwaGEgPSAuMywKICAgICAgICAgICAgIHNpemUgPSAuNSkgKwogIGdlb21fcG9pbnQoZGF0YSA9IGRhbmNlYWJpbGl0eV9tZWFuLAogICAgICAgICAgICAgbWFwcGluZyA9IGFlcyh4ID0gZGFuY2VhYmlsaXR5X21lYW4sIHkgPSBwbGF5bGlzdF9uYW1lKSwKICAgICAgICAgICAgIGNvbG9yID0gInJlZCIsCiAgICAgICAgICAgICBzaXplID0gMC43KSArIAogIGdlb21fcG9pbnQoZGF0YSA9IGRhbmNlYWJpbGl0eV9tZWRpYW4sIG1hcHBpbmcgPSBhZXMoeCA9IGRhbmNlYWJpbGl0eV9tZWRpYW4sIHkgPSBwbGF5bGlzdF9uYW1lKSwKICAgICAgICAgICAgIGNvbG9yID0gImJsdWUiLAogICAgICAgICAgICAgc2l6ZSA9IDAuNykgKwogIGxhYnMoeCA9ICJEYW5jZWFiaWxpZGFkZSIsCiAgICAgICB5ID0gIk5vbWUgZGEgcGxheWxpc3QiLAogICAgICAgdGl0bGUgPSAiRGFuY2VhYmlsaWRhZGUgeCBOb21lIGRhIHBsYXlsaXN0IiwKICAgICAgIHN1YnRpdGxlID0gIlBvbnRvIGF6dWwgPSBNZWRpYW5hICAgICAgUG9udG8gdmVybWVsaG8gPSBNw6lkaWEiKQoKCmBgYAoKQSBwbGF5bGlzdCBDbMOhc3NpY29zIGRvIEZ1bmsgcG9zc3VpIGEgbWFpb3IgbcOpZGlhIGUgYSBtYWlvciBkaXNwZXJzw6NvLCBvdSBzZWphLCBvcyBkYWRvcyBlc3TDo28gZGlzdGFudGVzIGRhIG3DqWRpYS4gIApPbGhhbmRvIHBhcmEgYSBwbGF5bGlzdCBCb25kZSBkbyBGdW5rLCB2ZW1vcyBxdWUgYSBtZXNtYSBwb3NzdWkgYSBzZWd1bmRhIG1haW9yIG3DqWRpYSwgZSBvIGRlc3ZpbyBwYWRyw6NvIGVzdMOhIGJlbSBwcsOzeGltby4gIAoKIyMjIyBNw6lkaWFzIGVtIG7Dum1lcm8KCmBgYHtyfQptdXNpY2FzICU+JSAKICBncm91cF9ieShwbGF5bGlzdF9uYW1lKSAlPiUKICBzdW1tYXJpc2UoZGFuY2VhYmlsaXR5X21lYW4gPSBtZWFuKGRhbmNlYWJpbGl0eSkpICU+JQogIGFycmFuZ2UoLWRhbmNlYWJpbGl0eV9tZWFuKQpgYGAKCmBgYHtyfQptdXNpY2FzICU+JSAgZ3JvdXBfYnkocGxheWxpc3RfbmFtZSkgJT4lCiAgc3VtbWFyaXNlKHNkX2RhbmNlYWJpbGl0eSA9IHNkKGRhbmNlYWJpbGl0eSkpICU+JQogIGdncGxvdChhZXMoeCA9IHNkX2RhbmNlYWJpbGl0eSwgeSA9IHBsYXlsaXN0X25hbWUpKSArCiAgZ2VvbV9wb2ludChzaXplID0gLjcsIGNvbG9yID0gInJlZCIpCiNBIFBMQVlMSVNUIENMQVNTSUNPUyBETyBGVU5LIFBPU1NVSSBPIE1FTk9SIERQIEUgQSBNQUlPUiBNRURJQSBERSAiREFOQ0FCSUxJREFERSIKYGBgCgpgYGB7cn0KbXVzaWNhcyAlPiUgCiAgZ3JvdXBfYnkocGxheWxpc3RfbmFtZSkgJT4lCiAgc3VtbWFyaXNlKGVuZXJneV9tZWFuID0gbWVhbihlbmVyZ3kpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBlbmVyZ3lfbWVhbiwgeSA9IHBsYXlsaXN0X25hbWUpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJyZWQiLCBzaXplID0gLjUpCiNBIFBMQVlMSVNUIENMQVNTSUNPUyBETyBGVU5LIFRBTULDiU0gUE9TU1VJIFVNQSBEQVMgTUVESUFTIERFIEVORVJHSUEgTUFJUyBBTFRBUwpgYGAKCmBgYHtyfQptdXNpY2FzICU+JSAKICBncm91cF9ieShwbGF5bGlzdF9uYW1lKSAlPiUKICBzdW1tYXJpc2UodmFsZW5jZV9tZWFuID0gbWVhbih2YWxlbmNlKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsZW5jZV9tZWFuLCB5ID0gcGxheWxpc3RfbmFtZSkpICsKICBnZW9tX3BvaW50KGNvbG9yID0gInJlZCIsIHNpemUgPSAuNykKI0EgUExBWUxJU1QgQ0xBU1NJQ09TIERPIEZVTksgVEVNIFVNQSBEQVMgTUVMSE9SRVMgTUVESUFTIERFICJWQUxFTkNFIgpgYGAKCmBgYHtyfQptdXNpY2FzICU+JSBncm91cF9ieShwbGF5bGlzdF9uYW1lKSAlPiUKICBnZ3Bsb3QobWFwcGluZyA9IGFlcyh5ID0gZGFuY2VhYmlsaXR5LCB4ID0gIiIsIGNvbG9yID0gcGxheWxpc3RfbmFtZSkpICsgCiAgZ2VvbV9xdWFzaXJhbmRvbShhbHBoYSA9IDAuNCkKIyEhISEhISEhISEhQ09NTyBHSVJBUiBPIE5PTUU/IE5PIFkgRklDQSBSVUlNCiNBUyBNRUxIT1JFUyBNVVNJQ0FTIFNBTyBEQSBQTEFZTElTVCBDTEFTU0lDT1MgRE8gRlVOSwpgYGAKCmBgYHtyfQptdXNpY2FzICU+JQogIGZpbHRlcihwbGF5bGlzdF9uYW1lID09ICJDbMOhc3NpY29zIGRvIEZ1bmsiKSAlPiUKICBzdW1tYXJpc2UobWF4KGRhbmNlYWJpbGl0eSwgdHJhY2tfbmFtZSkpCmBgYAoKYGBge3J9Cm11c2ljYXMgJT4lCiAgZmlsdGVyKHBsYXlsaXN0X25hbWUgPT0gIkNsw6Fzc2ljb3MgZG8gRnVuayIpICU+JQogIHN1bW1hcmlzZShtYXgoZW5lcmd5LCB0cmFja19uYW1lKSkKYGBgCmBgYHtyfQptdXNpY2FzICU+JQogIGZpbHRlcihwbGF5bGlzdF9uYW1lID09ICJDbMOhc3NpY29zIGRvIEZ1bmsiKSAlPiUKICBzdW1tYXJpc2UobWF4KHZhbGVuY2UsIHRyYWNrX25hbWUpKQpgYGAKCmBgYHtyfQptdXNpY2FzICU+JQogIGdyb3VwX2J5KHBsYXlsaXN0X25hbWUpICU+JQogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSB0cmFja19wb3B1bGFyaXR5LCB5ID0gcGxheWxpc3RfbmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBwbGF5bGlzdF9uYW1lKSkgKwogIGdlb21faml0dGVyKCkKI0EgUExBWUxJU1QgUE9QIFVQIFBPU1NVSSBBUyBUUkFDS1MgTUFJUyBQT1BVTEFSRVMKYGBgCgpgYGB7cn0KbXVzaWNhcyAlPiUgCiAgZ3JvdXBfYnkocGxheWxpc3RfbmFtZSkgJT4lCiAgY291bnQocGxheWxpc3RQb3B1bGFyaXR5ID0gbWVhbih0cmFja19wb3B1bGFyaXR5KSkgJT4lCiAgZ2dwbG90KG1hcHBpbmcgPSBhZXMoeCA9IHBsYXlsaXN0UG9wdWxhcml0eSwgeSA9IHBsYXlsaXN0X25hbWUpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJyZWQiLCBzaXplID0gLjQpCiNBUVVJLCBWRVJJRklDQS1TRSBRVUUgQSBQTEFZTElTVCBQT1AgVVAgUE9TU1VJIEEgTUFJT1IgUE9QVUxBUklEQURFIEVOVFJFIEVTU0FTIFBMQVlMSVNUUywgUE9SIE1FRElBIERFIFBPUFVMQVJJREFERSBERSBDQURBIFRSQUNLCmBgYApgYGB7cn0KbXVzaWNhcyAlPiUgCiAgZ3JvdXBfYnkocGxheWxpc3RfbmFtZSkgJT4lCiAgZ2dwbG90KG1hcHBpbmcgPSBhZXMoeSA9IHBsYXlsaXN0X25hbWUsIHggPSB0cmFja19wb3B1bGFyaXR5LCAKICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gcGxheWxpc3RfbmFtZSkpICsKICBnZW9tX2JveHBsb3QoKSArIAogIGdlb21faml0dGVyKGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjUpCgpgYGAKCmBgYHtyfQpwbGF5bGlzdFBvcHVsYXJpdHkgPSBtdXNpY2FzICU+JQogIGdyb3VwX2J5KHBsYXlsaXN0X25hbWUpICU+JQogIGNvdW50KHBsYXlsaXN0UG9wdWxhcml0eSA9IG1lYW4odHJhY2tfcG9wdWxhcml0eSkpCiAgCmdncGxvdCgpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gbXVzaWNhcywgCiAgICAgICAgICAgICBtYXBwaW5nID0gYWVzKHggPSB0cmFja19wb3B1bGFyaXR5LCB5ID0gcGxheWxpc3RfbmFtZSksIAogICAgICAgICAgICAgYWxwaGEgPSAwLjMsIHNpemUgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gcGxheWxpc3RQb3B1bGFyaXR5LCAKICAgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IHBsYXlsaXN0UG9wdWxhcml0eSwgeSA9IHBsYXlsaXN0X25hbWUpLCAKICAgICAgICAgICAgIGNvbG9yID0gInJlZCIsIHNpemUgPSAwLjYpICAgKyBsYWJzKHggPSAidW0gbm9tZSIsIHkgPSAib3V0cm8gbm9tZSIsIHRpdGxlID0gIm5vbWVkb2dyYWZpY28iKQoKYGBgCmBgYHtyfQptdXNpY2FzICU+JQogIGdyb3VwX2J5KHBsYXlsaXN0X25hbWUpICU+JQogIHN1bW1hcmlzZShzZFBsYXlsaXN0UG9wdWxhcml0eSA9IHNkKHRyYWNrX3BvcHVsYXJpdHkpKSAlPiUKICBhcnJhbmdlKHNkUGxheWxpc3RQb3B1bGFyaXR5KQpgYGAKCmBgYHtyfQptdXNpY2FzICU+JQogIGdncGxvdChhZXMoeCA9IGVuZXJneSwgeSA9IHZhbGVuY2UpLCBjb2xvciA9IHBsYXlsaXN0X25hbWUpICsKICBnZW9tX3BvaW50KGFscGhhID0gLjYsIHNpemUgPSAuNSkgKwogIGZhY2V0X3dyYXAofiBwbGF5bGlzdF9uYW1lKQpgYGAKCmBgYHtyfQptdXNpY2FzICU+JQogIGdyb3VwX2J5KHBsYXlsaXN0X25hbWUpICU+JQogIGdncGxvdChtYXBwaW5nID0gYWVzKHggPSB2YWxlbmNlLCB5ID0gZW5lcmd5LCBjb2xvciA9IHBsYXlsaXN0X25hbWUpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuOCwgc2l6ZSA9IDAuOCkKYGBgCgpSRUxBQ0FPIFBPU0lUSVZBIEUgTElORUFSLgpBIEVORVJHSUEgSU5GTFVFTkNJQSBBIEZFTElDSURBREUgUVVFIEEgTVVTSUNBIFRSQU5TTUlURT8KCmBgYHtyfQptdXNpY2FzICU+JQogIHN1bW1hcmlzZShjb2VmaWNpZW50ZSA9IGNvcih2YWxlbmNlLCBlbmVyZ3ksIG1ldGhvZCA9ICJwZWFyc29uIikpCmBgYAoKQVBBUkVOVEVNRU5URSBOQU8gQVBSRVNFTlRBIFVNQSBDT1JSRUxBQ0FPIE1VSVRPIEFMVEEuCgpVbWEgY29pc2EgY3VyaW9zYSBhIHNlciBhbmFsaXNhZGEgw6kgc2UgYXMgdHJhY2tzIGNvbSBzZWxvIEVYUExJQ0lUIHBvc3N1ZW0gdW1hIG1haW9yIHZhbGVuY2lhLCBlbmVyZ2lhIG91ICJkYW7Dp2FiaWxpZGFkZSIuIFZlamFtb3M6CgpgYGB7cn0KbXVzaWNhcyAlPiUKICBnZ3Bsb3QobWFwcGluZyA9IGFlcyh4ID0gIk11c2ljYXMiLCAKICAgICAgICAgICAgICAgICAgICAgICB5ID0gZW5lcmd5LCAKICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHBsYXlsaXN0X25hbWUpKSArCiAgZ2VvbV9xdWFzaXJhbmRvbSgpICsgCiAgZmFjZXRfd3JhcCh+IHRyYWNrX2V4cGxpY2l0KQpgYGAKCmBgYHtyfQptdXNpY2FzICU+JQogIGdyb3VwX2J5KHRyYWNrX2V4cGxpY2l0KSAlPiUKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oZW5lcmd5KSwgCiAgICAgICAgICAgIG1lZGlhbiA9IG1lZGlhbihlbmVyZ3kpKQpgYGAKCkFwYXJlbnRlbWVudGUgYXMgbXVzaWNhcyB0ZXJlbSBzZWxvIEVYUExJQ0lUIG7Do28gaW5mbHVlbmNpYW0gbmEgZW5lcmdpYSBxdWUgYSBtw7pzaWNhIHBhc3NhLCBtYXMgdmVqYW1vcyBjb21vIHNlIGNvbXBvcnRhIGNvbSBhIHZhbGVuY2lhOgoKYGBge3J9Cm11c2ljYXMgJT4lCiAgZ2dwbG90KG1hcHBpbmcgPSBhZXMoeCA9ICJNdXNpY2FzIiwgeSA9IHZhbGVuY2UsIGNvbG9yID0gcGxheWxpc3RfbmFtZSkpICsKICBnZW9tX3F1YXNpcmFuZG9tKCkgKyBmYWNldF93cmFwKH4gdHJhY2tfZXhwbGljaXQpCmBgYAoKYGBge3J9Cm11c2ljYXMgJT4lCiAgZ3JvdXBfYnkodHJhY2tfZXhwbGljaXQpICU+JQogIHN1bW1hcmlzZShtZWFuID0gbWVhbih2YWxlbmNlKSwgCiAgICAgICAgICAgIG1lZGlhbiA9IG1lZGlhbih2YWxlbmNlKSkKYGBgCgpBcyBtw7pzaWNhcyBjb20gc2VsbyBFWFBMSUNJVCB0YW1iw6ltIG7Do28gaW5mbHVlbmNpYW0gYSBmZWxpY2lkYWRlIHF1ZSBwYXNzYW0uCgpgYGB7cn0KbXVzaWNhcyAlPiUKICBnZ3Bsb3QobWFwcGluZyA9IGFlcyh4ID0gIk11c2ljYXMiLCB5ID0gZGFuY2VhYmlsaXR5LCBjb2xvciA9IHBsYXlsaXN0X25hbWUpKSArCiAgZ2VvbV9xdWFzaXJhbmRvbSgpICsgZmFjZXRfd3JhcCh+IHRyYWNrX2V4cGxpY2l0KQpgYGAKCmBgYHtyfQptdXNpY2FzICU+JQogIGdyb3VwX2J5KHRyYWNrX2V4cGxpY2l0KSAlPiUKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oZGFuY2VhYmlsaXR5KSwgCiAgICAgICAgICAgIG1lZGlhbiA9IG1lZGlhbihkYW5jZWFiaWxpdHkpLAogICAgICAgICAgICBzZCA9IHNkKGRhbmNlYWJpbGl0eSkpCmBgYAoKQXMgbXVzaWNhcyBjb20gdGFnIEVYUExJQ0lUIHBvc3N1ZW0gbWVkaWEgZSBtZWRpYW5hIGxldmVtZW50ZSBtYWlvcmVzIHF1ZSBhcyBxdWUgbsOjbyBwb3NzdWVtLCBhc3NpbSBjb21vIHVtIGRlc3ZpbyBwYWRyw6NvIG1lbm9yLCBlbnTDo28gVEFMVkVaIGhhamEgYWxndW1hIHJlbGHDp8Ojby4=