Regression

流浪汪星人 怎麼做 data package?

https://data.gov.tw/dataset/25602 98年度台灣地區各縣市流浪狗數調查結果?

https://animal.coa.gov.tw/html/index_06_0621_dog.html

require(dplyr)
require(ggplot2)
#https://www.dropbox.com/s/t8doe35f3o2we2m/dogs.txt?dl=0
# big5 data 用 file - reopen with encoding - save with encoding
dogs <- read.table("../../../data/txt/dogs.txt", header = T, fileEncoding="utf8")
qplot(computerR, adoptedR, data=dogs)
lm.model <- lm(adoptedR~computerR, data=dogs, x =TRUE)
summary(lm.model)
#plot(computerR~adoptedR, data=dogs)
ggplot(dogs, aes(x = computerR, y = adoptedR)) + 
  geom_point() +
  stat_smooth(method = "lm", col = "red")
anova(lm.model)
plot(lm.model)
resid <- lm.model$residuals
# using ggplot: https://rpubs.com/therimalaya/43190
# check normality
shapiro.test(resid)
dogs1 <- dogs[-c(1,5)]
round(cor(dogs1),2); head(dogs1)
pairs(dogs1)
# or using ggplot2 
#install.package('GGally')
require(GGally)
Loading required package: GGally
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2

Attaching package: ‘GGally’

The following object is masked from ‘package:dplyr’:

    nasa
ggpairs(dogs1[, c(2, 4:6)])
Error in ggpairs(dogs1[, c(2, 4:6)]) : 找不到物件 'dogs1'

比較紐約狗

The nycdogs package contains three datasets, nyc_license, nyc_bites, and nyc_zips. They contain, respectively, data on all licensed dogs in New York city, data on reported dog bites in New York city, and geographical data for New York city at the zip code level.

  • nycdogs is a data package, bundling several datasets into a convenient format.
#devtools::install_github("kjhealy/nycdogs")
library(tidyverse)
library(sf)
require(nycdogs)
Loading required package: nycdogs

To look at the tibble that contains the licensing data

nyc_license
  • use the nyc_zips object to create a map of, for example, the prevalence of dog names by zip code:
nyc_coco <- nyc_license %>%
    group_by(zip_code, animal_name) %>%
    tally() %>%
    mutate(freq = n / sum(n),
           pct = round(freq*100, 2)) %>%
    filter(animal_name == "Coco")

nyc_coco
coco_map <- left_join(nyc_zips, nyc_coco)
Joining, by = "zip_code"
## Map theme
theme_nymap <- function(base_size=9, base_family="") {
    require(grid)
    theme_bw(base_size=base_size, base_family=base_family) %+replace%
        theme(axis.line=element_blank(),
              axis.text=element_blank(),
              axis.ticks=element_blank(),
              axis.title=element_blank(),
              panel.background=element_blank(),
              panel.border=element_blank(),
              panel.grid=element_blank(),
              panel.spacing=unit(0, "lines"),
              plot.background=element_blank(),
              legend.justification = c(0,0),
              legend.position = c(0.1, 0.6), 
              legend.direction = "horizontal"
        )
}
  • 可以作地圖
coco_map %>% ggplot(mapping = aes(fill = pct)) +
    geom_sf(color = "gray80", size = 0.1) +
    scale_fill_viridis_c(option = "A") +
    labs(fill = "Percent of Licensed Dogs") +
  annotate(geom = "text", x = -74.145, y = 40.82, 
           label = "Where's Coco?", size = 6) + 
    theme_nymap() + 
    guides(fill = guide_legend(title.position = "top", 
                               label.position = "bottom"))


Topic modeling

require(quanteda)
require(quanteda.corpora)
require(lubridate)
require(topicmodels)
corp_news <- download('data_corpus_guardian')
嘗試 URL 'https://www.dropbox.com/s/7mu92jzodpq11zc/data_corpus_guardian.rds?dl=1&v=1'
Content type 'application/binary' length 11347175 bytes (10.8 MB)
==================================================
downloaded 10.8 MB
corp_news_subset <- corpus_subset(corp_news, 'date' >= 2016)
ndoc(corp_news_subset)
[1] 6000

