Network Scale Up (NELLS): Name analysis using Meertens Databank

In order to correctly create a module which we can use in the NELLS to measure the weak tie network we need to analyze the frequency of names. The names we eventually are going to use need to fulfill a view conditions and requirements. This HTML file documents the choices we make in creating the survey and it also provides easy reproducibility. Throughout we will use the guidelines as set out in (McCormick, Salganik, and Zheng 2010).

#list of packages that were used
library(tidyverse) #for data transformation
library(kableExtra) #for making nice tables
library(magrittr) #for data transformation
library(zoo) #for rolling average
library(cbsodataR) #for cbs data
library(patchwork)

Name frequency

We scraped the Meertens first name databank with use of an altered script that Rense Corten shared with us. The databank consists of multiple sources. A yearly popularity lists of newborns first names, the frequency of names in 2014 population, the number of newborns with a given name for each year between 1880-2016. The scrape procedure is as follows. I first scraped the yearly popularity lists from 1920 untill 2016 to get an overview of the most used names for newborns. This list of names is then used to scrape the entire Meertens databank. For every name in this list I scraped its frequency in the total population and also the number of newborns per year with that name. These scrape scripts can be found on my Github.

First let’s look at all the names we have scrape from the meertens databank.

#import the data from the web scrape (with the gender handles) 
namen_data <- read_csv("data_analysis/data/data_processed/meertens_scrape/all_names_19202014.csv")

#rename name into names and select only names and gender identifier. 
namen_data <- namen_data %>%
  rename(names = name) %>%
  select(names, is_girl_name)

#add frequency of birth data to the name data frame. 
voornamen_data <- read.csv("data_analysis/data/data_processed/meertens_scrape/dutch_names_frequency_18802016.csv")

#join the dfs togeteher, 
voornamen_data <- namen_data %>%
  left_join(voornamen_data, by = "names")

#reset all to utf8 coding. If I dont replace this then I wont be able to use group_by()
voornamen_data$names <- str_replace_all(voornamen_data$names,"[^[:graph:]]", " ")

#replace � with e. So all the names look prettier.
voornamen_data$names <- str_replace_all(voornamen_data$names, "�", "e")

#These are all names that were popular in the 1920-2014 timeframe.
unique(voornamen_data$names) %>%
  kbl(caption = "Unique Names in period 1920-2014", col.names = "Names") %>%
  kable_paper(full_width = F, bootstrap_options = c("hover", "condensed"), fixed_thead = T) %>%
  scroll_box(height = "300px")
Unique Names in period 1920-2014
Names
Sophie
Emma
Julia
Mila
Tess
Isa
Zo<U+FFFD>
Eva
Fenna
Anna
Sara
Evi
Lynn
Lotte
Lisa
Fleur
Saar
Sarah
Lieke
Roos
Noa
Nora
Maud
Sanne
Sofie
Liv
Esmee
Noor
Yara
Elin
Amy
Milou
Nina
Anne
Olivia
Feline
Femke
Jasmijn
Nova
Jill
Naomi
Lo<U+FFFD>s
Liz
Vera
Eline
Emily
Floor
Luna
Benthe
Iris
Fenne
Lizzy
Lina
Elise
Hannah
Isabella
Norah
Evy
Lana
Lola
Tessa
Amber
Suze
Isabel
Julie
Fay
Sophia
Lara
Charlotte
Nikki
Veerle
Ella
Lauren
Bo
Maria
Fien
Sofia
Rosalie
Bente
Elif
Fiene
Suus
Mirthe
Linde
Anouk
Fem
Johanna
Amira
Ilse
Senna
Lise
Marit
Merel
Cato
Demi
Rosa
Indy
Hailey
Daan
Bram
Sem
Finn
Milan
Lucas
Luuk
Levi
Liam
Noah
Tim
Jayden
Thijs
Jesse
Thomas
Lars
Ruben
Max
Julian
Mees
Sam
Stijn
Siem
Tygo
Benjamin
Gijs
Sven
Hugo
Luca
Jens
Vince
Dex
Noud
Teun
Mats
Ryan
Adam
Jan
Tijn
Jurre
Floris
Cas
Boaz
Dani<U+FFFD>l
Senn
Ties
Joep
David
Jack
Guus
Roan
Olivier
Jason
Dani
Niek
Tom
Pim
Willem
Dean
Koen
Pepijn
Dylan
Thijmen
Fedde
Bas
Mason
Morris
Tobias
Mohammed
Mohamed
Joey
Pieter
Stan
Xavi
Hidde
Niels
Quinn
Jasper
Casper
Timo
James
Johannes
Jip
Nathan
Joris
Owen
Jelle
Mick
Aiden
Samuel
Damian
Hendrik
Robin
Cornelis
Daley
Rayan
Stef
Simon
Nick
Alexander
Puck
Nienke
Elisa
Romy
Isis
Laura
Jade
Elena
Sterre
Lize
Kyan
Joshua
Abel
Rens
Sepp
Jelte
Vaj<U+FFFD>n
Kiki
Myrthe
Yfke
Quinten
Justin
Keano
Fabian
Mika
Mike
Britt
Meike
Guusje
Pien
Job
Jonathan
Luc
Bart
Esm<U+FFFD>e
Isabelle
Danique
Quinty
Madelief
Noortje
Wessel
Wesley
Twan
Rick
Sander
Dylano
Maarten
Tristan
Kim
Renske
Kyra
Lisanne
Matthijs
Kevin
Silke
Maartje
Daphne
Elisabeth
Tara
Maaike
Marijn
Jesper
Gerrit
Mara
Nynke
Aya
Tycho
Martijn
Jacob
Floortje
Mare
Michelle
Merle
Melissa
Wouter
Mark
Jochem
Joost
Wout
Jamie
Youri
Carmen
Esther
Kirsten
Sjoerd
Jordy
Jarno
Dirk
Sil
Chris
Dennis
Megan
Denise
Gwen
Manon
Marieke
Mandy
Stefan
Jort
Jeroen
Roy
Dewi
Jennifer
Dani<U+FFFD>lle
Rachel
Suzanne
Donna
Rik
Sebastiaan
Vincent
Melanie
Cornelia
Kimberly
Chantal
Inge
Jo<U+FFFD>lle
Michael
Jeffrey
Bryan
Nikita
Sharon
Kelly
Joyce
Larissa
Kaylee
Simone
Mathijs
Brian
Danny
Britney
Linda
Samantha
Patrick
Ricardo
Mitchell
Marco
Remco
Sabine
Celine
Jessica
Rianne
Maxime
Kimberley
Ashley
Dominique
Judith
Fabi<U+FFFD>nne
Robert
Lorenzo
Jordi
Frank
Giovanni
Marinus
Cheyenne
Nicole
Tamara
Nathalie
Nadine
Steven
Dion
Marc
Dave
Yannick
Laurens
Marloes
Wendy
Adriana
Menno
Peter
Erik
Leon
Christiaan
Claudia
Loes
Janneke
Mariska
Marjolein
Saskia
Bob
Richard
Jari
Michiel
Priscilla
Cynthia
Rebecca
Catharina
Rob
Glenn
Mitchel
Paul
Melvin
Rutger
Johan
Stephanie
Daisy
Ellen
Marleen
Sandra
Leonie
Marije
Michel
Erwin
Jacobus
Bastiaan
Angela
Evelien
Brenda
Lisette
Pascal
Maikel
Robbert
Nicky
Bianca
Lianne
Yvonne
Wilhelmina
Patricia
Ilona
Shirley
Amanda
Roel
Petrus
Martinus
Nicolaas
Jimmy
Cindy
Stefanie
Nadia
Hendrika
Monique
Stephan
Davey
Marcel
Roxanne
Deborah
Miranda
Ren<U+FFFD>
Martin
Ronald
Adrianus
Leroy
Susanne
Karin
Sabrina
Mirjam
Ruud
Maurice
Elizabeth
Mari<U+FFFD>lle
Edwin
Wilhelmus
Franciscus
Arjan
Gerardus
Irene
Marijke
Petra
Jolanda
Petronella
Eveline
Hendrikus
Eric
Ingrid
Ren<U+FFFD>e
Marianne
Martine
Albert
Antonius
Nancy
Anita
Raymond
Hans
Jacoba
Angelique
Sylvia
Annemarie
Margaretha
Jacqueline
Christian
Arie
Klaas
Geert
Diana
Hanneke
Ivo
Barbara
Annemieke
Astrid
Vanessa
Christina
Renate
Harm
Paulus
Robertus
Natasja
Helena
Caroline
Susan
Rogier
Arjen
Bj<U+FFFD>rn
Ramona
Natascha
Adriaan
Guido
Barry
Sonja
Debby
Sandy
Ralph
Gerard
Marcus
Heidi
Ramon
Tanja
Alexandra
Miriam
Arno
Roelof
Frederik
Roland
Aaltje
Karen
Andr<U+FFFD>
Henricus
Mirella
Brigitte
Geertruida
Ingeborg
Antonia
Yvette
Grietje
Leendert
Emiel
Remko
Ester
Francisca
Danielle
Jantje
Theodorus
Albertus
Roger
Jurgen
John
Mireille
Geertje
Marion
Silvia
Eduard
Leonardus
Arnold
Bernardus
Monica
Anja
Henri<U+FFFD>tte
Edith
Alida
Janna
Herman
Rudolf
Mario
Manuela
Annette
Theodora
Belinda
Trijntje
Marjan
Lambertus
Ronny
Evert
Berend
Olaf
Harold
Hubertus
Irma
Antoinette
Carolina
Antje
Willemina
Agnes
Carla
Edward
Andreas
Arthur
Frans
Jeannette
Martina
Ang<U+FFFD>lique
Pauline
Nicolette
Pieternella
Neeltje
Arnoldus
Hermanus
Marie
Hendrikje
Henrica
Jannetje
Gerarda
Josephus
Teunis
Arend
Ferdinand
Margriet
Gerda
Josephina
Hermina
Joseph
Jozef
Andries
Johnny
D<U+FFFD>sir<U+FFFD>e
Gerritje
Gertruda
Ronaldus
Walter
Egbert
Paulina
Louise
Wilma
Christine
Dirkje
Martha
Hendricus
Marcellinus
Aart
Gijsbertus
Regina
Aleida
Anton
Karel
Abraham
Rudi
Lucia
Berendina
Theresia
Anneke
Joannes
Gerhardus
Yolanda
Marja
Hendrina
Jeanette
Harry
Gijsbert
Alfred
Paula
Hubertina
Brigitta
Bernard
Marina
Bernadette
Jantina
Veronica
Derk
Magdalena
Francina
Frederika
Janny
Everdina
Louis
Micha<U+FFFD>l
Gerdina
Dina
Gerritdina
Henriette
Joanna
Antonie
Reinier
Lena
Ida
Dorothea
Antoon
Jakob
Willy
Antonetta
Bertha
Engelina
Josepha
Louisa
Marius
Kornelis
Henri
Anthonius
Agatha
Jannigje
Marten
Christianus
Bertus
Hendrica
Henderika
Josephine
Cornelius
Fredericus
Clasina
Jannie
Geesje
Annie
Mathilda
Leo
Olga
Clara
Jansje
George
Dick
Nelly
Teuntje
Alberdina
Gertrudis
Laurentius
Godefridus
Gezina
Alphonsus
Klazina
Bernardina
Frits
Harmen
Elly
Bernhard
Gerhard
Elsje
Wilhelm
Alberta
Susanna
Grada
Annigje
Lodewijk
Ludovicus
Piet
Anthonie
Mathias
Beatrix
Willempje
Barend
Theo
Hubert
Aartje
Gerardina
Henderikus
Margje
Pietertje
Pietje
Jeltje
Harmina
Roelofje
Lammert
Hermannus
Willemijntje
Geertruda
Gesina
Allegonda
Mattheus
Janke
Anthonia
Huibert
Douwe
Jacomina
Trientje
Reinder
Aagje
Adriaantje
Hindrik
Bartholomeus
Gijsberta
Maatje
Otto
Johannis
Leentje
Gradus
Klaasje
Leonard

