library(WikidataR)
library(rtoot)

Récupération des toots de Plazi

library(rtoot)
auth_setup() # authentification de l'utilisateur
"mastodon.social"
What type of token do you want? 

1: public
2: user
2
Token of type "user" for instance mastodon.social is valid
<mastodon bearer token> for instance: mastodon.social of type: user 
# documentation on Rtoot is available here https://www.rdocumentation.org/packages/rtoot/versions/0.3.4
id <- search_accounts("plazi_species")
print(id)
df <- get_account_statuses("109284766172512524", limit = 400L)
head(df$content, 1)
library(stringr)
library(dplyr)

Attachement du package : ‘dplyr’

Les objets suivants sont masqués depuis ‘package:stats’:

    filter, lag

Les objets suivants sont masqués depuis ‘package:base’:

    intersect, setdiff, setequal, union
pattern <- "(?<=</p><p>)(.*?)(?=</p><p>)"
df <- df %>%
  mutate(species_name = str_extract(content, pattern))  
#str_to_sentence(country_discovery$country_of_discovery)
head(df, 10)

items problématiques : https://mastodon.green/@plazi_species/113917317111853431 https://mastodon.green/@plazi_species/113916252425285117

library(stringr)
library(dplyr)

df <- df %>%
  filter(!str_detect(species_name, 'Treatment:'))
head(df, 10)
NA
library(purrr)
library(rvest)
df$content <- map_chr(df$content, function(x) {
  tryCatch({
    read_html(x) %>% html_text()
  }, error = function(e) {
    # renvoie le message original si une erreur est rencontrée
    return(x)
  })
})
head(df$content, 10)
 [1] "#NewSpecies!New running crab spiders from #china just ran in:Sinodromus fujianensisTreatment: treatment.plazi.org/id/41059653-9C0C-5EFD-91D5-09E2C260578BPublication: doi.org/10.3897/zookeys.1221.137930#ZooKeys_Journal #SinodromusFujianensis#FAIRdata#science #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #invertebrates #arachnology #arachnids #spider"                                       
 [2] "#NewSpecies!New marine goby from #taiwan:Callogobius aquilusTreatment: treatment.plazi.org/id/03BF244D-9543-FFB8-33D7-2193FE85F892Publication: doi.org/10.11646/zootaxa.5550.1.16#Zootaxa #CallogobiusAquilus#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #fish #TeamFish #ichthyology #goby"                                                             
 [3] "#NewSpecies!New beetle from #korea just came in:Viettherchnus orszulikiTreatment: treatment.plazi.org/id/1523AC3A-F82E-2968-BDE9-86E7FAF0F83BPublication: doi.org/10.11646/zootaxa.5519.4.7#Zootaxa #ViettherchnusOrszuliki#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #invertebrates #entomology #insects #coleoptera #beetles"                         
 [4] "#NewSpecies!New freshwater crayfish from #indonesia just surfaced:Cherax pulverulentusTreatment: treatment.plazi.org/id/03DB8794-3B48-037D-419A-44C726243339Publication: doi.org/10.11646/zootaxa.5566.3.4#Zootaxa #CheraxPulverulentus#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #invertebrates #arthropods #crustacea #crayfish #freshwater"          
 [5] "#NewSpecies!New harlequin frog from #peru just jumped in:Atelopus histrionicusTreatment: treatment.plazi.org/id/03E48797-FF95-FF8E-4081-7BA8FD38F9A7Publication: doi.org/10.11646/zootaxa.5571.1.1#Zootaxa #AtelopusHistrionicus#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #herpetology #herps #amphibia #frogs #harlequin"                             
 [6] "#NewSpecies!New planthopper from #vietnam:Pseudochoutagus lindaeTreatment: treatment.plazi.org/id/CB3887FB-7173-620A-FB48-F995FC1CFAC4Publication: doi.org/10.5852/ejt.2024.975.2769#ejtaxonomy #PseudochoutagusLindae#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #invertebrates #entomology #insects #hemiptera #planthopper"                           
 [7] "#NewSpecies!New snake from #ethiopia just sidled in:Boaedon broadleyiTreatment: treatment.plazi.org/id/03D887FD-FFDC-6D7D-FF18-0F58FE64CBCCPublication: doi.org/10.11646/zootaxa.5569.1.4 #Zootaxa #BoaedonBroadleyi#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #herpetology #herps #reptilia #snake"                                                    
 [8] "#NewSpecies!New rove beetle from #china just roved by:Hesperus pengiTreatment: treatment.plazi.org/id/612C87D2-185E-FFE0-EEFC-27C3FEFAAB1BPublication: doi.org/10.11646/zootaxa.5474.5.6#Zootaxa #HesperusPengi#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #invertebrates #entomology #insects #coleoptera #beetles #rovebeetles"                        
 [9] "#NewSpecies!New snakehead from #myanmar just surfaced:Channa pyrophthalmusTreatment: treatment.plazi.org/id/0386C114-1644-FFE5-FF67-FBFF3F97EFADPublication: doi.org/10.26107/RBZ-2024-0001#RafflesBulletinOfZoology #ChannaPyrophthalmus#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #animals #fish #TeamFish #fishofmastodon #fishfriday #ichthyology #snakehead"