記得在文本處理中,採 non-position 的作法,要先把 text 表徵成 document-term matrix (document-feature matrix)。 where rows represent documents, and columns terms. Each cell is a count of how many times the term occurs in the document. Terms are typically words, but could be any n-gram of interest.同時也要(在一些預設之下)決定如何前處理你的資料。

dfmat_news <- dfm(corp_news, remove_punct = TRUE, remove = stopwords('en')) %>% 
    dfm_remove(c('*-time', '*-timeUpdated', 'GMT', 'BST')) %>% 
    dfm_trim(min_termfreq = 0.95, termfreq_type = "quantile", 
             max_docfreq = 0.1, docfreq_type = "prop")

dfmat_news <- dfmat_news[ntoken(dfmat_news) > 0,]
dtm <- convert(dfmat_news, to = "topicmodels")
lda <- LDA(dtm, k = 10)
terms(lda, 10)
      Topic 1    Topic 2    Topic 3     Topic 4       Topic 5        
 [1,] "hospital" "online"   "nhs"       "climate"     "officers"     
 [2,] "violence" "game"     "food"      "china"       "investigation"
 [3,] "died"     "games"    "workers"   "chinese"     "justice"      
 [4,] "doctors"  "music"    "funding"   "leadership"  "inquiry"      
 [5,] "medical"  "users"    "housing"   "paris"       "allegations"  
 [6,] "child"    "google"   "income"    "agreement"   "trial"        
 [7,] "parents"  "apple"    "scheme"    "development" "officer"      
 [8,] "woman"    "internet" "customers" "elections"   "charges"      
 [9,] "mental"   "facebook" "cuts"      "trade"       "criminal"     
[10,] "mother"   "video"    "data"      "politics"    "alleged"      
      Topic 6         Topic 7        Topic 8      Topic 9    Topic 10   
 [1,] "energy"        "trump"        "mps"        "syria"    "markets"  
 [2,] "water"         "clinton"      "australia"  "military" "prices"   
 [3,] "climate"       "republican"   "referendum" "refugees" "shares"   
 [4,] "gas"           "sanders"      "australian" "isis"     "oil"      
 [5,] "project"       "obama"        "corbyn"     "attacks"  "sales"    
 [6,] "land"          "donald"       "labor"      "russian"  "rate"     
 [7,] "environmental" "cruz"         "tory"       "syrian"   "banks"    
 [8,] "green"         "2016"         "2016"       "forces"   "euro"     
 [9,] "coal"          "hillary"      "mp"         "russia"   "investors"
[10,] "food"          "presidential" "osborne"    "islamic"  "quarter"  
docvars(dfmat_news, 'topic') <- topics(lda)
head(topics(lda), 20)
text136751 text118588  text45146  text93623 text136585  text65682 text107174 
         4          2         10          8          8          5          3 
 text22792  text32425 text139163 text169133  text90312 text153451  text31104 
         5          9          3          1          6          5          3 
text163885  text81309 text157885  text99128 text173244  text27905 
         6         10          2          9          6          9 

應用

多觀摩一些專案,例如

Every year since 1947, representatives of UN member states gather at the annual sessions of the United Nations General Assembly. The centrepiece of each session is the General Debate. This is a forum at which leaders and other senior officials deliver statements that present their government’s perspective on the major issues in world politics. These statements are akin to the annual legislative state-of-the-union addresses in domestic politics. This new dataset, the UN General Debate Corpus (UNGDC), introduces the corpus of texts of General Debate statements from 1970 (Session 25) to 2016 (Session 71). Basic visualization and corpus exploration tools are available here.

  • 用莎翁名劇玩看看