Given that we have so many different names, it is fairly difficult to just choose a random number. We use the heuristics as set out in (McCormick 2010). As a start, we first need to get an overview of the different alter categories that we wish to include. These are gender, age, and ethnicity. For age, I will use four age categories: <25/25-40/41-65/65+. Gender consists of two categories: male/female. Ethnicity consists of Dutch native, Moroccan, and Turkish.

I will first turn to a the name frequency analysis for Dutch native names. In the second section I wil repeat this for the Moroccan and Turkish names.

Dutch Native Names

Given it is quite hard to eyeball the 763 names (period 1920 - 2014) we will make a first selection of names based on their frequency in the 2014 Dutch population. McCormick et al. specify that we want names that are not to frequent or infrequency (due to recall error). The ideal freuqency range is between 0.1 and 0.2 percentage of the population. We use the Dutch population of 2014 to calculate these frequencies. Unfortunately, we do not posses data on later years (as the Meertens databank has only information untill 2014).

Filter out names that are too frequent or infrequent in 2014: with a frequency lower than .1 or higher than .2.

#filter out 
voornamen_data_selection <- voornamen_data %>%
  filter((per > 0.1) & (per < .2)) 

voornamen_data_selection %>%
  filter(is_girl_name == 1) %>%
  group_by(names) %>%
  filter(row_number()==1) %>%
  ungroup() %>%
  select(names, number, per) %>%
  arrange(desc(per)) %>%
  kbl(caption = "Female names in selection \n (Dutch population 2014 = 16.829.289)", col.names = c("Name", "Frequency 2014", "Percentage")) %>%
  kable_paper(bootstrap_options = c("hover", "condensed"), full_width = F, fixed_thead = T) %>%
  scroll_box(height = "300px")
Female names in selection (Dutch population 2014 = 16.829.289)
Name Frequency 2014 Percentage
Esther 33392 0.1984160
Antonia 32039 0.1903764
Ingrid 31323 0.1861219
Christina 30630 0.1820041
Linda 29955 0.1779933
Robin 29432 0.1748856
Elizabeth 28968 0.1721285
Theodora 28221 0.1676898
Sandra 27680 0.1644752
Sanne 27394 0.1627757
Aaltje 27287 0.1621399
Kim 26055 0.1548194
Laura 25681 0.1525971
Grietje 25634 0.1523178
Alida 25422 0.1510581
Marianne 24671 0.1465956
Jolanda 23652 0.1405407
Karin 23067 0.1370646
Jantje 22884 0.1359772
Iris 22722 0.1350146
Trijntje 22377 0.1329646
Eva 21970 0.1305462
Jacqueline 21771 0.1293638
Lisa 21200 0.1259709
Neeltje 21116 0.1254717
Geertje 20789 0.1235287
Bianca 20518 0.1219184
Saskia 20375 0.1210687
Janna 20351 0.1209261
Astrid 20274 0.1204685
Chantal 19943 0.1185017
Wendy 19563 0.1162438
Danielle 19446 0.1155486
Petra 19336 0.1148949
Maaike 19217 0.1141878
Anouk 19186 0.1140036
Judith 19095 0.1134629
Patricia 19028 0.1130648
Antje 18876 0.1121616
Emma 18730 0.1112941
Femke 18102 0.1075625
Nicole 18094 0.1075149
Lotte 17675 0.1050252
Ellen 17210 0.1022622
Willemina 17133 0.1018047
Gerarda 17120 0.1017274
Jannetje 17001 0.1010203
Francisca 16944 0.1006816
voornamen_data_selection %>%
  filter(is_girl_name == 0) %>%
  group_by(names) %>%
  filter(row_number()==1) %>%
  ungroup() %>%
  select(names, number, per) %>%
  arrange(desc(per)) %>%
  kbl(caption = "Male names in selection \n (Dutch population 2014 = 16.829.289)", col.names = c("Name", "Frequenty 2014", "Percentage")) %>%
  kable_paper(full_width = F, bootstrap_options = c("hover", "condensed"), fixed_thead = T) %>%
  scroll_box(height = "300px")
Male names in selection (Dutch population 2014 = 16.829.289)
Name Frequenty 2014 Percentage
Mark 33618 0.1997589
Patrick 31984 0.1900496
Albert 31767 0.1887602
Arie 31685 0.1882730
Martijn 30193 0.1794075
Tim 30153 0.1791698
Robin 29432 0.1748856
Paul 28958 0.1720691
Erik 28852 0.1714392
Maarten 28703 0.1705538
Bernardus 27851 0.1654912
Wouter 27302 0.1622291
Marco 26958 0.1601850
Sander 26800 0.1592462
Bart 26183 0.1555800
Alexander 26020 0.1546114
Niels 25537 0.1517414
Michael 25405 0.1509571
Paulus 25326 0.1504876
Frank 24816 0.1474572
Leonardus 24628 0.1463401
Klaas 24357 0.1447298
Christiaan 23844 0.1416816
Albertus 23591 0.1401782
Kevin 23167 0.1376588
Tom 22988 0.1365952
Michel 22762 0.1352523
Daan 22704 0.1349077
Edwin 21866 0.1299282
Frederik 21490 0.1276940
Leendert 20913 0.1242655
Hans 20810 0.1236535
Adriaan 20628 0.1225720
Hubertus 20527 0.1219719
Ruben 20417 0.1213183
Stefan 20375 0.1210687
Gerard 20165 0.1198209
Lars 20135 0.1196426
Bram 20072 0.1192683
Martin 20061 0.1192029
Lucas 20049 0.1191316
Thijs 20016 0.1189355
Rudolf 19890 0.1181868
Roy 19856 0.1179848
Robertus 19799 0.1176461
Herman 19607 0.1165052
Jasper 19454 0.1155961
David 19142 0.1137422
Nick 19098 0.1134807
Hermanus 19025 0.1130470
Rick 18834 0.1119120
Eric 18735 0.1113238
Bas 18709 0.1111693
Roelof 18502 0.1099393
Harm 18344 0.1090004
Lambertus 18182 0.1080378
Simon 17949 0.1066533
Josephus 17844 0.1060294
Joseph 17492 0.1039378
Mike 17351 0.1031000
Danny 17029 0.1011867
Max 17024 0.1011570
Joost 16941 0.1006638
Geert 16890 0.1003607

Popularity heatmaps

It is important that the names provide an overview of the population that we want to scale up to. This means that we want our set of names to be representative in terms of age, as naming preferences are structured by period. For instance, we will introduce bias when we only choose names that were popular in the 50s. Luckily, we can easily show these patterns with heatmaps of the percentage of newborns with a given name in a given year. When we order the names in the heatmap by age we can easily see the age structure of names.

#first, before we make the plot we need to create an order in the plot. 
#what we want is to have the names ordered by time where they were mos popular. 

#create test procedure for just one name (Anne)
#idea is to first create rolling average of 6 years. 
name_order <- voornamen_data_selection %>%
  group_by(names) %>%
  mutate(rol_average = zoo::rollmean(value_list, k = 6, fill = NA)) %>%
  #look for min roll average within names (lower rank means higher popularity)
  mutate(max_average = max(rol_average, na.rm = T)) %>%
  #filter for min roll average
  filter(rol_average == max_average) %>%
  #rename year into min_year. With this we can arrange the data later on.
  rename(max_year = year_list) %>%
  #only select name and min_year.
  select(names, max_year) %>%
  ungroup()

#we still have multiple cases for several names.
#so we choose the earliest observation per name.
name_order %<>%
  arrange(names) %>%
  group_by(names) %>%
  arrange(max_year) %>%
  #choose the first observation
  filter(row_number()==1) %>%
  ungroup()

#let's add this data to the voornamen_data_selection file.
voornamen_data_selection %<>%
  left_join(name_order, by = "names")

#let's create the heatplot for female names.
#first, let's reorder the factor names based on min_year.
voornamen_data_selection$names <- factor(voornamen_data_selection$names)
voornamen_data_selection$names <- fct_reorder(voornamen_data_selection$names,voornamen_data_selection$max_year)
voornamen_data_selection %>%
  filter(is_girl_name == 1 & year_list > 1940) %>%
  ggplot(aes(x = year_list, y = names, fill = value_list)) +
  geom_tile() +
  theme_minimal() + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
  scale_x_continuous(breaks = 1940:2016) +
  scale_fill_continuous(type = "viridis") +
  labs(title = "Heatmap of popularity female names of newborn in the Netherlands (1920-2016)", caption = "Source: Meertens Instituut (2016)")

voornamen_data_selection %>%
  filter(is_girl_name == 0 & year_list > 1940) %>%
  ggplot(aes(x = year_list, y = names, fill = value_list)) +
  geom_tile() +
  theme_minimal() + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
  scale_x_continuous(breaks = 1940:2016) +
  scale_fill_continuous(type = "viridis") +
  labs(title = "Heatmap of popularity male names of newborn in the Netherlands (1920-2014)", caption = "Source: Meertens Instituut (2016)")

Selection of names

Based on the heat map and the frequency of names I have chosen the following names. Additionally, I also took into account the socioeconomic status of names. I tried to keep a balance of high and low status names to reduce bias in the results. (Bloothooft and Groot 2008; “Socioeconomic Determinants of First Names: Names: Vol 59, No 1” n.d.).

Male names

< 25 years old 25-40 40-65 65+
Male Daan Kevin Edwin Albert
Female Emma Linda Ingrid Willemina

For now we have a selection of 16 names. We will add 4 ethnic names to this mix, 2 names with Moroccan origin and 2 names with turkish origin. For these we need a seperate name analyses, which will be done in the next section.

Ethnic Names