[10] "#NewSpeciesA newly discovered fungus from #china for #FungiFriday:Trichoderma strophariensisTreatment: treatment.plazi.org/id/22D20AFB-BC41-5495-B40A-EB53EFFBE5CBPublication: doi.org/10.3897/mycokeys.110.134154#MycoKeys #TrichodermaStrophariensis#FAIRdata#science #OA #openaccess #biology #taxonomy #ecology #biodiversity #nature #wildlife #conservation #fungi #mushrooms #mycology"                                    
library(stringr)
pattern <- "(?<=doi.org/)(.*?)(?=#)"
df <- df %>%
  mutate(doi = str_extract(content, pattern))  
#str_to_sentence(country_discovery$country_of_discovery)
head(df, 10)
library(stringr)
pattern <- "(?<=from #)(\\w+)"
df <- df %>%
  mutate(
    country_of_discovery = str_extract(content, pattern),
    country_of_discovery = str_to_title(country_of_discovery) 
  )
head(df, 10)
df <- select(df, species_name, country_of_discovery, doi)
head(df,10)

Propriétés :

location of discovery : P189 described by source : P1343

library(WikidataR)
library(WikidataQueryServiceR)
See ?WDQS for resources on Wikidata Query Service and SPARQL

Attachement du package : ‘WikidataQueryServiceR’

Les objets suivants sont masqués depuis ‘package:WikidataR’:

    get_example, query_wikidata
library(dplyr)

Attachement du package : ‘dplyr’

Les objets suivants sont masqués depuis ‘package:stats’:

    filter, lag

Les objets suivants sont masqués depuis ‘package:base’:

    intersect, setdiff, setequal, union