完整從 http://shakespeare.mit.edu 抓檔過程在此。但若理解不需要再無故排放 CO2。資料在此。說明參見:https://m-clark.github.io/text-analysis-with-R/topic-modeling.html

可以參考 Julia Silge (text mining with R 作者) 最近做的 side project 福爾摩斯的故事

# `stm` require `glmnet`, which requieres R >= 3.6.0 so you would have to update R to be able to install it library(stm)
# check your R version with `version`, download latest R (3.6.2), install and restart Rstudio

#library(stm)



----------------------------------------

# Word embeddings

https://cbail.github.io/textasdata/word2vec/rmarkdown/word2vec.html
LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIE1vZGVsaW5nLiB3ZWVrMTUiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCgoKIyBSZWdyZXNzaW9uCgrmtYHmtarmsarmmJ/kurog5oCO6bq85YGaIGRhdGEgcGFja2FnZT8KCmh0dHBzOi8vZGF0YS5nb3YudHcvZGF0YXNldC8yNTYwMgo5OOW5tOW6puWPsOeBo+WcsOWNgOWQhOe4o+W4gua1gea1queLl+aVuOiqv+afpee1kOaenD8KCmh0dHBzOi8vYW5pbWFsLmNvYS5nb3YudHcvaHRtbC9pbmRleF8wNl8wNjIxX2RvZy5odG1sCgoKCgotIGBjb21wdXRlclJgOiDlkITnuKPluILlubPlnYfmr48xMDDlgIvlrrbluq3nmoTpm7vohabmlbjnm64KLSBgZ3JhZHVhdGVgOiDlkITnuKPluILnoJTnqbbmiYDnlaLmpa3ogIXkurrmlbgKCgpgYGB7cn0KcmVxdWlyZShkcGx5cikKcmVxdWlyZShnZ3Bsb3QyKQojaHR0cHM6Ly93d3cuZHJvcGJveC5jb20vcy90OGRvZTM1ZjNvMndlMm0vZG9ncy50eHQ/ZGw9MAojIGJpZzUgZGF0YSDnlKggZmlsZSAtIHJlb3BlbiB3aXRoIGVuY29kaW5nIC0gc2F2ZSB3aXRoIGVuY29kaW5nCmRvZ3MgPC0gcmVhZC50YWJsZSgiLi4vLi4vLi4vZGF0YS90eHQvZG9ncy50eHQiLCBoZWFkZXIgPSBULCBmaWxlRW5jb2Rpbmc9InV0ZjgiKQpxcGxvdChjb21wdXRlclIsIGFkb3B0ZWRSLCBkYXRhPWRvZ3MpCgpgYGAKCgoKLSDov7Tmrbjkv4LmlbjoqIjnrpfmjqjoq5YKYGBge3J9CmxtLm1vZGVsIDwtIGxtKGFkb3B0ZWRSfmNvbXB1dGVyUiwgZGF0YT1kb2dzLCB4ID1UUlVFKQpzdW1tYXJ5KGxtLm1vZGVsKQoKYGBgCgoKYGBge3J9CiNwbG90KGNvbXB1dGVyUn5hZG9wdGVkUiwgZGF0YT1kb2dzKQpnZ3Bsb3QoZG9ncywgYWVzKHggPSBjb21wdXRlclIsIHkgPSBhZG9wdGVkUikpICsgCiAgZ2VvbV9wb2ludCgpICsKICBzdGF0X3Ntb290aChtZXRob2QgPSAibG0iLCBjb2wgPSAicmVkIikKYGBgCgoKCi0g57Ch5Zau57ea5oCn6L+05q2455qEIEFOT1ZBIOihqOagvApgYGB7cn0KYW5vdmEobG0ubW9kZWwpCmBgYAoKCi0g5q6Y5beu5YiG5p6QIChSZXNpZHVhbHMgYW5hbHlzaXMpCgpgYGB7cn0KcGxvdChsbS5tb2RlbCkKcmVzaWQgPC0gbG0ubW9kZWwkcmVzaWR1YWxzCiMgdXNpbmcgZ2dwbG90OiBodHRwczovL3JwdWJzLmNvbS90aGVyaW1hbGF5YS80MzE5MAojIGNoZWNrIG5vcm1hbGl0eQpzaGFwaXJvLnRlc3QocmVzaWQpCgpgYGAKCgoKLSBDb3JyZWxhdGlvbiBtYXRyaXgg6YG45Y+W6Kej6YeL6K6K5pW4CgpgYGB7cn0KZG9nczEgPC0gZG9nc1stYygxLDUpXQpyb3VuZChjb3IoZG9nczEpLDIpOyBoZWFkKGRvZ3MxKQpgYGAKCgoKYGBge3J9CnBhaXJzKGRvZ3MxKQojIG9yIHVzaW5nIGdncGxvdDIgCmBgYAoKCmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlKCdHR2FsbHknKQpyZXF1aXJlKEdHYWxseSkKZ2dwYWlycyhkb2dzMVssIGMoMiwgNDo2KV0pCgpgYGAKCiMjIOavlOi8g+e0kOe0hOeLlwoKClRoZSBgbnljZG9nc2AgcGFja2FnZSBjb250YWlucyB0aHJlZSBkYXRhc2V0cywgYG55Y19saWNlbnNlLCBueWNfYml0ZXNgLCBhbmQgYG55Y196aXBzYC4gVGhleSBjb250YWluLCByZXNwZWN0aXZlbHksIGRhdGEgb24gYWxsIGxpY2Vuc2VkIGRvZ3MgaW4gTmV3IFlvcmsgY2l0eSwgZGF0YSBvbiByZXBvcnRlZCBkb2cgYml0ZXMgaW4gTmV3IFlvcmsgY2l0eSwgYW5kIGdlb2dyYXBoaWNhbCBkYXRhIGZvciBOZXcgWW9yayBjaXR5IGF0IHRoZSB6aXAgY29kZSBsZXZlbC4KCi0gbnljZG9ncyBpcyBhIGRhdGEgcGFja2FnZSwgYnVuZGxpbmcgc2V2ZXJhbCBkYXRhc2V0cyBpbnRvIGEgY29udmVuaWVudCBmb3JtYXQuCgpgYGB7cn0KI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigia2poZWFseS9ueWNkb2dzIikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2YpCnJlcXVpcmUobnljZG9ncykKYGBgCgoKVG8gbG9vayBhdCB0aGUgdGliYmxlIHRoYXQgY29udGFpbnMgdGhlIGxpY2Vuc2luZyBkYXRhCgpgYGB7cn0KbnljX2xpY2Vuc2UKYGBgCgoKCi0gdXNlIHRoZSBgbnljX3ppcHNgIG9iamVjdCB0byBjcmVhdGUgYSBtYXAgb2YsIGZvciBleGFtcGxlLCB0aGUgcHJldmFsZW5jZSBvZiBkb2cgbmFtZXMgYnkgemlwIGNvZGU6CgoKYGBge3J9Cm55Y19jb2NvIDwtIG55Y19saWNlbnNlICU+JQogICAgZ3JvdXBfYnkoemlwX2NvZGUsIGFuaW1hbF9uYW1lKSAlPiUKICAgIHRhbGx5KCkgJT4lCiAgICBtdXRhdGUoZnJlcSA9IG4gLyBzdW0obiksCiAgICAgICAgICAgcGN0ID0gcm91bmQoZnJlcSoxMDAsIDIpKSAlPiUKICAgIGZpbHRlcihhbmltYWxfbmFtZSA9PSAiQ29jbyIpCgpueWNfY29jbwpgYGAKCgpgYGB7cn0KY29jb19tYXAgPC0gbGVmdF9qb2luKG55Y196aXBzLCBueWNfY29jbykKIyMgTWFwIHRoZW1lCnRoZW1lX255bWFwIDwtIGZ1bmN0aW9uKGJhc2Vfc2l6ZT05LCBiYXNlX2ZhbWlseT0iIikgewogICAgcmVxdWlyZShncmlkKQogICAgdGhlbWVfYncoYmFzZV9zaXplPWJhc2Vfc2l6ZSwgYmFzZV9mYW1pbHk9YmFzZV9mYW1pbHkpICUrcmVwbGFjZSUKICAgICAgICB0aGVtZShheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgIGF4aXMudGV4dD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgYXhpcy50aXRsZT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgcGFuZWwuYmFja2dyb3VuZD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICBwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICBwYW5lbC5zcGFjaW5nPXVuaXQoMCwgImxpbmVzIiksCiAgICAgICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwwKSwKICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuMSwgMC42KSwgCiAgICAgICAgICAgICAgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIgogICAgICAgICkKfQpgYGAKCi0g5Y+v5Lul5L2c5Zyw5ZyWCgoKYGBge3J9CmNvY29fbWFwICU+JSBnZ3Bsb3QobWFwcGluZyA9IGFlcyhmaWxsID0gcGN0KSkgKwogICAgZ2VvbV9zZihjb2xvciA9ICJncmF5ODAiLCBzaXplID0gMC4xKSArCiAgICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAiQSIpICsKICAgIGxhYnMoZmlsbCA9ICJQZXJjZW50IG9mIExpY2Vuc2VkIERvZ3MiKSArCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeCA9IC03NC4xNDUsIHkgPSA0MC44MiwgCiAgICAgICAgICAgbGFiZWwgPSAiV2hlcmUncyBDb2NvPyIsIHNpemUgPSA2KSArIAogICAgdGhlbWVfbnltYXAoKSArIAogICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUucG9zaXRpb24gPSAidG9wIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbC5wb3NpdGlvbiA9ICJib3R0b20iKSkKYGBgCgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgVG9waWMgbW9kZWxpbmcgCgotIOW+nuaWh+S7tuS4reaJvuWHuua9m+WcqOOAjOS4u+mhjOOAjeeahOe1seioiOaooeWei+OAggoKLSBMREEg55qEW+aVuOWtuOaOqOWwjl0o5Y6f5paH77yaQmxlaSwgRGF2aWQgTS4sIEFuZHJldyBZLiBOZywgYW5kIE1pY2hhZWwgSS4gSm9yZGFuLiAyMDAzLiAiTGF0ZW50IERpcmljaGxldCBBbGxvY2F0aW9uLiIgVGhlIEpvdXJuYWwgb2YgTWFjaGluZSBMZWFybmluZyBSZXNlYXJjaCAzKDEpOiA5OTMtMTAyMi4pCgotIOWFiOeUqCBgcXVhbnRlZGFgIOeahOS+i+WtkOe3tOe/kueci+eci+OAggoKYGBge3J9CnJlcXVpcmUocXVhbnRlZGEpCnJlcXVpcmUocXVhbnRlZGEuY29ycG9yYSkKcmVxdWlyZShsdWJyaWRhdGUpCnJlcXVpcmUodG9waWNtb2RlbCkKYGBgCgoKLSDkuIvovInoi7HlnIvooZvloLHos4fmlpnvvIzmjJHpgbggMjAxNiDlh7rniYjnmoTmlrDogZ4KCmBgYHtyfQpjb3JwX25ld3MgPC0gZG93bmxvYWQoJ2RhdGFfY29ycHVzX2d1YXJkaWFuJykKY29ycF9uZXdzX3N1YnNldCA8LSBjb3JwdXNfc3Vic2V0KGNvcnBfbmV3cywgJ2RhdGUnID49IDIwMTYpCm5kb2MoY29ycF9uZXdzX3N1YnNldCkKYGBgCgoKCj4g6KiY5b6X5Zyo5paH5pys6JmV55CG5Lit77yM5o6hIG5vbi1wb3NpdGlvbiDnmoTkvZzms5XvvIzopoHlhYjmioogdGV4dCDooajlvrXmiJAgYGRvY3VtZW50LXRlcm0gbWF0cml4YCAoYGRvY3VtZW50LWZlYXR1cmUgbWF0cml4YCnjgIIgd2hlcmUgcm93cyByZXByZXNlbnQgZG9jdW1lbnRzLCBhbmQgY29sdW1ucyB0ZXJtcy4gRWFjaCBjZWxsIGlzIGEgY291bnQgb2YgaG93IG1hbnkgdGltZXMgdGhlIHRlcm0gb2NjdXJzIGluIHRoZSBkb2N1bWVudC4gVGVybXMgYXJlIHR5cGljYWxseSB3b3JkcywgYnV0IGNvdWxkIGJlIGFueSBuLWdyYW0gb2YgaW50ZXJlc3Qu5ZCM5pmC5Lmf6KaB77yI5Zyo5LiA5Lqb6aCQ6Kit5LmL5LiL77yJ5rG65a6a5aaC5L2V5YmN6JmV55CG5L2g55qE6LOH5paZ44CCCgoKLSDku6XpgJnlgIvkvovlrZDkvoboqqrvvIzliY3omZXnkIbljIXmi6zkuobnp7vpmaTlip/og73oqZ7jgIHmqJnpu57nrKbomZ/vvJvmib7lh7rpoa/okZfnibnlvrXoqZ7kvZzngrogKipmZWF0dXJlcyoqICB0aGUgdG9wIDUlIG9mIHRoZSBtb3N0IGZyZXF1ZW50IGZlYXR1cmVzIChgbWluX3Rlcm1mcmVxID0gMC45NWApIHRoYXQgYXBwZWFyIGluIGxlc3MgdGhhbiAxMCUgb2YgYWxsIGRvY3VtZW50cyAoYG1heF9kb2NmcmVxID0gMC4xYCkgdXNpbmcgYGRmbV90cmltKClgIHRvIGZvY3VzIG9uIGNvbW1vbiBidXQgZGlzdGluZ3Vpc2hpbmcgZmVhdHVyZXMuCgpgYGB7cn0KZGZtYXRfbmV3cyA8LSBkZm0oY29ycF9uZXdzLCByZW1vdmVfcHVuY3QgPSBUUlVFLCByZW1vdmUgPSBzdG9wd29yZHMoJ2VuJykpICU+JSAKICAgIGRmbV9yZW1vdmUoYygnKi10aW1lJywgJyotdGltZVVwZGF0ZWQnLCAnR01UJywgJ0JTVCcpKSAlPiUgCiAgICBkZm1fdHJpbShtaW5fdGVybWZyZXEgPSAwLjk1LCB0ZXJtZnJlcV90eXBlID0gInF1YW50aWxlIiwgCiAgICAgICAgICAgICBtYXhfZG9jZnJlcSA9IDAuMSwgZG9jZnJlcV90eXBlID0gInByb3AiKQoKZGZtYXRfbmV3cyA8LSBkZm1hdF9uZXdzW250b2tlbihkZm1hdF9uZXdzKSA+IDAsXQoKYGBgCgoKLSDmlr3ooYzkuLvpoYzmqKHlnosgdG9waWMgbW9kZWxpbmcgKOS9v+eUqCBgdG9waWNtb2RlbGAg5aWX5Lu25Lit55qEIGBMREFgKe+8jOmgkOWFiOaxuuWumuS4u+mhjOaVuOmHjyAkayQg77yI6ZyA6KaB5LiA6bue5pmC6ZaT77yJCgpgYGB7cn0KZHRtIDwtIGNvbnZlcnQoZGZtYXRfbmV3cywgdG8gPSAidG9waWNtb2RlbHMiKQpsZGEgPC0gTERBKGR0bSwgayA9IDEwKQpgYGAKCgotIOW7uuWlveaooeWei+S5i+W+jO+8jOWwseWPr+S7peeci+eci+mAmeS6m+S4u+mhjOS9v+eUqOS6huWTquS6m+mHjeimgeipnuW9mQoKYGBge3J9CnRlcm1zKGxkYSwgMTApCmBgYAoKLSDkuZ/lj6/ku6XlhLLlrZjotbfkvobnlbbmiJDmlofku7bnmoTlvozoqK3os4fmlpkKCmBgYHtyfQpkb2N2YXJzKGRmbWF0X25ld3MsICd0b3BpYycpIDwtIHRvcGljcyhsZGEpCmhlYWQodG9waWNzKGxkYSksIDIwKQoKYGBgCgotIOaAjum6vOimluimuuWMlumAmeS6m+S4u+mhjOeahOWIhuS9iO+8nwpgTERBdmlzYChodHRwczovL2dpdGh1Yi5jb20vY3BzaWV2ZXJ0L0xEQXZpcy8pCgohW10oaHR0cHM6Ly9rbm93bGVkZ2VyLnJiaW5kLmlvL2ltZy9MREF2aXMucG5nKQoKCiMjIOaHieeUqAoK5aSa6KeA5pGp5LiA5Lqb5bCI5qGI77yM5L6L5aaCCgotIFvoga/lkIjlnIsgR2VuZXJhbCBEZWJhdGUgQ29ycHVzXShodHRwczovL2RhdGEud29ybGQvaWFuL3VuaXRlZC1uYXRpb25zLWdlbmVyYWwtZGViYXRlLWNvcnB1cynjgILlj6/ku6XlhYjmib7nnIvnnIvmmK/lkKbliKXkurrlt7LntpPmioros4fmlpnomZXnkIblpb3kuobvvIzlpoIgW2thZ2dsZSDlubPlj7BdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vdW5pdGVkbmF0aW9ucy91bi1nZW5lcmFsLWRlYmF0ZXMjdW4tZ2VuZXJhbC1kZWJhdGVzLmNzdinjgILnlKjkuLvpoYzmqKHlnovkvobnnIvnnIvkuI3lkIzlubTku6PvvIxb5ZCE5ZyL5Luj6KGo6YO95Zyo6KuH5LuA6bq844CM5Li76aGM44CN44CCXShodHRwOi8vdW5nZC5zbWlraGF5bG92Lm5ldC8pCiAgLSDlu7bkvLjvvJrlj7DngaPlnIvmnIPvvJ/kuI3lkIznuKPluILnmoTorbDmnIPos6roqaLvvJ8KCgo+IEV2ZXJ5IHllYXIgc2luY2UgMTk0NywgcmVwcmVzZW50YXRpdmVzIG9mIFVOIG1lbWJlciBzdGF0ZXMgZ2F0aGVyIGF0IHRoZSBhbm51YWwgc2Vzc2lvbnMgb2YgdGhlIFVuaXRlZCBOYXRpb25zIEdlbmVyYWwgQXNzZW1ibHkuIFRoZSBjZW50cmVwaWVjZSBvZiBlYWNoIHNlc3Npb24gaXMgdGhlIEdlbmVyYWwgRGViYXRlLiBUaGlzIGlzIGEgZm9ydW0gYXQgd2hpY2ggbGVhZGVycyBhbmQgb3RoZXIgc2VuaW9yIG9mZmljaWFscyBkZWxpdmVyIHN0YXRlbWVudHMgdGhhdCBwcmVzZW50IHRoZWlyIGdvdmVybm1lbnTigJlzIHBlcnNwZWN0aXZlIG9uIHRoZSBtYWpvciBpc3N1ZXMgaW4gd29ybGQgcG9saXRpY3MuIFRoZXNlIHN0YXRlbWVudHMgYXJlIGFraW4gdG8gdGhlIGFubnVhbCBsZWdpc2xhdGl2ZSBzdGF0ZS1vZi10aGUtdW5pb24gYWRkcmVzc2VzIGluIGRvbWVzdGljIHBvbGl0aWNzLiBUaGlzIG5ldyBkYXRhc2V0LCB0aGUgVU4gR2VuZXJhbCBEZWJhdGUgQ29ycHVzIChVTkdEQyksIGludHJvZHVjZXMgdGhlIGNvcnB1cyBvZiB0ZXh0cyBvZiBHZW5lcmFsIERlYmF0ZSBzdGF0ZW1lbnRzIGZyb20gMTk3MCAoU2Vzc2lvbiAyNSkgdG8gMjAxNiAoU2Vzc2lvbiA3MSkuIEJhc2ljIHZpc3VhbGl6YXRpb24gYW5kIGNvcnB1cyBleHBsb3JhdGlvbiB0b29scyBhcmUgYXZhaWxhYmxlIGhlcmUuCgoKCgoKLSDnlKjojo7nv4HlkI3liofnjqnnnIvnnIsKCuWujOaVtOW+niBodHRwOi8vc2hha2VzcGVhcmUubWl0LmVkdSDmipPmqpTpgY7nqItb5Zyo5q2kXShodHRwczovL20tY2xhcmsuZ2l0aHViLmlvL3RleHQtYW5hbHlzaXMtd2l0aC1SL3NoYWtlc3BlYXJlLmh0bWwjc2hha2VzcGVhcmUtc3RhcnQtdG8tZmluaXNoKeOAguS9huiLpeeQhuino+S4jemcgOimgeWGjeeEoeaVheaOkuaUviBDTzLjgIJb6LOH5paZ5Zyo5q2kXShodHRwczovL2dpdGh1Yi5jb20vbS1jbGFyay90ZXh0LWFuYWx5c2lzLXdpdGgtUi9ibG9iL21hc3Rlci9kYXRhL3NoYWtlc19kdG1fc3RlbW1lZC5SRGF0YSnjgILoqqrmmI7lj4PopovvvJpodHRwczovL20tY2xhcmsuZ2l0aHViLmlvL3RleHQtYW5hbHlzaXMtd2l0aC1SL3RvcGljLW1vZGVsaW5nLmh0bWwKCgotIOmAsumajueahOS4u+mhjOaooeWeizogU3RydWN0dXJhbCB0b3BpYyBtb2RlbCAoW3dpdGggYHN0bWAgcGFja2FnZV0oaHR0cHM6Ly93d3cuc3RydWN0dXJhbHRvcGljbW9kZWwuY29tLykpIAoK5Y+v5Lul5Y+D6ICDIEp1bGlhIFNpbGdlICh0ZXh0IG1pbmluZyB3aXRoIFIg5L2c6ICFKSDmnIDov5HlgZrnmoQgc2lkZSBwcm9qZWN0IFvnpo/niL7mkanmlq/nmoTmlYXkuotdKGh0dHBzOi8vanVsaWFzaWxnZS5jb20vYmxvZy9zaGVybG9jay1ob2xtZXMtc3RtLykKCgpgYGB7cn0KIyBgc3RtYCByZXF1aXJlIGBnbG1uZXRgLCB3aGljaCByZXF1aWVyZXMgUiA+PSAzLjYuMCBzbyB5b3Ugd291bGQgaGF2ZSB0byB1cGRhdGUgUiB0byBiZSBhYmxlIHRvIGluc3RhbGwgaXQgbGlicmFyeShzdG0pCiMgY2hlY2sgeW91ciBSIHZlcnNpb24gd2l0aCBgdmVyc2lvbmAsIGRvd25sb2FkIGxhdGVzdCBSICgzLjYuMiksIGluc3RhbGwgYW5kIHJlc3RhcnQgUnN0dWRpbwoKI2xpYnJhcnkoc3RtKQoKCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIFdvcmQgZW1iZWRkaW5ncwoKaHR0cHM6Ly9jYmFpbC5naXRodWIuaW8vdGV4dGFzZGF0YS93b3JkMnZlYy9ybWFya2Rvd24vd29yZDJ2ZWMuaHRtbAo=