For the development of the NELLS questionnaire we would also like to include ethnic names so we can capture the ethnic segregation of a network. For this purpose we also made the same frequency analysis for ethnic names. To scrape the Meertens data bank we need a list of names that can be classified as Turkish or Moroccan, since these are the two ethnic minorities we over-sample in the NELLS. I used a publication of Bloothooft and Groot that was published in 2005. They describe the clustering of names in the Netherlands and in the appendix of this study they provide all the names in each cluster. I used the names from the Turkish and the Arabic clusters to scrape the Meertens databank.

ethnic_names <- read_csv("data_analysis/data/data_processed/meertens_scrape/bloothooft_names_frequency_18802016.csv")

Name frequency

Let’s check the frequency of Turkish and Moroccan names in 2014 for male and females respectively. The histogram clearly shows that for these ethnic names we need other criteria for name frequency, since all names do not meet the criteria of .1 or .2 overall frequency.

#create percentage variable
ethnic_names <- ethnic_names %>%
  mutate(n = 16829289,
         per = (n_total / n) * 100)

#check the over distribution of percentages
ethnic_names %>%
  group_by(names) %>%
  summarise(percentage = max(per),
            is_female = max(gender) - 1, 
            ethnicity = max(ethnicity)) %>%
  arrange(desc(percentage)) %>%
  ggplot(aes(x = percentage)) +
  geom_histogram() +
  theme_minimal() + 
  facet_wrap(vars(is_female, ethnicity)) +
  labs(title = "Distribution of name frequency for Turkish and Moroccan \nfemale and male first names")

If we do filter with these values we literally get zero rows. So no ethnic names are frequent enough if we use the same heuristic for choosing dutch names; especially Turkish names are less frequent. So we need a way to take a sample of these names. For now, a simple heuristic. Take names that are one standard deviation more frequent than the mean frequency per category (ethnicity/gender). This means we select the most frequent ethnic names.

ethnic_names_summarized <- ethnic_names %>%
  group_by(names) %>%
  summarise(percentage = max(per),
            is_female = max(gender) - 1, 
            ethnicity = max(ethnicity)) %>%
  ungroup() %>%
  group_by(ethnicity, is_female) %>%
  mutate(mean_percentage = mean(percentage),
         sd_percentage = sd(percentage)) %>%
  ungroup()

#filter based on +1 sd above mean frequency. 
sample <- ethnic_names_summarized %>%
  filter(percentage > (mean_percentage + sd_percentage)) %>%
  select(names)

#extract the sample from the name_data. 
final_sample <- ethnic_names %>%
  filter(names %in% sample$names)

final_sample %>%
  filter(gender == 2) %>%
  select(names, n_total, per, ethnicity) %>%
  arrange(desc(per)) %>%
  distinct() %>%
  kbl(caption = "Female Turkish and Arabic names in selection \n (Dutch population 2014 = 16.829.289)", col.names = c("Name", "Frequency 2014", "Percentage", "Ethnicity")) %>%
  kable_paper(bootstrap_options = c("hover", "condensed"), full_width = F, fixed_thead = T) %>%
  scroll_box(height = "300px")
Female Turkish and Arabic names in selection (Dutch population 2014 = 16.829.289)
Name Frequency 2014 Percentage Ethnicity
Nadia 3956 0.0235066 arabic
Fatima 2808 0.0166852 arabic
Samira 2186 0.0129893 arabic
Yasmine 1919 0.0114027 arabic
Esra 1878 0.0111591 turkish
final_sample %>%
  filter(gender == 1) %>%
  select(names, n_total, per, ethnicity) %>%
  arrange(desc(per)) %>%
  distinct() %>%
  kbl(caption = "Male Turkish and Arabic names in selection \n (Dutch population 2014 = 16.829.289)", col.names = c("Name", "Frequency 2014", "Percentage", "Ethnicity")) %>%
  kable_paper(bootstrap_options = c("hover", "condensed"), full_width = F, fixed_thead = T) %>%
  scroll_box(height = "300px")
Male Turkish and Arabic names in selection (Dutch population 2014 = 16.829.289)
Name Frequency 2014 Percentage Ethnicity
Mohamed 8445 0.0501804 arabic
Ibrahim 2099 0.0124723 turkish
Emre 1582 0.0094003 turkish
Yusuf 1497 0.0088952 turkish

Birth frequency heatmaps

Same as with the native dutch names we can create heatmaps to look for a relationship between name and age.

#first, before we make the plot we need to create an order in the plot. 
#we have the birth frequency per year of a given name. 

#create rolling average of 6 years. 
name_order <- final_sample %>%
  group_by(names) %>%
  mutate(rol_average = zoo::rollmean(value_list, k = 6, fill = NA)) %>%
  #look for max roll average within names
  mutate(max_average = max(rol_average, na.rm = T)) %>%
  #filter for min roll average
  filter(rol_average == max_average) %>%
  #rename year into min_year. With this we can arrange the data later on.
  rename(min_year = year_list) %>%
  #only select name and min_year.
  select(names, min_year) %>%
  ungroup()

#we still have multiple cases for several names.
#so we choose the earliest observation per name.
name_order %<>%
  arrange(names) %>%
  group_by(names) %>%
  arrange(min_year) %>%
  #choose the first observation
  filter(row_number()==1) %>%
  ungroup()

#let's add this data to the voornamen_data_selection file.
final_sample %<>%
  left_join(name_order, by = "names")

#let's create the heatplot for female names.
#first, let's reorder the factor names based on min_year.
final_sample$names <- factor(final_sample$names)
final_sample$names <- fct_reorder(final_sample$names,final_sample$min_year)
heatmap_male_turkish <- final_sample %>%
  filter((gender == 1) & (year_list > 1920)& (ethnicity == "turkish")) %>%
  ggplot(aes(x = year_list, y = names, fill = value_list)) +
  geom_tile() +
  theme_minimal() + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),
        legend.position = "none") +
# scale_x_continuous(breaks = final_sample$year_list) +
  scale_fill_continuous(type = "viridis") +
  labs(title = "Male Turkish Names") 

heatmap_female_turkish <- final_sample %>%
  filter((gender == 2) & (year_list > 1920)& (ethnicity == "turkish")) %>%
  ggplot(aes(x = year_list, y = names, fill = value_list)) +
  geom_tile() +
  theme_minimal() + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
 # scale_x_continuous(breaks = final_sample$year_list) +
  scale_fill_continuous(type = "viridis") +
  labs(title = "Female Turkish Names") 

heatmap_male_moroccan <- final_sample %>%
  filter((gender == 1) & (year_list > 1920)& (ethnicity == "arabic")) %>%
  ggplot(aes(x = year_list, y = names, fill = value_list)) +
  geom_tile() +
  theme_minimal() + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),
        legend.position = "none") +
#  scale_x_continuous(breaks = final_sample$year_list) +
  scale_fill_continuous(type = "viridis") +
  labs(title = "Male Arabic Names") 

heatmap_female_moroccan <- final_sample %>%
  filter((gender == 2) & (year_list > 1920)& (ethnicity == "arabic")) %>%
  ggplot(aes(x = year_list, y = names, fill = value_list)) +
  geom_tile() +
  theme_minimal() + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
 # scale_x_continuous(breaks = final_sample$year_list) +
  scale_fill_continuous(type = "viridis") +
  labs(title = "Female Arabic Names", caption = "Source: Meertens Instituut (2016)") 


heatmap_male_turkish + heatmap_female_turkish

heatmap_male_moroccan + heatmap_female_moroccan

These heat maps show that for most of the Moroccan and Turkish names there is no clear relationship with age. Also, the number of names to choose from is rather low. So, I would propose to select the names that are highly prevalent in these four categories. Also, when we take a look at the demographic profile, in this case the percentage of Dutch citizens with a Turkish or Moroccan migration background we see that only ~4% of the population falls in one of those two categories.

toc <- cbs_get_toc(Language="en") # retrieve only english tables

#select the table that I want. Odata site gives 37296ned as code.  
cbs_demo <- cbs_get_data("37296eng") 

#let's check the demographic comoposition of the Netherlands in 2021. 
cbs_demo %<>%
  filter(Periods == "2020JJ00")

#calculate percentage 
cbs_demo %>%
  select(Morocco_35, Turkey_38, TotalPopulation_1) %>%
  mutate(per_mar = (Morocco_35/TotalPopulation_1) * 100,
           per_turk = (Turkey_38/TotalPopulation_1) * 100) %>%
  kbl(caption = "Turkish and Moroccan minorities in Dutch population (2021) Source: CBS Odata API", col.names = c("N Moroccans", "N Turks", "N population", "% Moroccans", "%Turks")) %>%
  kable_paper(bootstrap_options = c("hover", "condensed"), full_width = F, fixed_thead = T) %>%
  scroll_box(height = "300px")
Turkish and Moroccan minorities in Dutch population (2021) Source: CBS Odata API
N Moroccans N Turks N population % Moroccans %Turks
408864 416864 17407585 2.348769 2.394726

My proposal would be to select four ethnic names, each representing one of the groups ethnicity/gender. So I would propose, based on these data: Ibrahim and Esra for Turkish male and female names. For Moroccan male and female names I would choose Mohammed and Fatima.

Final Names

For the survey we have a list of 12 names that we will use. These are:

  • Daan
  • Kevin
  • Edwin
  • Albert
  • Emma
  • Linda
  • Ingrid
  • Willemina
  • Mohammed
  • Fatima
  • Esra
  • Ibrahim

References