# URL to this query on Wikidata query service
countries_qid <- query_wikidata('
SELECT ?item ?itemLabel 
WHERE
{

     ?item wdt:P31 wd:Q6256 .
           
              SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}')
Rows: 194 Columns: 2── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (2): item, itemLabel
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
qid_no_url <- gsub('[http://www.wikidata.org/entity/]', '', countries_qid$item) # extrait le qid de la colonne item et ajoute une colonne au tableau des pays
countries_qid <- as.data.frame(countries_qid) # fait de countries_qid2 un dataframe afin que mutate puisse fonctionner (ligne suivante)
countries_qid <- countries_qid %>% 
  mutate(
    qid=qid_no_url,
    country_of_discovery = paste(countries_qid$itemLabel)
    )
        
head(countries_qid, 10)

df1 <- merge(df, countries_qid, by = "country_of_discovery")
df1 <- select(df1, species_name, qid, country_of_discovery, doi)
head(df1, 10)
NA

get_qid <- function(name) {
  results <- find_item(name)  # Search for the name in Wikidata
  if (length(results) > 0) {
    return(results[[1]]$id)  # Extract QID of the first result
  } else {
    return(NA)  # Return NA if no result is found
  }
}
df1$QID_items <- sapply(df1$species_name, get_qid)
head(df1, 10)
NA
NA
NA

df2  <- df1[is.na(df1$QID_items),]
head(df2, 10)
NA
#df3 : items déjà créésdans Wikdata
df3  <- df1[!is.na(df1$QID_items),] # filter(df1 =="NA") won't do it (see here https://stackoverflow.com/questions/7980622/subset-of-rows-containing-na-missing-values-in-a-chosen-column-of-a-data-frame#7980765)
head(df3, 10)
NA

création d’un tableau à partir des données relatives aux éléments à créer


df2_sub <- slice_head(df2, n = 3, by = NULL)
df2_sub <- df2_sub %>% 
  mutate(
    row_num = row_number(),
    item = paste0("CREATE_",row_num),
    Len = paste0(df2_sub$species_name),
    P189 = paste0(df2_sub$qid),
    P356 = paste0(df2_sub$doi),
  )
df2_sub <- select(df2_sub, item, species_name, Len, P189, P356)
print(df2_sub)
NA
library(tidyr)
library(stringr)

import <- df2_sub %>% 
  select(item, 
         matches("^L", ignore.case = FALSE), 
         matches("^D", ignore.case = FALSE), 
         # if there are some Sitelinks to other Wiki pages
         #matches("^S", ignore.case = FALSE), 
         matches("^P", ignore.case = FALSE)) %>% 
  pivot_longer(cols = 2:last_col(), names_to = "property", values_to = "value") %>% 
  # fix helper with two columns referring to the same property
  mutate(property = str_remove(property, "_.*")) %>% 
  filter(!is.na(value)) %>% 
  distinct()

print(import)
library(WikidataR)
write_wikidata(
  items        = import$item,
  properties   = import$property,
  values       = import$value,
  format       = "api",
  api.username = "Udo_Bolano", 
  api.token    = "$2y$10$qy3Omn7Dn4DaXAD1QBWcs.dNjrKwlrc.cFX2rVZMyQ7oYt2xYSmJS", #REDACTED#
  )

api.token = mettre ici le token récupéré sur https://quickstatements.toolforge.org/#/user

voir mode d’emploi ici : https://katharinabrunner.de/2022/06/wikibase-wikidata-etl-data-import-with-r/

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkoV2lraWRhdGFSKQpsaWJyYXJ5KHJ0b290KQoKYGBgCgojIFLDqWN1cMOpcmF0aW9uIGRlcyB0b290cyBkZSBQbGF6aSAKCmBgYHtyIGF1dGhlbnRpY2F0aW9uIG9uIE1hc3RvZG9uIGFuZCBpZGVudGlmaWNhdGlvbiBvZiBQbGF6aSBNYXN0b2RvbiBhY2NvdW50fQpsaWJyYXJ5KHJ0b290KQphdXRoX3NldHVwKCkgIyBhdXRoZW50aWZpY2F0aW9uIGRlIGwndXRpbGlzYXRldXIKIyBkb2N1bWVudGF0aW9uIG9uIFJ0b290IGlzIGF2YWlsYWJsZSBoZXJlIGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9ydG9vdC92ZXJzaW9ucy8wLjMuNAppZCA8LSBzZWFyY2hfYWNjb3VudHMoInBsYXppX3NwZWNpZXMiKQpwcmludChpZCkKYGBgCgpgYGB7ciBjb2xsZWN0aW9uIG9mIFBMYXppXCdzIHRvb3RzfQpkZiA8LSBnZXRfYWNjb3VudF9zdGF0dXNlcygiMTA5Mjg0NzY2MTcyNTEyNTI0IiwgbGltaXQgPSA0MDBMKQpoZWFkKGRmJGNvbnRlbnQsIDEpCmBgYAoKCmBgYHtyIHLDqWN1cMOpcmF0aW9uIGVzcMOoY2V9CmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShkcGx5cikKcGF0dGVybiA8LSAiKD88PTwvcD48cD4pKC4qPykoPz08L3A+PHA+KSIKZGYgPC0gZGYgJT4lCiAgbXV0YXRlKHNwZWNpZXNfbmFtZSA9IHN0cl9leHRyYWN0KGNvbnRlbnQsIHBhdHRlcm4pKSAgCiNzdHJfdG9fc2VudGVuY2UoY291bnRyeV9kaXNjb3ZlcnkkY291bnRyeV9vZl9kaXNjb3ZlcnkpCmhlYWQoZGYsIDEwKQpgYGAKCgoKaXRlbXMgcHJvYmzDqW1hdGlxdWVzIDogCmh0dHBzOi8vbWFzdG9kb24uZ3JlZW4vQHBsYXppX3NwZWNpZXMvMTEzOTE3MzE3MTExODUzNDMxCmh0dHBzOi8vbWFzdG9kb24uZ3JlZW4vQHBsYXppX3NwZWNpZXMvMTEzOTE2MjUyNDI1Mjg1MTE3CgoKYGBge3IgZXhjbHVzaW9uIGVzcMOoY2VzIHbDqWfDqXRhbGVzIH0KbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KGRwbHlyKQoKZGYgPC0gZGYgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KHNwZWNpZXNfbmFtZSwgJ1RyZWF0bWVudDonKSkKaGVhZChkZiwgMTApCgpgYGAKCgoKCgoKYGBge3IgaHRtbCB0YWdzIGRlbGV0aW9uIGluIHRvb3QgY29udGVudCB9CmxpYnJhcnkocHVycnIpCmxpYnJhcnkocnZlc3QpCmRmJGNvbnRlbnQgPC0gbWFwX2NocihkZiRjb250ZW50LCBmdW5jdGlvbih4KSB7CiAgdHJ5Q2F0Y2goewogICAgcmVhZF9odG1sKHgpICU+JSBodG1sX3RleHQoKQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgIyByZW52b2llIGxlIG1lc3NhZ2Ugb3JpZ2luYWwgc2kgdW5lIGVycmV1ciBlc3QgcmVuY29udHLDqWUKICAgIHJldHVybih4KQogIH0pCn0pCmhlYWQoZGYkY29udGVudCwgMTApCmBgYApgYGB7ciByw6ljdXDDqXJhdGlvbiBET0lzfQpsaWJyYXJ5KHN0cmluZ3IpCnBhdHRlcm4gPC0gIig/PD1kb2kub3JnLykoLio/KSg/PSMpIgpkZiA8LSBkZiAlPiUKICBtdXRhdGUoZG9pID0gc3RyX2V4dHJhY3QoY29udGVudCwgcGF0dGVybikpICAKI3N0cl90b19zZW50ZW5jZShjb3VudHJ5X2Rpc2NvdmVyeSRjb3VudHJ5X29mX2Rpc2NvdmVyeSkKaGVhZChkZiwgMTApCmBgYAoKCmBgYHtyIHLDqWN1cMOpcmF0aW9uIHBheXMgZGUgZMOpY291dmVydGV9CmxpYnJhcnkoc3RyaW5ncikKcGF0dGVybiA8LSAiKD88PWZyb20gIykoXFx3KykiCmRmIDwtIGRmICU+JQogIG11dGF0ZSgKICAgIGNvdW50cnlfb2ZfZGlzY292ZXJ5ID0gc3RyX2V4dHJhY3QoY29udGVudCwgcGF0dGVybiksCiAgICBjb3VudHJ5X29mX2Rpc2NvdmVyeSA9IHN0cl90b190aXRsZShjb3VudHJ5X29mX2Rpc2NvdmVyeSkgCiAgKQpoZWFkKGRmLCAxMCkKYGBgCgpgYGB7ciBzw6lsZWN0aW9ubmVyIGxlcyBjb2xvbm5lcyBpbXBvcnRhbnRlcyBwb3VyIG5vdXMgfQpkZiA8LSBzZWxlY3QoZGYsIHNwZWNpZXNfbmFtZSwgY291bnRyeV9vZl9kaXNjb3ZlcnksIGRvaSkKaGVhZChkZiwxMCkKYGBgCgojIFByb3ByacOpdMOpcyA6IAoKbG9jYXRpb24gb2YgZGlzY292ZXJ5IDogW1AxODldKGh0dHBzOi8vd3d3Lndpa2lkYXRhLm9yZy93aWtpL1Byb3BlcnR5OlAxODkpCmRlc2NyaWJlZCBieSBzb3VyY2UgOiBbUDEzNDNdKGh0dHBzOi8vd3d3Lndpa2lkYXRhLm9yZy93aWtpL1Byb3BlcnR5OlAxMzQzKQoKCgoKCmBgYHtyIGdldCB0aGUgbGlzdCBvZiBhbGwgY291bnRyaWVzIGluIGVuZ2xpc2ggd2l0aCB0aGVpciBxaWR9CmxpYnJhcnkoV2lraWRhdGFSKQpsaWJyYXJ5KFdpa2lkYXRhUXVlcnlTZXJ2aWNlUikKbGlicmFyeShkcGx5cikKIyBVUkwgdG8gdGhpcyBxdWVyeSBvbiBXaWtpZGF0YSBxdWVyeSBzZXJ2aWNlCmNvdW50cmllc19xaWQgPC0gcXVlcnlfd2lraWRhdGEoJwpTRUxFQ1QgP2l0ZW0gP2l0ZW1MYWJlbCAKV0hFUkUKewoKICAgICA/aXRlbSB3ZHQ6UDMxIHdkOlE2MjU2IC4KICAgICAgICAgICAKICAgICAgICAgICAgICBTRVJWSUNFIHdpa2liYXNlOmxhYmVsIHsgYmQ6c2VydmljZVBhcmFtIHdpa2liYXNlOmxhbmd1YWdlICJlbiIuIH0KfScpCnFpZF9ub191cmwgPC0gZ3N1YignW2h0dHA6Ly93d3cud2lraWRhdGEub3JnL2VudGl0eS9dJywgJycsIGNvdW50cmllc19xaWQkaXRlbSkgIyBleHRyYWl0IGxlIHFpZCBkZSBsYSBjb2xvbm5lIGl0ZW0gZXQgYWpvdXRlIHVuZSBjb2xvbm5lIGF1IHRhYmxlYXUgZGVzIHBheXMKY291bnRyaWVzX3FpZCA8LSBhcy5kYXRhLmZyYW1lKGNvdW50cmllc19xaWQpICMgZmFpdCBkZSBjb3VudHJpZXNfcWlkMiB1biBkYXRhZnJhbWUgYWZpbiBxdWUgbXV0YXRlIHB1aXNzZSBmb25jdGlvbm5lciAobGlnbmUgc3VpdmFudGUpCmNvdW50cmllc19xaWQgPC0gY291bnRyaWVzX3FpZCAlPiUgCiAgbXV0YXRlKAogICAgcWlkPXFpZF9ub191cmwsCiAgICBjb3VudHJ5X29mX2Rpc2NvdmVyeSA9IHBhc3RlKGNvdW50cmllc19xaWQkaXRlbUxhYmVsKQogICAgKQogICAgICAgIApoZWFkKGNvdW50cmllc19xaWQsIDEwKQpgYGAKCmBgYHtyIGpvbmN0aW9uIGRlcyBkZXV4IHRhYmxlYXUgfQoKZGYxIDwtIG1lcmdlKGRmLCBjb3VudHJpZXNfcWlkLCBieSA9ICJjb3VudHJ5X29mX2Rpc2NvdmVyeSIpCmRmMSA8LSBzZWxlY3QoZGYxLCBzcGVjaWVzX25hbWUsIHFpZCwgY291bnRyeV9vZl9kaXNjb3ZlcnksIGRvaSkKaGVhZChkZjEsIDEwKQoKYGBgCgpgYGB7ciByw6ljdXDDqXJhdGlvbiBkZXMgaXRlbXMgcXVpIGV4aXN0ZW50IGTDqWrDoCBkYW5zIFdpa2lkYXRhfQoKZ2V0X3FpZCA8LSBmdW5jdGlvbihuYW1lKSB7CiAgcmVzdWx0cyA8LSBmaW5kX2l0ZW0obmFtZSkgICMgU2VhcmNoIGZvciB0aGUgbmFtZSBpbiBXaWtpZGF0YQogIGlmIChsZW5ndGgocmVzdWx0cykgPiAwKSB7CiAgICByZXR1cm4ocmVzdWx0c1tbMV1dJGlkKSAgIyBFeHRyYWN0IFFJRCBvZiB0aGUgZmlyc3QgcmVzdWx0CiAgfSBlbHNlIHsKICAgIHJldHVybihOQSkgICMgUmV0dXJuIE5BIGlmIG5vIHJlc3VsdCBpcyBmb3VuZAogIH0KfQpkZjEkUUlEX2l0ZW1zIDwtIHNhcHBseShkZjEkc3BlY2llc19uYW1lLCBnZXRfcWlkKQpoZWFkKGRmMSwgMTApCgoKCmBgYAoKYGBge3IgcsOpY3Vww6lyYXRpb24gZGVzIGl0ZW1zIHF1aSBuZSBzb250IHBhcyBwcsOpc2VudHMgZGFucyBXaWtpZGF0YX0KI2RmMiA6IGl0ZW1zIMOgIGNyw6llciBkYW5zIFdpa2RhdGEKZGYyICA8LSBkZjFbaXMubmEoZGYxJFFJRF9pdGVtcyksXSAjIGZpbHRlcihkZjEgPT0iTkEiKSB3b24ndCBkbyBpdCAoc2VlIGhlcmUgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzk4MDYyMi9zdWJzZXQtb2Ytcm93cy1jb250YWluaW5nLW5hLW1pc3NpbmctdmFsdWVzLWluLWEtY2hvc2VuLWNvbHVtbi1vZi1hLWRhdGEtZnJhbWUjNzk4MDc2NSkKaGVhZChkZjIsIDEwKQoKYGBgCgpgYGB7ciByw6ljdXDDqXJhdGlvbiBkZXMgaXRlbXMgcXVpIG5lIHNvbnQgZMOpasOgIHByw6lzZW50cyBkYW5zIFdpa2lkYXRhfQojZGYzIDogaXRlbXMgZMOpasOgIGNyw6nDqXNkYW5zIFdpa2RhdGEKZGYzICA8LSBkZjFbIWlzLm5hKGRmMSRRSURfaXRlbXMpLF0gIyBmaWx0ZXIoZGYxID09Ik5BIikgd29uJ3QgZG8gaXQgKHNlZSBoZXJlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzc5ODA2MjIvc3Vic2V0LW9mLXJvd3MtY29udGFpbmluZy1uYS1taXNzaW5nLXZhbHVlcy1pbi1hLWNob3Nlbi1jb2x1bW4tb2YtYS1kYXRhLWZyYW1lIzc5ODA3NjUpCmhlYWQoZGYzLCAxMCkKCmBgYAoKCiMgY3LDqWF0aW9uIGQndW4gdGFibGVhdSDDoCBwYXJ0aXIgZGVzIGRvbm7DqWVzIHJlbGF0aXZlcyBhdXggw6lsw6ltZW50cyDDoCBjcsOpZXIKCmBgYHtyIHNlbGVjdGlvbiBkZXMgdHJvaXMgaXRlbXMgZGUgdMOqdGUgZGUgbGEgbGlzdGUgZGYyKX0KCmRmMl9zdWIgPC0gc2xpY2VfaGVhZChkZjIsIG4gPSAzLCBieSA9IE5VTEwpCmRmMl9zdWIgPC0gZGYyX3N1YiAlPiUgCiAgbXV0YXRlKAogICAgcm93X251bSA9IHJvd19udW1iZXIoKSwKICAgIGl0ZW0gPSBwYXN0ZTAoIkNSRUFURV8iLHJvd19udW0pLAogICAgTGVuID0gcGFzdGUwKGRmMl9zdWIkc3BlY2llc19uYW1lKSwKICAgIFAxODkgPSBwYXN0ZTAoZGYyX3N1YiRxaWQpLAogICAgUDM1NiA9IHBhc3RlMChkZjJfc3ViJGRvaSksCiAgKQpkZjJfc3ViIDwtIHNlbGVjdChkZjJfc3ViLCBpdGVtLCBzcGVjaWVzX25hbWUsIExlbiwgUDE4OSwgUDM1NikKcHJpbnQoZGYyX3N1YikKCmBgYAoKYGBge3IgY29kZSBkZSBLYXRoYXJpbmEgQnJ1bm5lcn0KbGlicmFyeSh0aWR5cikKbGlicmFyeShzdHJpbmdyKQoKaW1wb3J0IDwtIGRmMl9zdWIgJT4lIAogIHNlbGVjdChpdGVtLCAKICAgICAgICAgbWF0Y2hlcygiXkwiLCBpZ25vcmUuY2FzZSA9IEZBTFNFKSwgCiAgICAgICAgIG1hdGNoZXMoIl5EIiwgaWdub3JlLmNhc2UgPSBGQUxTRSksIAogICAgICAgICAjIGlmIHRoZXJlIGFyZSBzb21lIFNpdGVsaW5rcyB0byBvdGhlciBXaWtpIHBhZ2VzCiAgICAgICAgICNtYXRjaGVzKCJeUyIsIGlnbm9yZS5jYXNlID0gRkFMU0UpLCAKICAgICAgICAgbWF0Y2hlcygiXlAiLCBpZ25vcmUuY2FzZSA9IEZBTFNFKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gMjpsYXN0X2NvbCgpLCBuYW1lc190byA9ICJwcm9wZXJ0eSIsIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JSAKICAjIGZpeCBoZWxwZXIgd2l0aCB0d28gY29sdW1ucyByZWZlcnJpbmcgdG8gdGhlIHNhbWUgcHJvcGVydHkKICBtdXRhdGUocHJvcGVydHkgPSBzdHJfcmVtb3ZlKHByb3BlcnR5LCAiXy4qIikpICU+JSAKICBmaWx0ZXIoIWlzLm5hKHZhbHVlKSkgJT4lIAogIGRpc3RpbmN0KCkKCnByaW50KGltcG9ydCkKYGBgCgoKYGBge3IgZW52b3llciB2ZXJzIHdpa2lkYXRhIH0KbGlicmFyeShXaWtpZGF0YVIpCndyaXRlX3dpa2lkYXRhKAogIGl0ZW1zICAgICAgICA9IGltcG9ydCRpdGVtLAogIHByb3BlcnRpZXMgICA9IGltcG9ydCRwcm9wZXJ0eSwKICB2YWx1ZXMgICAgICAgPSBpbXBvcnQkdmFsdWUsCiAgZm9ybWF0ICAgICAgID0gImFwaSIsCiAgYXBpLnVzZXJuYW1lID0gIlVkb19Cb2xhbm8iLCAKICBhcGkudG9rZW4gICAgPSAiJDJ5JDEwJHF5M09tbjdEbjREYVhBRDFRQldjcy5kTmpyS3dscmMuY0ZYMnJWWk15UTdvWXQyeFlTbUpTIiwgI1JFREFDVEVEIwogICkKCmBgYAoKCgoKYXBpLnRva2VuICAgID0gbWV0dHJlIGljaSBsZSB0b2tlbiByw6ljdXDDqXLDqSBzdXIgaHR0cHM6Ly9xdWlja3N0YXRlbWVudHMudG9vbGZvcmdlLm9yZy8jL3VzZXIKCnZvaXIgbW9kZSBkJ2VtcGxvaSBpY2kgOiBodHRwczovL2thdGhhcmluYWJydW5uZXIuZGUvMjAyMi8wNi93aWtpYmFzZS13aWtpZGF0YS1ldGwtZGF0YS1pbXBvcnQtd2l0aC1yLyA=