Bloothooft, Gerrit, and Loek Groot. 2008. “Name Clustering on the Basis of Parental Preferences.” Names 56 (3): 111–63. https://doi.org/10.1179/175622708X332851.
McCormick, Tyler H., Matthew J. Salganik, and Tian Zheng. 2010. “How Many People Do You Know?: Efficiently Estimating Personal Network Size.” Journal of the American Statistical Association 105 (489): 59–70. https://doi.org/10.1198/jasa.2009.ap08518.
“Socioeconomic Determinants of First Names: Names: Vol 59, No 1.” n.d. Accessed September 27, 2021. https://www.tandfonline.com/doi/abs/10.1179/002777311X12942225544679.
LS0tDQp0aXRsZTogIk5TVU0gbW9kdWxlOiBuYW1lIHNlbGVjdGlvbiINCmF1dGhvcjogIlRoaWptZW4gSmVyb2Vuc2UiDQpkYXRlOiAiTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCINCmJpYmxpb2dyYXBoeTogcmVmZXJlbmNlcy5iaWINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoY2FjaGUgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgcmVzdWx0cyA9ICJhc2lzIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmBgYA0KDQojIE5ldHdvcmsgU2NhbGUgVXAgKE5FTExTKTogTmFtZSBhbmFseXNpcyB1c2luZyBNZWVydGVucyBEYXRhYmFuayANCg0KSW4gb3JkZXIgdG8gY29ycmVjdGx5IGNyZWF0ZSBhIG1vZHVsZSB3aGljaCB3ZSBjYW4gdXNlIGluIHRoZSBORUxMUyB0byBtZWFzdXJlIHRoZSB3ZWFrIHRpZSBuZXR3b3JrIHdlIG5lZWQgdG8gYW5hbHl6ZSB0aGUgZnJlcXVlbmN5IG9mIG5hbWVzLiBUaGUgbmFtZXMgd2UgZXZlbnR1YWxseSBhcmUgZ29pbmcgdG8gdXNlIG5lZWQgdG8gZnVsZmlsbCBhIHZpZXcgY29uZGl0aW9ucyBhbmQgcmVxdWlyZW1lbnRzLiBUaGlzIEhUTUwgZmlsZSBkb2N1bWVudHMgdGhlIGNob2ljZXMgd2UgbWFrZSBpbiBjcmVhdGluZyB0aGUgc3VydmV5IGFuZCBpdCBhbHNvIHByb3ZpZGVzIGVhc3kgcmVwcm9kdWNpYmlsaXR5LiBUaHJvdWdob3V0IHdlIHdpbGwgdXNlIHRoZSBndWlkZWxpbmVzIGFzIHNldCBvdXQgaW4gW0BtY2Nvcm1pY2tfaG93XzIwMTBdLiANCg0KYGBge3IgbG9hZCBwYWNrYWdlc30NCg0KI2xpc3Qgb2YgcGFja2FnZXMgdGhhdCB3ZXJlIHVzZWQNCmxpYnJhcnkodGlkeXZlcnNlKSAjZm9yIGRhdGEgdHJhbnNmb3JtYXRpb24NCmxpYnJhcnkoa2FibGVFeHRyYSkgI2ZvciBtYWtpbmcgbmljZSB0YWJsZXMNCmxpYnJhcnkobWFncml0dHIpICNmb3IgZGF0YSB0cmFuc2Zvcm1hdGlvbg0KbGlicmFyeSh6b28pICNmb3Igcm9sbGluZyBhdmVyYWdlDQpsaWJyYXJ5KGNic29kYXRhUikgI2ZvciBjYnMgZGF0YQ0KbGlicmFyeShwYXRjaHdvcmspDQpgYGANCg0KIyMgTmFtZSBmcmVxdWVuY3kNCg0KV2Ugc2NyYXBlZCB0aGUgW01lZXJ0ZW5zIGZpcnN0IG5hbWUgZGF0YWJhbmtdKGh0dHBzOi8vd3d3Lm1lZXJ0ZW5zLmtuYXcubmwvbnZiLykgd2l0aCB1c2Ugb2YgYW4gYWx0ZXJlZCBzY3JpcHQgdGhhdCBSZW5zZSBDb3J0ZW4gc2hhcmVkIHdpdGggdXMuIFRoZSBkYXRhYmFuayBjb25zaXN0cyBvZiBtdWx0aXBsZSBzb3VyY2VzLiBBIHllYXJseSBwb3B1bGFyaXR5IGxpc3RzIG9mIG5ld2Jvcm5zIGZpcnN0IG5hbWVzLCB0aGUgZnJlcXVlbmN5IG9mIG5hbWVzIGluIDIwMTQgcG9wdWxhdGlvbiwgdGhlIG51bWJlciBvZiBuZXdib3JucyB3aXRoIGEgZ2l2ZW4gbmFtZSBmb3IgZWFjaCB5ZWFyIGJldHdlZW4gMTg4MC0yMDE2LiBUaGUgc2NyYXBlIHByb2NlZHVyZSBpcyBhcyBmb2xsb3dzLiBJIGZpcnN0IHNjcmFwZWQgdGhlIHllYXJseSBwb3B1bGFyaXR5IGxpc3RzIGZyb20gMTkyMCB1bnRpbGwgMjAxNiB0byBnZXQgYW4gb3ZlcnZpZXcgb2YgdGhlIG1vc3QgdXNlZCBuYW1lcyBmb3IgbmV3Ym9ybnMuIFRoaXMgbGlzdCBvZiBuYW1lcyBpcyB0aGVuIHVzZWQgdG8gc2NyYXBlIHRoZSBlbnRpcmUgTWVlcnRlbnMgZGF0YWJhbmsuIEZvciBldmVyeSBuYW1lIGluIHRoaXMgbGlzdCBJIHNjcmFwZWQgaXRzIGZyZXF1ZW5jeSBpbiB0aGUgdG90YWwgcG9wdWxhdGlvbiBhbmQgYWxzbyB0aGUgbnVtYmVyIG9mIG5ld2Jvcm5zIHBlciB5ZWFyIHdpdGggdGhhdCBuYW1lLiBUaGVzZSBzY3JhcGUgc2NyaXB0cyBjYW4gYmUgZm91bmQgb24gbXkgR2l0aHViLiAgDQoNCkZpcnN0IGxldCdzIGxvb2sgYXQgYWxsIHRoZSBuYW1lcyB3ZSBoYXZlIHNjcmFwZSBmcm9tIHRoZSBtZWVydGVucyBkYXRhYmFuay4gDQpgYGB7ciBpbXBvcnQgZGF0YX0NCiNpbXBvcnQgdGhlIGRhdGEgZnJvbSB0aGUgd2ViIHNjcmFwZSAod2l0aCB0aGUgZ2VuZGVyIGhhbmRsZXMpIA0KbmFtZW5fZGF0YSA8LSByZWFkX2NzdigiZGF0YV9hbmFseXNpcy9kYXRhL2RhdGFfcHJvY2Vzc2VkL21lZXJ0ZW5zX3NjcmFwZS9hbGxfbmFtZXNfMTkyMDIwMTQuY3N2IikNCg0KI3JlbmFtZSBuYW1lIGludG8gbmFtZXMgYW5kIHNlbGVjdCBvbmx5IG5hbWVzIGFuZCBnZW5kZXIgaWRlbnRpZmllci4gDQpuYW1lbl9kYXRhIDwtIG5hbWVuX2RhdGEgJT4lDQogIHJlbmFtZShuYW1lcyA9IG5hbWUpICU+JQ0KICBzZWxlY3QobmFtZXMsIGlzX2dpcmxfbmFtZSkNCg0KI2FkZCBmcmVxdWVuY3kgb2YgYmlydGggZGF0YSB0byB0aGUgbmFtZSBkYXRhIGZyYW1lLiANCnZvb3JuYW1lbl9kYXRhIDwtIHJlYWQuY3N2KCJkYXRhX2FuYWx5c2lzL2RhdGEvZGF0YV9wcm9jZXNzZWQvbWVlcnRlbnNfc2NyYXBlL2R1dGNoX25hbWVzX2ZyZXF1ZW5jeV8xODgwMjAxNi5jc3YiKQ0KDQojam9pbiB0aGUgZGZzIHRvZ2V0ZWhlciwgDQp2b29ybmFtZW5fZGF0YSA8LSBuYW1lbl9kYXRhICU+JQ0KICBsZWZ0X2pvaW4odm9vcm5hbWVuX2RhdGEsIGJ5ID0gIm5hbWVzIikNCg0KI3Jlc2V0IGFsbCB0byB1dGY4IGNvZGluZy4gSWYgSSBkb250IHJlcGxhY2UgdGhpcyB0aGVuIEkgd29udCBiZSBhYmxlIHRvIHVzZSBncm91cF9ieSgpDQp2b29ybmFtZW5fZGF0YSRuYW1lcyA8LSBzdHJfcmVwbGFjZV9hbGwodm9vcm5hbWVuX2RhdGEkbmFtZXMsIlteWzpncmFwaDpdXSIsICIgIikNCg0KI3JlcGxhY2Ug77+9IHdpdGggZS4gU28gYWxsIHRoZSBuYW1lcyBsb29rIHByZXR0aWVyLg0Kdm9vcm5hbWVuX2RhdGEkbmFtZXMgPC0gc3RyX3JlcGxhY2VfYWxsKHZvb3JuYW1lbl9kYXRhJG5hbWVzLCAi77+9IiwgImUiKQ0KDQojVGhlc2UgYXJlIGFsbCBuYW1lcyB0aGF0IHdlcmUgcG9wdWxhciBpbiB0aGUgMTkyMC0yMDE0IHRpbWVmcmFtZS4NCnVuaXF1ZSh2b29ybmFtZW5fZGF0YSRuYW1lcykgJT4lDQogIGtibChjYXB0aW9uID0gIlVuaXF1ZSBOYW1lcyBpbiBwZXJpb2QgMTkyMC0yMDE0IiwgY29sLm5hbWVzID0gIk5hbWVzIikgJT4lDQogIGthYmxlX3BhcGVyKGZ1bGxfd2lkdGggPSBGLCBib290c3RyYXBfb3B0aW9ucyA9IGMoImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmaXhlZF90aGVhZCA9IFQpICU+JQ0KICBzY3JvbGxfYm94KGhlaWdodCA9ICIzMDBweCIpDQoNCmBgYA0KDQpHaXZlbiB0aGF0IHdlIGhhdmUgc28gbWFueSBkaWZmZXJlbnQgbmFtZXMsIGl0IGlzIGZhaXJseSBkaWZmaWN1bHQgdG8ganVzdCBjaG9vc2UgYSByYW5kb20gbnVtYmVyLiBXZSB1c2UgdGhlIGhldXJpc3RpY3MgYXMgc2V0IG91dCBpbiAoTWNDb3JtaWNrIDIwMTApLiBBcyBhIHN0YXJ0LCB3ZSBmaXJzdCBuZWVkIHRvIGdldCBhbiBvdmVydmlldyBvZiB0aGUgZGlmZmVyZW50IGFsdGVyIGNhdGVnb3JpZXMgdGhhdCB3ZSB3aXNoIHRvIGluY2x1ZGUuIFRoZXNlIGFyZSBnZW5kZXIsIGFnZSwgYW5kIGV0aG5pY2l0eS4gRm9yIGFnZSwgSSB3aWxsIHVzZSBmb3VyIGFnZSBjYXRlZ29yaWVzOiA8MjUvMjUtNDAvNDEtNjUvNjUrLiBHZW5kZXIgY29uc2lzdHMgb2YgdHdvIGNhdGVnb3JpZXM6IG1hbGUvZmVtYWxlLiBFdGhuaWNpdHkgY29uc2lzdHMgb2YgRHV0Y2ggbmF0aXZlLCBNb3JvY2NhbiwgYW5kIFR1cmtpc2guIA0KDQpJIHdpbGwgZmlyc3QgdHVybiB0byBhIHRoZSBuYW1lIGZyZXF1ZW5jeSBhbmFseXNpcyBmb3IgRHV0Y2ggbmF0aXZlIG5hbWVzLiBJbiB0aGUgc2Vjb25kIHNlY3Rpb24gSSB3aWwgcmVwZWF0IHRoaXMgZm9yIHRoZSBNb3JvY2NhbiBhbmQgVHVya2lzaCBuYW1lcy4gDQoNCiMjIER1dGNoIE5hdGl2ZSBOYW1lcw0KDQpHaXZlbiBpdCBpcyBxdWl0ZSBoYXJkIHRvIGV5ZWJhbGwgdGhlIDc2MyBuYW1lcyAocGVyaW9kIDE5MjAgLSAyMDE0KSB3ZSB3aWxsIG1ha2UgYSBmaXJzdCBzZWxlY3Rpb24gb2YgbmFtZXMgYmFzZWQgb24gdGhlaXIgZnJlcXVlbmN5IGluIHRoZSAyMDE0IER1dGNoIHBvcHVsYXRpb24uIE1jQ29ybWljayBldCBhbC4gc3BlY2lmeSB0aGF0IHdlIHdhbnQgbmFtZXMgdGhhdCBhcmUgbm90IHRvIGZyZXF1ZW50IG9yIGluZnJlcXVlbmN5IChkdWUgdG8gcmVjYWxsIGVycm9yKS4gVGhlIGlkZWFsIGZyZXVxZW5jeSByYW5nZSBpcyBiZXR3ZWVuIDAuMSBhbmQgMC4yIHBlcmNlbnRhZ2Ugb2YgdGhlIHBvcHVsYXRpb24uIFdlIHVzZSB0aGUgRHV0Y2ggcG9wdWxhdGlvbiBvZiAyMDE0IHRvIGNhbGN1bGF0ZSB0aGVzZSBmcmVxdWVuY2llcy4gVW5mb3J0dW5hdGVseSwgd2UgZG8gbm90IHBvc3NlcyBkYXRhIG9uIGxhdGVyIHllYXJzIChhcyB0aGUgTWVlcnRlbnMgZGF0YWJhbmsgaGFzIG9ubHkgaW5mb3JtYXRpb24gdW50aWxsIDIwMTQpLg0KDQpGaWx0ZXIgb3V0IG5hbWVzIHRoYXQgYXJlIHRvbyBmcmVxdWVudCBvciBpbmZyZXF1ZW50IGluIDIwMTQ6IHdpdGggYSBmcmVxdWVuY3kgbG93ZXIgdGhhbiAuMSBvciBoaWdoZXIgdGhhbiAuMi4NCg0KYGBge3IgZmlsdGVyIG91dCBuYW1lc30NCiNmaWx0ZXIgb3V0IA0Kdm9vcm5hbWVuX2RhdGFfc2VsZWN0aW9uIDwtIHZvb3JuYW1lbl9kYXRhICU+JQ0KICBmaWx0ZXIoKHBlciA+IDAuMSkgJiAocGVyIDwgLjIpKSANCg0Kdm9vcm5hbWVuX2RhdGFfc2VsZWN0aW9uICU+JQ0KICBmaWx0ZXIoaXNfZ2lybF9uYW1lID09IDEpICU+JQ0KICBncm91cF9ieShuYW1lcykgJT4lDQogIGZpbHRlcihyb3dfbnVtYmVyKCk9PTEpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHNlbGVjdChuYW1lcywgbnVtYmVyLCBwZXIpICU+JQ0KICBhcnJhbmdlKGRlc2MocGVyKSkgJT4lDQogIGtibChjYXB0aW9uID0gIkZlbWFsZSBuYW1lcyBpbiBzZWxlY3Rpb24gXG4gKER1dGNoIHBvcHVsYXRpb24gMjAxNCA9IDE2LjgyOS4yODkpIiwgY29sLm5hbWVzID0gYygiTmFtZSIsICJGcmVxdWVuY3kgMjAxNCIsICJQZXJjZW50YWdlIikpICU+JQ0KICBrYWJsZV9wYXBlcihib290c3RyYXBfb3B0aW9ucyA9IGMoImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmdWxsX3dpZHRoID0gRiwgZml4ZWRfdGhlYWQgPSBUKSAlPiUNCiAgc2Nyb2xsX2JveChoZWlnaHQgPSAiMzAwcHgiKQ0KYGBgDQoNCg0KYGBge3IgZHV0Y2ggbWFsZSBuYW1lc30NCnZvb3JuYW1lbl9kYXRhX3NlbGVjdGlvbiAlPiUNCiAgZmlsdGVyKGlzX2dpcmxfbmFtZSA9PSAwKSAlPiUNCiAgZ3JvdXBfYnkobmFtZXMpICU+JQ0KICBmaWx0ZXIocm93X251bWJlcigpPT0xKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBzZWxlY3QobmFtZXMsIG51bWJlciwgcGVyKSAlPiUNCiAgYXJyYW5nZShkZXNjKHBlcikpICU+JQ0KICBrYmwoY2FwdGlvbiA9ICJNYWxlIG5hbWVzIGluIHNlbGVjdGlvbiBcbiAoRHV0Y2ggcG9wdWxhdGlvbiAyMDE0ID0gMTYuODI5LjI4OSkiLCBjb2wubmFtZXMgPSBjKCJOYW1lIiwgIkZyZXF1ZW50eSAyMDE0IiwgIlBlcmNlbnRhZ2UiKSkgJT4lDQogIGthYmxlX3BhcGVyKGZ1bGxfd2lkdGggPSBGLCBib290c3RyYXBfb3B0aW9ucyA9IGMoImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmaXhlZF90aGVhZCA9IFQpICU+JQ0KICBzY3JvbGxfYm94KGhlaWdodCA9ICIzMDBweCIpDQpgYGANCg0KIyMjIFBvcHVsYXJpdHkgaGVhdG1hcHMNCkl0IGlzIGltcG9ydGFudCB0aGF0IHRoZSBuYW1lcyBwcm92aWRlIGFuIG92ZXJ2aWV3IG9mIHRoZSBwb3B1bGF0aW9uIHRoYXQgd2Ugd2FudCB0byBzY2FsZSB1cCB0by4gVGhpcyBtZWFucyB0aGF0IHdlIHdhbnQgb3VyIHNldCBvZiBuYW1lcyB0byBiZSByZXByZXNlbnRhdGl2ZSBpbiB0ZXJtcyBvZiBhZ2UsIGFzIG5hbWluZyBwcmVmZXJlbmNlcyBhcmUgc3RydWN0dXJlZCBieSBwZXJpb2QuIEZvciBpbnN0YW5jZSwgd2Ugd2lsbCBpbnRyb2R1Y2UgYmlhcyB3aGVuIHdlIG9ubHkgY2hvb3NlIG5hbWVzIHRoYXQgd2VyZSBwb3B1bGFyIGluIHRoZSA1MHMuIEx1Y2tpbHksIHdlIGNhbiBlYXNpbHkgc2hvdyB0aGVzZSBwYXR0ZXJucyB3aXRoIGhlYXRtYXBzIG9mIHRoZSBwZXJjZW50YWdlIG9mIG5ld2Jvcm5zIHdpdGggYSBnaXZlbiBuYW1lIGluIGEgZ2l2ZW4geWVhci4gV2hlbiB3ZSBvcmRlciB0aGUgbmFtZXMgaW4gdGhlIGhlYXRtYXAgYnkgYWdlIHdlIGNhbiBlYXNpbHkgc2VlIHRoZSBhZ2Ugc3RydWN0dXJlIG9mIG5hbWVzLiANCg0KYGBge3IgZHV0Y2ggaGVhdG1hcCBkYXRhIHByZXB9DQoNCiNmaXJzdCwgYmVmb3JlIHdlIG1ha2UgdGhlIHBsb3Qgd2UgbmVlZCB0byBjcmVhdGUgYW4gb3JkZXIgaW4gdGhlIHBsb3QuIA0KI3doYXQgd2Ugd2FudCBpcyB0byBoYXZlIHRoZSBuYW1lcyBvcmRlcmVkIGJ5IHRpbWUgd2hlcmUgdGhleSB3ZXJlIG1vcyBwb3B1bGFyLiANCg0KI2NyZWF0ZSB0ZXN0IHByb2NlZHVyZSBmb3IganVzdCBvbmUgbmFtZSAoQW5uZSkNCiNpZGVhIGlzIHRvIGZpcnN0IGNyZWF0ZSByb2xsaW5nIGF2ZXJhZ2Ugb2YgNiB5ZWFycy4gDQpuYW1lX29yZGVyIDwtIHZvb3JuYW1lbl9kYXRhX3NlbGVjdGlvbiAlPiUNCiAgZ3JvdXBfYnkobmFtZXMpICU+JQ0KICBtdXRhdGUocm9sX2F2ZXJhZ2UgPSB6b286OnJvbGxtZWFuKHZhbHVlX2xpc3QsIGsgPSA2LCBmaWxsID0gTkEpKSAlPiUNCiAgI2xvb2sgZm9yIG1pbiByb2xsIGF2ZXJhZ2Ugd2l0aGluIG5hbWVzIChsb3dlciByYW5rIG1lYW5zIGhpZ2hlciBwb3B1bGFyaXR5KQ0KICBtdXRhdGUobWF4X2F2ZXJhZ2UgPSBtYXgocm9sX2F2ZXJhZ2UsIG5hLnJtID0gVCkpICU+JQ0KICAjZmlsdGVyIGZvciBtaW4gcm9sbCBhdmVyYWdlDQogIGZpbHRlcihyb2xfYXZlcmFnZSA9PSBtYXhfYXZlcmFnZSkgJT4lDQogICNyZW5hbWUgeWVhciBpbnRvIG1pbl95ZWFyLiBXaXRoIHRoaXMgd2UgY2FuIGFycmFuZ2UgdGhlIGRhdGEgbGF0ZXIgb24uDQogIHJlbmFtZShtYXhfeWVhciA9IHllYXJfbGlzdCkgJT4lDQogICNvbmx5IHNlbGVjdCBuYW1lIGFuZCBtaW5feWVhci4NCiAgc2VsZWN0KG5hbWVzLCBtYXhfeWVhcikgJT4lDQogIHVuZ3JvdXAoKQ0KDQojd2Ugc3RpbGwgaGF2ZSBtdWx0aXBsZSBjYXNlcyBmb3Igc2V2ZXJhbCBuYW1lcy4NCiNzbyB3ZSBjaG9vc2UgdGhlIGVhcmxpZXN0IG9ic2VydmF0aW9uIHBlciBuYW1lLg0KbmFtZV9vcmRlciAlPD4lDQogIGFycmFuZ2UobmFtZXMpICU+JQ0KICBncm91cF9ieShuYW1lcykgJT4lDQogIGFycmFuZ2UobWF4X3llYXIpICU+JQ0KICAjY2hvb3NlIHRoZSBmaXJzdCBvYnNlcnZhdGlvbg0KICBmaWx0ZXIocm93X251bWJlcigpPT0xKSAlPiUNCiAgdW5ncm91cCgpDQoNCiNsZXQncyBhZGQgdGhpcyBkYXRhIHRvIHRoZSB2b29ybmFtZW5fZGF0YV9zZWxlY3Rpb24gZmlsZS4NCnZvb3JuYW1lbl9kYXRhX3NlbGVjdGlvbiAlPD4lDQogIGxlZnRfam9pbihuYW1lX29yZGVyLCBieSA9ICJuYW1lcyIpDQoNCiNsZXQncyBjcmVhdGUgdGhlIGhlYXRwbG90IGZvciBmZW1hbGUgbmFtZXMuDQojZmlyc3QsIGxldCdzIHJlb3JkZXIgdGhlIGZhY3RvciBuYW1lcyBiYXNlZCBvbiBtaW5feWVhci4NCnZvb3JuYW1lbl9kYXRhX3NlbGVjdGlvbiRuYW1lcyA8LSBmYWN0b3Iodm9vcm5hbWVuX2RhdGFfc2VsZWN0aW9uJG5hbWVzKQ0Kdm9vcm5hbWVuX2RhdGFfc2VsZWN0aW9uJG5hbWVzIDwtIGZjdF9yZW9yZGVyKHZvb3JuYW1lbl9kYXRhX3NlbGVjdGlvbiRuYW1lcyx2b29ybmFtZW5fZGF0YV9zZWxlY3Rpb24kbWF4X3llYXIpDQpgYGANCg0KYGBge3IgZHV0Y2ggaGVhdG1hcCBmZW1hbGUgbmFtZXMsIGZpZy5oZWlnaHQ9MTUsIGZpZy53aWR0aD0gMTAgfQ0Kdm9vcm5hbWVuX2RhdGFfc2VsZWN0aW9uICU+JQ0KICBmaWx0ZXIoaXNfZ2lybF9uYW1lID09IDEgJiB5ZWFyX2xpc3QgPiAxOTQwKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0geWVhcl9saXN0LCB5ID0gbmFtZXMsIGZpbGwgPSB2YWx1ZV9saXN0KSkgKw0KICBnZW9tX3RpbGUoKSArDQogIHRoZW1lX21pbmltYWwoKSArIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSwgaGp1c3Q9MSkpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE5NDA6MjAxNikgKw0KICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIikgKw0KICBsYWJzKHRpdGxlID0gIkhlYXRtYXAgb2YgcG9wdWxhcml0eSBmZW1hbGUgbmFtZXMgb2YgbmV3Ym9ybiBpbiB0aGUgTmV0aGVybGFuZHMgKDE5MjAtMjAxNikiLCBjYXB0aW9uID0gIlNvdXJjZTogTWVlcnRlbnMgSW5zdGl0dXV0ICgyMDE2KSIpDQpgYGANCg0KYGBge3IgZHV0Y2ggaGVhdG1hcCBtYWxlIG5hbWVzLCBmaWcuaGVpZ2h0PTE1LCBmaWcud2lkdGg9IDEwIH0NCnZvb3JuYW1lbl9kYXRhX3NlbGVjdGlvbiAlPiUNCiAgZmlsdGVyKGlzX2dpcmxfbmFtZSA9PSAwICYgeWVhcl9saXN0ID4gMTk0MCkgJT4lDQogIGdncGxvdChhZXMoeCA9IHllYXJfbGlzdCwgeSA9IG5hbWVzLCBmaWxsID0gdmFsdWVfbGlzdCkpICsNCiAgZ2VvbV90aWxlKCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKyANCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAxOTQwOjIwMTYpICsNCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIpICsNCiAgbGFicyh0aXRsZSA9ICJIZWF0bWFwIG9mIHBvcHVsYXJpdHkgbWFsZSBuYW1lcyBvZiBuZXdib3JuIGluIHRoZSBOZXRoZXJsYW5kcyAoMTkyMC0yMDE0KSIsIGNhcHRpb24gPSAiU291cmNlOiBNZWVydGVucyBJbnN0aXR1dXQgKDIwMTYpIikNCmBgYA0KDQoNCiMjIyBTZWxlY3Rpb24gb2YgbmFtZXMNCg0KQmFzZWQgb24gdGhlIGhlYXQgbWFwIGFuZCB0aGUgZnJlcXVlbmN5IG9mIG5hbWVzIEkgaGF2ZSBjaG9zZW4gdGhlIGZvbGxvd2luZyBuYW1lcy4gQWRkaXRpb25hbGx5LCBJIGFsc28gdG9vayBpbnRvIGFjY291bnQgdGhlIHNvY2lvZWNvbm9taWMgc3RhdHVzIG9mIG5hbWVzLiBJIHRyaWVkIHRvIGtlZXAgYSBiYWxhbmNlIG9mIGhpZ2ggYW5kIGxvdyBzdGF0dXMgbmFtZXMgdG8gcmVkdWNlIGJpYXMgaW4gdGhlIHJlc3VsdHMuIFtAYmxvb3Rob29mdF9uYW1lXzIwMDg7IEBub2F1dGhvcl9zb2Npb2Vjb25vbWljX25vZGF0ZV0uDQoNCioqTWFsZSBuYW1lcyoqDQoNCnwgICAgICAgICAgIHwgPCAyNSB5ZWFycyBvbGQgIHwgMjUtNDAgICB8IDQwLTY1ICAgIHwgNjUrICAgICB8IA0KfC0tLSAgICAgICAgfCAtLS0gICAgICAgICAgICAgfCAtLS0gICAgIHwgIC0tLSAgICAgfCAtLS0gICAgIHwNCnxNYWxlICAgfCAgICAgICAgRGFhbiAgICB8IEtldmluICAgICB8IEVkd2luIHwgIEFsYmVydCB8DQp8RmVtYWxlIHwgICAgICAgRW1tYSAgICAgfCBMaW5kYSB8ICBJbmdyaWQgICB8ICBXaWxsZW1pbmEgIHwNCg0KDQpGb3Igbm93IHdlIGhhdmUgYSBzZWxlY3Rpb24gb2YgMTYgbmFtZXMuIFdlIHdpbGwgYWRkIDQgZXRobmljIG5hbWVzIHRvIHRoaXMgbWl4LCAyIG5hbWVzIHdpdGggTW9yb2NjYW4gb3JpZ2luIGFuZCAyIG5hbWVzIHdpdGggdHVya2lzaCBvcmlnaW4uIEZvciB0aGVzZSB3ZSBuZWVkIGEgc2VwZXJhdGUgbmFtZSBhbmFseXNlcywgd2hpY2ggd2lsbCBiZSBkb25lIGluIHRoZSBuZXh0IHNlY3Rpb24uDQoNCiMjIEV0aG5pYyBOYW1lcw0KRm9yIHRoZSBkZXZlbG9wbWVudCBvZiB0aGUgTkVMTFMgcXVlc3Rpb25uYWlyZSB3ZSB3b3VsZCBhbHNvIGxpa2UgdG8gaW5jbHVkZSBldGhuaWMgbmFtZXMgc28gd2UgY2FuIGNhcHR1cmUgdGhlIGV0aG5pYyBzZWdyZWdhdGlvbiBvZiBhIG5ldHdvcmsuIEZvciB0aGlzIHB1cnBvc2Ugd2UgYWxzbyBtYWRlIHRoZSBzYW1lIGZyZXF1ZW5jeSBhbmFseXNpcyBmb3IgZXRobmljIG5hbWVzLiBUbyBzY3JhcGUgdGhlIE1lZXJ0ZW5zIGRhdGEgYmFuayB3ZSBuZWVkIGEgbGlzdCBvZiBuYW1lcyB0aGF0IGNhbiBiZSBjbGFzc2lmaWVkIGFzIFR1cmtpc2ggb3IgTW9yb2NjYW4sIHNpbmNlIHRoZXNlIGFyZSB0aGUgdHdvIGV0aG5pYyBtaW5vcml0aWVzIHdlIG92ZXItc2FtcGxlIGluIHRoZSBORUxMUy4gSSB1c2VkIGEgcHVibGljYXRpb24gb2YgQmxvb3Rob29mdCBhbmQgR3Jvb3QgdGhhdCB3YXMgcHVibGlzaGVkIGluIDIwMDUuIFRoZXkgZGVzY3JpYmUgdGhlIGNsdXN0ZXJpbmcgb2YgbmFtZXMgaW4gdGhlIE5ldGhlcmxhbmRzIGFuZCBpbiB0aGUgYXBwZW5kaXggb2YgdGhpcyBzdHVkeSB0aGV5IHByb3ZpZGUgYWxsIHRoZSBuYW1lcyBpbiBlYWNoIGNsdXN0ZXIuIEkgdXNlZCB0aGUgbmFtZXMgZnJvbSB0aGUgVHVya2lzaCBhbmQgdGhlIEFyYWJpYyBjbHVzdGVycyB0byBzY3JhcGUgdGhlIE1lZXJ0ZW5zIGRhdGFiYW5rLiANCg0KDQpgYGB7ciBsb2FkIGV0aG5pYyBkYXRhfQ0KZXRobmljX25hbWVzIDwtIHJlYWRfY3N2KCJkYXRhX2FuYWx5c2lzL2RhdGEvZGF0YV9wcm9jZXNzZWQvbWVlcnRlbnNfc2NyYXBlL2Jsb290aG9vZnRfbmFtZXNfZnJlcXVlbmN5XzE4ODAyMDE2LmNzdiIpDQpgYGANCg0KDQojIyMgTmFtZSBmcmVxdWVuY3kNCkxldCdzIGNoZWNrIHRoZSBmcmVxdWVuY3kgb2YgVHVya2lzaCBhbmQgTW9yb2NjYW4gbmFtZXMgaW4gMjAxNCBmb3IgbWFsZSBhbmQgZmVtYWxlcyByZXNwZWN0aXZlbHkuIFRoZSBoaXN0b2dyYW0gY2xlYXJseSBzaG93cyB0aGF0IGZvciB0aGVzZSBldGhuaWMgbmFtZXMgd2UgbmVlZCBvdGhlciBjcml0ZXJpYSBmb3IgbmFtZSBmcmVxdWVuY3ksIHNpbmNlIGFsbCBuYW1lcyBkbyBub3QgbWVldCB0aGUgY3JpdGVyaWEgb2YgLjEgb3IgLjIgb3ZlcmFsbCBmcmVxdWVuY3kuIA0KDQpgYGB7ciBmaWx0ZXIgZXRobmljIGNhc2VzfQ0KI2NyZWF0ZSBwZXJjZW50YWdlIHZhcmlhYmxlDQpldGhuaWNfbmFtZXMgPC0gZXRobmljX25hbWVzICU+JQ0KICBtdXRhdGUobiA9IDE2ODI5Mjg5LA0KICAgICAgICAgcGVyID0gKG5fdG90YWwgLyBuKSAqIDEwMCkNCg0KI2NoZWNrIHRoZSBvdmVyIGRpc3RyaWJ1dGlvbiBvZiBwZXJjZW50YWdlcw0KZXRobmljX25hbWVzICU+JQ0KICBncm91cF9ieShuYW1lcykgJT4lDQogIHN1bW1hcmlzZShwZXJjZW50YWdlID0gbWF4KHBlciksDQogICAgICAgICAgICBpc19mZW1hbGUgPSBtYXgoZ2VuZGVyKSAtIDEsIA0KICAgICAgICAgICAgZXRobmljaXR5ID0gbWF4KGV0aG5pY2l0eSkpICU+JQ0KICBhcnJhbmdlKGRlc2MocGVyY2VudGFnZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBwZXJjZW50YWdlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbSgpICsNCiAgdGhlbWVfbWluaW1hbCgpICsgDQogIGZhY2V0X3dyYXAodmFycyhpc19mZW1hbGUsIGV0aG5pY2l0eSkpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgbmFtZSBmcmVxdWVuY3kgZm9yIFR1cmtpc2ggYW5kIE1vcm9jY2FuIFxuZmVtYWxlIGFuZCBtYWxlIGZpcnN0IG5hbWVzIikNCg0KYGBgDQoNCg0KSWYgd2UgZG8gZmlsdGVyIHdpdGggdGhlc2UgdmFsdWVzIHdlIGxpdGVyYWxseSBnZXQgemVybyByb3dzLiBTbyBubyBldGhuaWMgbmFtZXMgYXJlIGZyZXF1ZW50IGVub3VnaCBpZiB3ZSB1c2UgdGhlIHNhbWUgaGV1cmlzdGljIGZvciBjaG9vc2luZyBkdXRjaCBuYW1lczsgZXNwZWNpYWxseSBUdXJraXNoIG5hbWVzIGFyZSBsZXNzIGZyZXF1ZW50LiBTbyB3ZSBuZWVkIGEgd2F5IHRvIHRha2UgYSBzYW1wbGUgb2YgdGhlc2UgbmFtZXMuIEZvciBub3csIGEgc2ltcGxlIGhldXJpc3RpYy4gVGFrZSBuYW1lcyB0aGF0IGFyZSBvbmUgc3RhbmRhcmQgZGV2aWF0aW9uIG1vcmUgZnJlcXVlbnQgdGhhbiB0aGUgbWVhbiBmcmVxdWVuY3kgcGVyIGNhdGVnb3J5IChldGhuaWNpdHkvZ2VuZGVyKS4gVGhpcyBtZWFucyB3ZSBzZWxlY3QgdGhlIG1vc3QgZnJlcXVlbnQgZXRobmljIG5hbWVzLiANCg0KDQpgYGB7ciBmZW1hbGUgdHVya2lzaCBhbmQgYXJhYmljIG5hbWVzfQ0KZXRobmljX25hbWVzX3N1bW1hcml6ZWQgPC0gZXRobmljX25hbWVzICU+JQ0KICBncm91cF9ieShuYW1lcykgJT4lDQogIHN1bW1hcmlzZShwZXJjZW50YWdlID0gbWF4KHBlciksDQogICAgICAgICAgICBpc19mZW1hbGUgPSBtYXgoZ2VuZGVyKSAtIDEsIA0KICAgICAgICAgICAgZXRobmljaXR5ID0gbWF4KGV0aG5pY2l0eSkpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIGdyb3VwX2J5KGV0aG5pY2l0eSwgaXNfZmVtYWxlKSAlPiUNCiAgbXV0YXRlKG1lYW5fcGVyY2VudGFnZSA9IG1lYW4ocGVyY2VudGFnZSksDQogICAgICAgICBzZF9wZXJjZW50YWdlID0gc2QocGVyY2VudGFnZSkpICU+JQ0KICB1bmdyb3VwKCkNCg0KI2ZpbHRlciBiYXNlZCBvbiArMSBzZCBhYm92ZSBtZWFuIGZyZXF1ZW5jeS4gDQpzYW1wbGUgPC0gZXRobmljX25hbWVzX3N1bW1hcml6ZWQgJT4lDQogIGZpbHRlcihwZXJjZW50YWdlID4gKG1lYW5fcGVyY2VudGFnZSArIHNkX3BlcmNlbnRhZ2UpKSAlPiUNCiAgc2VsZWN0KG5hbWVzKQ0KDQojZXh0cmFjdCB0aGUgc2FtcGxlIGZyb20gdGhlIG5hbWVfZGF0YS4gDQpmaW5hbF9zYW1wbGUgPC0gZXRobmljX25hbWVzICU+JQ0KICBmaWx0ZXIobmFtZXMgJWluJSBzYW1wbGUkbmFtZXMpDQoNCmZpbmFsX3NhbXBsZSAlPiUNCiAgZmlsdGVyKGdlbmRlciA9PSAyKSAlPiUNCiAgc2VsZWN0KG5hbWVzLCBuX3RvdGFsLCBwZXIsIGV0aG5pY2l0eSkgJT4lDQogIGFycmFuZ2UoZGVzYyhwZXIpKSAlPiUNCiAgZGlzdGluY3QoKSAlPiUNCiAga2JsKGNhcHRpb24gPSAiRmVtYWxlIFR1cmtpc2ggYW5kIEFyYWJpYyBuYW1lcyBpbiBzZWxlY3Rpb24gXG4gKER1dGNoIHBvcHVsYXRpb24gMjAxNCA9IDE2LjgyOS4yODkpIiwgY29sLm5hbWVzID0gYygiTmFtZSIsICJGcmVxdWVuY3kgMjAxNCIsICJQZXJjZW50YWdlIiwgIkV0aG5pY2l0eSIpKSAlPiUNCiAga2FibGVfcGFwZXIoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJob3ZlciIsICJjb25kZW5zZWQiKSwgZnVsbF93aWR0aCA9IEYsIGZpeGVkX3RoZWFkID0gVCkgJT4lDQogIHNjcm9sbF9ib3goaGVpZ2h0ID0gIjMwMHB4IikNCg0KYGBgDQoNCg0KYGBge3IgVHVya2lzaCBhbmQgQXJhYmljIG1hbGUgbmFtZXN9DQpmaW5hbF9zYW1wbGUgJT4lDQogIGZpbHRlcihnZW5kZXIgPT0gMSkgJT4lDQogIHNlbGVjdChuYW1lcywgbl90b3RhbCwgcGVyLCBldGhuaWNpdHkpICU+JQ0KICBhcnJhbmdlKGRlc2MocGVyKSkgJT4lDQogIGRpc3RpbmN0KCkgJT4lDQogIGtibChjYXB0aW9uID0gIk1hbGUgVHVya2lzaCBhbmQgQXJhYmljIG5hbWVzIGluIHNlbGVjdGlvbiBcbiAoRHV0Y2ggcG9wdWxhdGlvbiAyMDE0ID0gMTYuODI5LjI4OSkiLCBjb2wubmFtZXMgPSBjKCJOYW1lIiwgIkZyZXF1ZW5jeSAyMDE0IiwgIlBlcmNlbnRhZ2UiLCAiRXRobmljaXR5IikpICU+JQ0KICBrYWJsZV9wYXBlcihib290c3RyYXBfb3B0aW9ucyA9IGMoImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmdWxsX3dpZHRoID0gRiwgZml4ZWRfdGhlYWQgPSBUKSAlPiUNCiAgc2Nyb2xsX2JveChoZWlnaHQgPSAiMzAwcHgiKQ0KYGBgDQoNCiMjIyBCaXJ0aCBmcmVxdWVuY3kgaGVhdG1hcHMNCg0KU2FtZSBhcyB3aXRoIHRoZSBuYXRpdmUgZHV0Y2ggbmFtZXMgd2UgY2FuIGNyZWF0ZSBoZWF0bWFwcyB0byBsb29rIGZvciBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG5hbWUgYW5kIGFnZS4gIA0KDQpgYGB7ciB0dXJraXNoIGFuZCBhcmFiaWMgaGVhdG1hcCBkYXRhIHByZXB9DQojZmlyc3QsIGJlZm9yZSB3ZSBtYWtlIHRoZSBwbG90IHdlIG5lZWQgdG8gY3JlYXRlIGFuIG9yZGVyIGluIHRoZSBwbG90LiANCiN3ZSBoYXZlIHRoZSBiaXJ0aCBmcmVxdWVuY3kgcGVyIHllYXIgb2YgYSBnaXZlbiBuYW1lLiANCg0KI2NyZWF0ZSByb2xsaW5nIGF2ZXJhZ2Ugb2YgNiB5ZWFycy4gDQpuYW1lX29yZGVyIDwtIGZpbmFsX3NhbXBsZSAlPiUNCiAgZ3JvdXBfYnkobmFtZXMpICU+JQ0KICBtdXRhdGUocm9sX2F2ZXJhZ2UgPSB6b286OnJvbGxtZWFuKHZhbHVlX2xpc3QsIGsgPSA2LCBmaWxsID0gTkEpKSAlPiUNCiAgI2xvb2sgZm9yIG1heCByb2xsIGF2ZXJhZ2Ugd2l0aGluIG5hbWVzDQogIG11dGF0ZShtYXhfYXZlcmFnZSA9IG1heChyb2xfYXZlcmFnZSwgbmEucm0gPSBUKSkgJT4lDQogICNmaWx0ZXIgZm9yIG1pbiByb2xsIGF2ZXJhZ2UNCiAgZmlsdGVyKHJvbF9hdmVyYWdlID09IG1heF9hdmVyYWdlKSAlPiUNCiAgI3JlbmFtZSB5ZWFyIGludG8gbWluX3llYXIuIFdpdGggdGhpcyB3ZSBjYW4gYXJyYW5nZSB0aGUgZGF0YSBsYXRlciBvbi4NCiAgcmVuYW1lKG1pbl95ZWFyID0geWVhcl9saXN0KSAlPiUNCiAgI29ubHkgc2VsZWN0IG5hbWUgYW5kIG1pbl95ZWFyLg0KICBzZWxlY3QobmFtZXMsIG1pbl95ZWFyKSAlPiUNCiAgdW5ncm91cCgpDQoNCiN3ZSBzdGlsbCBoYXZlIG11bHRpcGxlIGNhc2VzIGZvciBzZXZlcmFsIG5hbWVzLg0KI3NvIHdlIGNob29zZSB0aGUgZWFybGllc3Qgb2JzZXJ2YXRpb24gcGVyIG5hbWUuDQpuYW1lX29yZGVyICU8PiUNCiAgYXJyYW5nZShuYW1lcykgJT4lDQogIGdyb3VwX2J5KG5hbWVzKSAlPiUNCiAgYXJyYW5nZShtaW5feWVhcikgJT4lDQogICNjaG9vc2UgdGhlIGZpcnN0IG9ic2VydmF0aW9uDQogIGZpbHRlcihyb3dfbnVtYmVyKCk9PTEpICU+JQ0KICB1bmdyb3VwKCkNCg0KI2xldCdzIGFkZCB0aGlzIGRhdGEgdG8gdGhlIHZvb3JuYW1lbl9kYXRhX3NlbGVjdGlvbiBmaWxlLg0KZmluYWxfc2FtcGxlICU8PiUNCiAgbGVmdF9qb2luKG5hbWVfb3JkZXIsIGJ5ID0gIm5hbWVzIikNCg0KI2xldCdzIGNyZWF0ZSB0aGUgaGVhdHBsb3QgZm9yIGZlbWFsZSBuYW1lcy4NCiNmaXJzdCwgbGV0J3MgcmVvcmRlciB0aGUgZmFjdG9yIG5hbWVzIGJhc2VkIG9uIG1pbl95ZWFyLg0KZmluYWxfc2FtcGxlJG5hbWVzIDwtIGZhY3RvcihmaW5hbF9zYW1wbGUkbmFtZXMpDQpmaW5hbF9zYW1wbGUkbmFtZXMgPC0gZmN0X3Jlb3JkZXIoZmluYWxfc2FtcGxlJG5hbWVzLGZpbmFsX3NhbXBsZSRtaW5feWVhcikNCmBgYA0KDQpgYGB7ciB0dXJraXNoIGFuZCBhcmFiaWMgaGVhdG1hcHMsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0gMTR9DQpoZWF0bWFwX21hbGVfdHVya2lzaCA8LSBmaW5hbF9zYW1wbGUgJT4lDQogIGZpbHRlcigoZ2VuZGVyID09IDEpICYgKHllYXJfbGlzdCA+IDE5MjApJiAoZXRobmljaXR5ID09ICJ0dXJraXNoIikpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyX2xpc3QsIHkgPSBuYW1lcywgZmlsbCA9IHZhbHVlX2xpc3QpKSArDQogIGdlb21fdGlsZSgpICsNCiAgdGhlbWVfbWluaW1hbCgpICsgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQojIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBmaW5hbF9zYW1wbGUkeWVhcl9saXN0KSArDQogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiKSArDQogIGxhYnModGl0bGUgPSAiTWFsZSBUdXJraXNoIE5hbWVzIikgDQoNCmhlYXRtYXBfZmVtYWxlX3R1cmtpc2ggPC0gZmluYWxfc2FtcGxlICU+JQ0KICBmaWx0ZXIoKGdlbmRlciA9PSAyKSAmICh5ZWFyX2xpc3QgPiAxOTIwKSYgKGV0aG5pY2l0eSA9PSAidHVya2lzaCIpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0geWVhcl9saXN0LCB5ID0gbmFtZXMsIGZpbGwgPSB2YWx1ZV9saXN0KSkgKw0KICBnZW9tX3RpbGUoKSArDQogIHRoZW1lX21pbmltYWwoKSArIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSwgaGp1c3Q9MSkpICsNCiAjIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBmaW5hbF9zYW1wbGUkeWVhcl9saXN0KSArDQogIHNjYWxlX2ZpbGxfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiKSArDQogIGxhYnModGl0bGUgPSAiRmVtYWxlIFR1cmtpc2ggTmFtZXMiKSANCg0KaGVhdG1hcF9tYWxlX21vcm9jY2FuIDwtIGZpbmFsX3NhbXBsZSAlPiUNCiAgZmlsdGVyKChnZW5kZXIgPT0gMSkgJiAoeWVhcl9saXN0ID4gMTkyMCkmIChldGhuaWNpdHkgPT0gImFyYWJpYyIpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0geWVhcl9saXN0LCB5ID0gbmFtZXMsIGZpbGwgPSB2YWx1ZV9saXN0KSkgKw0KICBnZW9tX3RpbGUoKSArDQogIHRoZW1lX21pbmltYWwoKSArIA0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSwgaGp1c3Q9MSksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KIyAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGZpbmFsX3NhbXBsZSR5ZWFyX2xpc3QpICsNCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKHR5cGUgPSAidmlyaWRpcyIpICsNCiAgbGFicyh0aXRsZSA9ICJNYWxlIEFyYWJpYyBOYW1lcyIpIA0KDQpoZWF0bWFwX2ZlbWFsZV9tb3JvY2NhbiA8LSBmaW5hbF9zYW1wbGUgJT4lDQogIGZpbHRlcigoZ2VuZGVyID09IDIpICYgKHllYXJfbGlzdCA+IDE5MjApJiAoZXRobmljaXR5ID09ICJhcmFiaWMiKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHllYXJfbGlzdCwgeSA9IG5hbWVzLCBmaWxsID0gdmFsdWVfbGlzdCkpICsNCiAgZ2VvbV90aWxlKCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKyANCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpKSArDQogIyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gZmluYWxfc2FtcGxlJHllYXJfbGlzdCkgKw0KICBzY2FsZV9maWxsX2NvbnRpbnVvdXModHlwZSA9ICJ2aXJpZGlzIikgKw0KICBsYWJzKHRpdGxlID0gIkZlbWFsZSBBcmFiaWMgTmFtZXMiLCBjYXB0aW9uID0gIlNvdXJjZTogTWVlcnRlbnMgSW5zdGl0dXV0ICgyMDE2KSIpIA0KDQoNCmhlYXRtYXBfbWFsZV90dXJraXNoICsgaGVhdG1hcF9mZW1hbGVfdHVya2lzaA0KaGVhdG1hcF9tYWxlX21vcm9jY2FuICsgaGVhdG1hcF9mZW1hbGVfbW9yb2NjYW4NCg0KYGBgDQoNClRoZXNlIGhlYXQgbWFwcyBzaG93IHRoYXQgZm9yIG1vc3Qgb2YgdGhlIE1vcm9jY2FuIGFuZCBUdXJraXNoIG5hbWVzIHRoZXJlIGlzIG5vIGNsZWFyIHJlbGF0aW9uc2hpcCB3aXRoIGFnZS4gQWxzbywgdGhlIG51bWJlciBvZiBuYW1lcyB0byBjaG9vc2UgZnJvbSBpcyByYXRoZXIgbG93LiBTbywgSSB3b3VsZCBwcm9wb3NlIHRvIHNlbGVjdCB0aGUgbmFtZXMgdGhhdCBhcmUgaGlnaGx5IHByZXZhbGVudCBpbiB0aGVzZSBmb3VyIGNhdGVnb3JpZXMuIEFsc28sIHdoZW4gd2UgdGFrZSBhIGxvb2sgYXQgdGhlIGRlbW9ncmFwaGljIHByb2ZpbGUsIGluIHRoaXMgY2FzZSB0aGUgcGVyY2VudGFnZSBvZiBEdXRjaCBjaXRpemVucyB3aXRoIGEgIFR1cmtpc2ggb3IgTW9yb2NjYW4gbWlncmF0aW9uIGJhY2tncm91bmQgd2Ugc2VlIHRoYXQgb25seSB+NCUgb2YgdGhlIHBvcHVsYXRpb24gZmFsbHMgaW4gb25lIG9mIHRob3NlIHR3byBjYXRlZ29yaWVzLg0KDQpgYGB7ciBldGhuaWMgY2JzfQ0KdG9jIDwtIGNic19nZXRfdG9jKExhbmd1YWdlPSJlbiIpICMgcmV0cmlldmUgb25seSBlbmdsaXNoIHRhYmxlcw0KDQojc2VsZWN0IHRoZSB0YWJsZSB0aGF0IEkgd2FudC4gT2RhdGEgc2l0ZSBnaXZlcyAzNzI5Nm5lZCBhcyBjb2RlLiAgDQpjYnNfZGVtbyA8LSBjYnNfZ2V0X2RhdGEoIjM3Mjk2ZW5nIikgDQoNCiNsZXQncyBjaGVjayB0aGUgZGVtb2dyYXBoaWMgY29tb3Bvc2l0aW9uIG9mIHRoZSBOZXRoZXJsYW5kcyBpbiAyMDIxLiANCmNic19kZW1vICU8PiUNCiAgZmlsdGVyKFBlcmlvZHMgPT0gIjIwMjBKSjAwIikNCg0KI2NhbGN1bGF0ZSBwZXJjZW50YWdlIA0KY2JzX2RlbW8gJT4lDQogIHNlbGVjdChNb3JvY2NvXzM1LCBUdXJrZXlfMzgsIFRvdGFsUG9wdWxhdGlvbl8xKSAlPiUNCiAgbXV0YXRlKHBlcl9tYXIgPSAoTW9yb2Njb18zNS9Ub3RhbFBvcHVsYXRpb25fMSkgKiAxMDAsDQogICAgICAgICAgIHBlcl90dXJrID0gKFR1cmtleV8zOC9Ub3RhbFBvcHVsYXRpb25fMSkgKiAxMDApICU+JQ0KICBrYmwoY2FwdGlvbiA9ICJUdXJraXNoIGFuZCBNb3JvY2NhbiBtaW5vcml0aWVzIGluIER1dGNoIHBvcHVsYXRpb24gKDIwMjEpIFNvdXJjZTogQ0JTIE9kYXRhIEFQSSIsIGNvbC5uYW1lcyA9IGMoIk4gTW9yb2NjYW5zIiwgIk4gVHVya3MiLCAiTiBwb3B1bGF0aW9uIiwgIiUgTW9yb2NjYW5zIiwgIiVUdXJrcyIpKSAlPiUNCiAga2FibGVfcGFwZXIoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJob3ZlciIsICJjb25kZW5zZWQiKSwgZnVsbF93aWR0aCA9IEYsIGZpeGVkX3RoZWFkID0gVCkgJT4lDQogIHNjcm9sbF9ib3goaGVpZ2h0ID0gIjMwMHB4IikNCg0KDQpgYGANCg0KDQpNeSBwcm9wb3NhbCB3b3VsZCBiZSB0byBzZWxlY3QgZm91ciBldGhuaWMgbmFtZXMsIGVhY2ggcmVwcmVzZW50aW5nIG9uZSBvZiB0aGUgZ3JvdXBzIGV0aG5pY2l0eS9nZW5kZXIuIFNvIEkgd291bGQgcHJvcG9zZSwgYmFzZWQgb24gdGhlc2UgZGF0YTogSWJyYWhpbSBhbmQgRXNyYSBmb3IgVHVya2lzaCBtYWxlIGFuZCBmZW1hbGUgbmFtZXMuIEZvciBNb3JvY2NhbiBtYWxlIGFuZCBmZW1hbGUgbmFtZXMgSSB3b3VsZCBjaG9vc2UgTW9oYW1tZWQgYW5kIEZhdGltYS4gDQoNCiMjIEZpbmFsIE5hbWVzDQoNCkZvciB0aGUgc3VydmV5IHdlIGhhdmUgYSBsaXN0IG9mIDEyIG5hbWVzIHRoYXQgd2Ugd2lsbCB1c2UuIFRoZXNlIGFyZToNCg0KLSBEYWFuDQotIEtldmluDQotIEVkd2luDQotIEFsYmVydA0KLSBFbW1hDQotIExpbmRhDQotIEluZ3JpZA0KLSBXaWxsZW1pbmENCi0gTW9oYW1tZWQNCi0gRmF0aW1hDQotIEVzcmENCi0gSWJyYWhpbQ0KDQoNCiMgUmVmZXJlbmNlcw0K


Copyright © 2024 Jeroense Thijmen