Datamunging

Datensatz anzeigen

head(FaithfulFaces) #im der Rmd - ersten Daten
tail(FaithfulFaces) #im der Rmd - letzten Daten
str(FaithfulFaces, give.attr = F) #Struktur
'data.frame':   170 obs. of  8 variables:
 $ X         : int  1 2 3 4 5 6 7 8 9 10 ...
 $ SexDimorph: num  4.9 2.58 4.3 4.08 4.5 ...
 $ Attract   : num  2 2.08 2.67 2.92 3.5 ...
 $ Cheater   : int  1 1 1 0 0 0 1 1 0 0 ...
 $ Trust     : num  4.12 4 3.94 4.12 3.23 ...
 $ Faithful  : num  6.29 6.59 5.82 5.41 4 ...
 $ FaceSex   : chr  "F" "F" "F" "F" ...
 $ RaterSex  : chr  "M" "M" "M" "M" ...
#View(FaithfulFaces) # Neuen Fenster
sample(FaithfulFaces) # Alle Daten
FaithfulFaces

Spaltennamen umbenennen

Var1:

# sehr "row"
colnames(FaithfulFaces)[4] <- "Betrueger" # Spalte 4  - Der Name wird geändert 
colnames(FaithfulFaces)[5] <- "Vertrauen" # Spalte 5  - Der Name wird geändert 
head(FaithfulFaces) # - ersten Daten

Var2:


library(dplyr) #-> Rename
FaithfulFaces <- FaithfulFaces %>% #pipe 
           rename(ProbandGeschlecht      = 'RaterSex',
                  GeschlechtTypGesicht   = 'SexDimorph')

Hinweis: “Rechts” der “alte Name”(immer im Hochkomma) - Links der “neue Name”

head(FaithfulFaces) #im der Rmd - ersten Daten

Rekodieren

#library(dplyr) #-> Rekodieren
FaithfulFaces <- FaithfulFaces %>%
  mutate(FaceSex   = factor(FaceSex, levels = c("F", "M"), labels = c("Weiblich", "Männlich")))

Hinweis: Zahlen ohne Hochkomma, Buchstaben mit Hochkomma

head(FaithfulFaces) 

Datensatzauswahl Fokus/Auswahl

Standardweg über FaithfulFaces$

# Normaler Wege: FaithfulFaces$Attract
a <- FaithfulFaces$Attract + FaithfulFaces$Faithful

Der Datensatz wird steht im Fokus


attach(FaithfulFaces)
# Es wird dieses Datensatz gewählt!
a <- Attract + Faithful


detach(FaithfulFaces)

mehrfach Zuweisung

a <-b<- FaithfulFaces$Attract + FaithfulFaces$Faithful

Hinzufügen einer neuen Spalte

var 1:

ncol(FaithfulFaces)
[1] 8
FaithfulFaces["neuspalte"] <- a
ncol(FaithfulFaces)
[1] 9

Var2:

FaithfulFaces$neuspalte <- NULL
ncol(FaithfulFaces)
[1] 8
FaithfulFaces<- cbind(FaithfulFaces, "neuspalte"= a)
ncol(FaithfulFaces)
[1] 9

Umgang mit NA - Missing Value


# Finden der NA-Werte 
#is.na(FaithfulFaces)

# wie viele NA-Werte
sum(is.na(FaithfulFaces))
[1] 0
sprintf("Anzahl der NAs: %d",sum(is.na(FaithfulFaces)) )
[1] "Anzahl der NAs: 0"
# Auslassen der NA-Werte 
FaithfulFaces <- na.omit(FaithfulFaces)

Handisches Loeschen von Daten

ausreiser <- boxplot(FaithfulFaces$Attract)

ausreiser$out
[1] 5.833 6.333 5.167 5.167
nrow(FaithfulFaces)
[1] 170
# Diese Zeilen sollen entfernt werden
drops <- c(65,63,97,163)

# Zeilen loeschen
FaithfulFaces <- FaithfulFaces[-drops,]
nrow(FaithfulFaces)
[1] 166

Automatisches Loeschen der Ausreiser

FaithfulFaces <- read.csv("C:/Users/Alfa/Downloads/FaithfulFaces(2).csv")

boxplot(FaithfulFaces$Attract) # Boxplot

# Suche der Ausreiser
outliers <- boxplot(FaithfulFaces$Attract, plot=FALSE)$out 
#Ausgabe der Ausreiser
print(outliers)
[1] 5.833 6.333 5.167 5.167
#Wegfilter der Ausreiser
FaithfulFaces <- FaithfulFaces[-which(FaithfulFaces$Attract %in% outliers),]
#Boxplot
boxplot(FaithfulFaces$Attract)

die Reihenfolge ändern

Var1:

unique(FaithfulFaces$FaceSex)
[1] "F" "M"
#neuordnen!

FaithfulFaces$FaceSex <- factor(FaithfulFaces$FaceSex, levels=c("Männlich", "Weiblich"))  
unique(FaithfulFaces$FaceSex)
[1] <NA>
Levels: Männlich Weiblich

Var2:

unique(FaithfulFaces$FaceSex)
[1] "F" "M"
FaithfulFaces$FaceSex <- as.character(FaithfulFaces$FaceSex)
FaithfulFaces$FaceSex <- factor(FaithfulFaces$FaceSex, levels = unique(FaithfulFaces$FaceSex))
unique(FaithfulFaces$FaceSex)
[1] F M
Levels: F M

Spalte löschen

FaithfulFaces$Attract <- NULL

head(FaithfulFaces)
NA

Downsizing - Gruppenbildung

Var1:

library(RcmdrMisc)

FaithfulFaces <- within(FaithfulFaces, {
  attract_group <- Recode(Attract, 
  '0:2.0 ="low";2.01 : 3.5 = "mid"; 3.51 : 100 = "high";', 
  as.factor=TRUE)
})

head(FaithfulFaces)

Var2:

#library(dplyr)

FaithfulFaces$Attract<-
  case_when((FaithfulFaces$Attract <= 2)~ 1,
 (FaithfulFaces$Attract > 2) & (FaithfulFaces$Attract <= 3) ~ 2,
 (FaithfulFaces$Attract > 3)                                ~ 3)
head(FaithfulFaces)
NA

var3:

library(RcmdrMisc)
 attract_group <- Recode(FaithfulFaces$Attract, 
  '0:2.0 ="low";2.01 : 3.5 = "mid"; 3.51 : 100 = "high";', 
  as.factor=TRUE)
FaithfulFaces["attract_group"] = attract_group

Datenauswahl / Subsets

Var1:

#spalten 1 , sowie 5,6,7
FaithfulFaces_test <- FaithfulFaces[c(1,5:7)] 
head(FaithfulFaces_test)

Var2: Filter ist eine Möglichkeit

#Ratersex nur Männer und Attract über 3.5 und Cheater gleich 1 
# library(dplyr)
list_of_values <- c("M") #Objekte können ausgelagert werden. 
FaithfulFaces1 <- filter(FaithfulFaces, RaterSex %in% list_of_values &  Attract < 3.5 & Cheater == 1 )
#Ratersex nur Männer und Faithful unter 6
library(dplyr)
list_of_values <- c("M") 
FaithfulFaces2 <- filter(FaithfulFaces, RaterSex %in% list_of_values &  Faithful < 6)

Var3: subset

#Ratersex nur Frauen und Faithful über 5 , alle spalten werden angezeigt
FaithfulFaces_w <- subset(FaithfulFaces, FaceSex == "Weiblich" & Faithful > 5)
#Ratersex nur Frauen oder Faithful über 5 , es werden nur die Spalten: Faithful,FaceSex
FaithfulFaces_test <- subset(FaithfulFaces, FaceSex == "Weiblich" | Faithful > 5,  select=c(Faithful,FaceSex) )
head(FaithfulFaces_test)
FaithfulFaces <- read.csv("C:/Users/Alfa/Downloads/FaithfulFaces(2).csv")
#head(FaithfulFaces)

#Ratersex nur Frauen und Faithful über 5 , es werden alle  Spalten von X1 bis Faithful ausgegeben
FaithfulFaces_test <- subset(FaithfulFaces, FaceSex == "F", select=c(X:Faithful))
#head(FaithfulFaces_test)

Objekthandling

a <- c(1,2,3,4,9) # c steht für Combine Values into a Vector or List
print(a)
a[1] # Erster Wert ansteuern 
[1] 1

If-Else - Bedingungen


#Wie alt sind Sie? 
alter <-  19

if( 20 > alter ) {
           print("Du Teenager!!! ")
}else if (50 > alter & alter >= 20 ) {
           print("Du wirst auch nicht mehr jünger.")
}else{ 
           print("Ich zähle die Tage bis zur Rente.")
  }
[1] "Du Teenager!!! "

dreifacH Array.

arr  <- array(c(1:9), dim=c(3,3,4,2)) # Zeile | Spalte | Tiefe  | Wiederholung
arr
, , 1, 1

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 2, 1

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 3, 1

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 4, 1

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 1, 2

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 2, 2

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 3, 2

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 4, 2

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
arr[, , 4, 2] [,3]#Ansteuern des Wertes 
[1] 7 8 9

Schleifen

Es gibt drei Schleifenarten

1. Schleife: repeat

revar1 = 1


repeat{

          print(revar1)
          revar1 = revar1 +2
          
          if (revar1 > 9)
            break
          
  
}
[1] 1
[1] 3
[1] 5
[1] 7
[1] 9

2. Schleife: While

whilevar1=0

while(whilevar1 < 15)
{
  
  print(whilevar1)
  whilevar1 = whilevar1 +2;
  
}
[1] 0
[1] 2
[1] 4
[1] 6
[1] 8
[1] 10
[1] 12
[1] 14

3. Schleife: for

anzahl <- 5
ende <- 10
for (i in ende:anzahl)
{
  
 #anzahl = anzahl +1;
  print (i)
  
}
[1] 10
[1] 9
[1] 8
[1] 7
[1] 6
[1] 5

Umstellen der Nullstellen von Exponent auf Kommazahlen

ran2 <- c(1.646e-05) 
 options("scipen"=-100, "digits"=4)
 ran2

 options("scipen"=100, "digits"=4)
 ran2
LS0tDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCiFbRGF0YW11bmdpbmddKERhdGEuanBnKQ0KDQoNCg0KYGBge3Igd2FybmluZz0gRkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9DQpGYWl0aGZ1bEZhY2VzIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9BbGZhL0Rvd25sb2Fkcy9GYWl0aGZ1bEZhY2VzKDIpLmNzdiIpDQpgYGANCg0KIyMjIERhdGVuc2F0eiBhbnplaWdlbiANCmBgYHtyfQ0KaGVhZChGYWl0aGZ1bEZhY2VzKSAjaW0gZGVyIFJtZCAtIGVyc3RlbiBEYXRlbg0KdGFpbChGYWl0aGZ1bEZhY2VzKSAjaW0gZGVyIFJtZCAtIGxldHp0ZW4gRGF0ZW4NCnN0cihGYWl0aGZ1bEZhY2VzLCBnaXZlLmF0dHIgPSBGKSAjU3RydWt0dXINCiNWaWV3KEZhaXRoZnVsRmFjZXMpICMgTmV1ZW4gRmVuc3Rlcg0Kc2FtcGxlKEZhaXRoZnVsRmFjZXMpICMgQWxsZSBEYXRlbg0KRmFpdGhmdWxGYWNlcw0KYGBgDQoNCg0KDQojIyMgIFNwYWx0ZW5uYW1lbiB1bWJlbmVubmVuDQoNCioqVmFyMToqKg0KYGBge3J9DQojIHNlaHIgInJvdyINCmNvbG5hbWVzKEZhaXRoZnVsRmFjZXMpWzRdIDwtICJCZXRydWVnZXIiICMgU3BhbHRlIDQgIC0gRGVyIE5hbWUgd2lyZCBnZcOkbmRlcnQgDQpjb2xuYW1lcyhGYWl0aGZ1bEZhY2VzKVs1XSA8LSAiVmVydHJhdWVuIiAjIFNwYWx0ZSA1ICAtIERlciBOYW1lIHdpcmQgZ2XDpG5kZXJ0IA0KDQpgYGANCg0KYGBge3J9DQpoZWFkKEZhaXRoZnVsRmFjZXMpICMgLSBlcnN0ZW4gRGF0ZW4NCmBgYA0KDQoqKlZhcjI6KioNCg0KYGBge3J9DQoNCmxpYnJhcnkoZHBseXIpICMtPiBSZW5hbWUNCkZhaXRoZnVsRmFjZXMgPC0gRmFpdGhmdWxGYWNlcyAlPiUgI3BpcGUgDQogICAgICAgICAgIHJlbmFtZShQcm9iYW5kR2VzY2hsZWNodCAgICAgID0gJ1JhdGVyU2V4JywNCiAgICAgICAgICAgICAgICAgIEdlc2NobGVjaHRUeXBHZXNpY2h0ICAgPSAnU2V4RGltb3JwaCcpDQpgYGANCioqSGlud2VpczoqKiAiUmVjaHRzIiBkZXIgImFsdGUgTmFtZSIoaW1tZXIgaW0gSG9jaGtvbW1hKSAtIExpbmtzIGRlciAibmV1ZSBOYW1lIiAgDQoNCmBgYHtyfQ0KaGVhZChGYWl0aGZ1bEZhY2VzKSAjaW0gZGVyIFJtZCAtIGVyc3RlbiBEYXRlbg0KYGBgDQoNCiMjIyBSZWtvZGllcmVuDQoNCg0KYGBge3J9DQojbGlicmFyeShkcGx5cikgIy0+IFJla29kaWVyZW4NCkZhaXRoZnVsRmFjZXMgPC0gRmFpdGhmdWxGYWNlcyAlPiUNCiAgbXV0YXRlKEZhY2VTZXggICA9IGZhY3RvcihGYWNlU2V4LCBsZXZlbHMgPSBjKCJGIiwgIk0iKSwgbGFiZWxzID0gYygiV2VpYmxpY2giLCAiTcOkbm5saWNoIikpKQ0KYGBgDQoqKkhpbndlaXM6KiogWmFobGVuIG9obmUgSG9jaGtvbW1hLCBCdWNoc3RhYmVuIG1pdCBIb2Noa29tbWENCg0KDQoNCmBgYHtyfQ0KaGVhZChGYWl0aGZ1bEZhY2VzKSANCmBgYA0KDQojIyMgRGF0ZW5zYXR6YXVzd2FobCBGb2t1cy9BdXN3YWhsDQoNCioqU3RhbmRhcmR3ZWcgw7xiZXIgRmFpdGhmdWxGYWNlcyQgKioNCmBgYHtyfQ0KIyBOb3JtYWxlciBXZWdlOiBGYWl0aGZ1bEZhY2VzJEF0dHJhY3QNCmEgPC0gRmFpdGhmdWxGYWNlcyRBdHRyYWN0ICsgRmFpdGhmdWxGYWNlcyRGYWl0aGZ1bA0KDQpgYGANCg0KKipEZXIgRGF0ZW5zYXR6IHdpcmQgc3RlaHQgaW0gRm9rdXMqKg0KDQpgYGB7cn0NCg0KYXR0YWNoKEZhaXRoZnVsRmFjZXMpDQojIEVzIHdpcmQgZGllc2VzIERhdGVuc2F0eiBnZXfDpGhsdCENCmEgPC0gQXR0cmFjdCArIEZhaXRoZnVsDQoNCg0KZGV0YWNoKEZhaXRoZnVsRmFjZXMpDQoNCmBgYA0KDQoNCiMjIyBtZWhyZmFjaCBadXdlaXN1bmcNCmBgYHtyfQ0KYSA8LWI8LSBGYWl0aGZ1bEZhY2VzJEF0dHJhY3QgKyBGYWl0aGZ1bEZhY2VzJEZhaXRoZnVsDQoNCmBgYA0KDQoNCiMjIyBIaW56dWbDvGdlbiBlaW5lciBuZXVlbiBTcGFsdGUNCioqdmFyIDE6KioNCmBgYHtyfQ0KbmNvbChGYWl0aGZ1bEZhY2VzKQ0KRmFpdGhmdWxGYWNlc1sibmV1c3BhbHRlIl0gPC0gYQ0KbmNvbChGYWl0aGZ1bEZhY2VzKQ0KDQpgYGANCg0KKipWYXIyOioqDQoNCmBgYHtyfQ0KRmFpdGhmdWxGYWNlcyRuZXVzcGFsdGUgPC0gTlVMTA0KbmNvbChGYWl0aGZ1bEZhY2VzKQ0KRmFpdGhmdWxGYWNlczwtIGNiaW5kKEZhaXRoZnVsRmFjZXMsICJuZXVzcGFsdGUiPSBhKQ0KbmNvbChGYWl0aGZ1bEZhY2VzKQ0KYGBgDQoNCiMjIyBVbWdhbmcgbWl0IE5BIC0gTWlzc2luZyBWYWx1ZSANCg0KDQpgYGB7cn0NCg0KIyBGaW5kZW4gZGVyIE5BLVdlcnRlIA0KI2lzLm5hKEZhaXRoZnVsRmFjZXMpDQoNCiMgd2llIHZpZWxlIE5BLVdlcnRlDQpzdW0oaXMubmEoRmFpdGhmdWxGYWNlcykpDQpzcHJpbnRmKCJBbnphaGwgZGVyIE5BczogJWQiLHN1bShpcy5uYShGYWl0aGZ1bEZhY2VzKSkgKQ0KDQojIEF1c2xhc3NlbiBkZXIgTkEtV2VydGUgDQpGYWl0aGZ1bEZhY2VzIDwtIG5hLm9taXQoRmFpdGhmdWxGYWNlcykNCg0KYGBgDQoNCg0KIyMjIEhhbmRpc2NoZXMgTG9lc2NoZW4gdm9uIERhdGVuDQoNCmBgYHtyfQ0KYXVzcmVpc2VyIDwtIGJveHBsb3QoRmFpdGhmdWxGYWNlcyRBdHRyYWN0KQ0KYXVzcmVpc2VyJG91dA0KbnJvdyhGYWl0aGZ1bEZhY2VzKQ0KIyBEaWVzZSBaZWlsZW4gc29sbGVuIGVudGZlcm50IHdlcmRlbg0KZHJvcHMgPC0gYyg2NSw2Myw5NywxNjMpDQoNCiMgWmVpbGVuIGxvZXNjaGVuDQpGYWl0aGZ1bEZhY2VzIDwtIEZhaXRoZnVsRmFjZXNbLWRyb3BzLF0NCm5yb3coRmFpdGhmdWxGYWNlcykNCmBgYA0KDQoNCg0KDQojIyMgIEF1dG9tYXRpc2NoZXMgTG9lc2NoZW4gZGVyIEF1c3JlaXNlcg0KDQpgYGB7cn0NCkZhaXRoZnVsRmFjZXMgPC0gcmVhZC5jc3YoIkM6L1VzZXJzL0FsZmEvRG93bmxvYWRzL0ZhaXRoZnVsRmFjZXMoMikuY3N2IikNCg0KYm94cGxvdChGYWl0aGZ1bEZhY2VzJEF0dHJhY3QpICMgQm94cGxvdA0KIyBTdWNoZSBkZXIgQXVzcmVpc2VyDQpvdXRsaWVycyA8LSBib3hwbG90KEZhaXRoZnVsRmFjZXMkQXR0cmFjdCwgcGxvdD1GQUxTRSkkb3V0IA0KI0F1c2dhYmUgZGVyIEF1c3JlaXNlcg0KcHJpbnQob3V0bGllcnMpDQojV2VnZmlsdGVyIGRlciBBdXNyZWlzZXINCkZhaXRoZnVsRmFjZXMgPC0gRmFpdGhmdWxGYWNlc1std2hpY2goRmFpdGhmdWxGYWNlcyRBdHRyYWN0ICVpbiUgb3V0bGllcnMpLF0NCiNCb3hwbG90DQpib3hwbG90KEZhaXRoZnVsRmFjZXMkQXR0cmFjdCkNCg0KYGBgDQoNCg0KDQoNCiMjIyBkaWUgUmVpaGVuZm9sZ2Ugw6RuZGVybg0KKipWYXIxOioqDQpgYGB7cn0NCnVuaXF1ZShGYWl0aGZ1bEZhY2VzJEZhY2VTZXgpDQojbmV1b3JkbmVuIQ0KDQpGYWl0aGZ1bEZhY2VzJEZhY2VTZXggPC0gZmFjdG9yKEZhaXRoZnVsRmFjZXMkRmFjZVNleCwgbGV2ZWxzPWMoIk3DpG5ubGljaCIsICJXZWlibGljaCIpKSAgDQp1bmlxdWUoRmFpdGhmdWxGYWNlcyRGYWNlU2V4KQ0KYGBgDQoNCioqVmFyMjoqKg0KYGBge3Igd2FybmluZz0gRkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9DQpGYWl0aGZ1bEZhY2VzIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9BbGZhL0Rvd25sb2Fkcy9GYWl0aGZ1bEZhY2VzKDIpLmNzdiIpDQoNCmBgYA0KDQpgYGB7cn0NCnVuaXF1ZShGYWl0aGZ1bEZhY2VzJEZhY2VTZXgpDQpGYWl0aGZ1bEZhY2VzJEZhY2VTZXggPC0gYXMuY2hhcmFjdGVyKEZhaXRoZnVsRmFjZXMkRmFjZVNleCkNCkZhaXRoZnVsRmFjZXMkRmFjZVNleCA8LSBmYWN0b3IoRmFpdGhmdWxGYWNlcyRGYWNlU2V4LCBsZXZlbHMgPSB1bmlxdWUoRmFpdGhmdWxGYWNlcyRGYWNlU2V4KSkNCnVuaXF1ZShGYWl0aGZ1bEZhY2VzJEZhY2VTZXgpDQpgYGANCg0KDQojIyMgU3BhbHRlIGzDtnNjaGVuDQoNCmBgYHtyfQ0KRmFpdGhmdWxGYWNlcyRBdHRyYWN0IDwtIE5VTEwNCg0KaGVhZChGYWl0aGZ1bEZhY2VzKQ0KDQpgYGANCg0KIyMjIERvd25zaXppbmcgLSBHcnVwcGVuYmlsZHVuZyANCg0KKipWYXIxOioqDQpgYGB7ciB3YXJuaW5nPSBGQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0NCkZhaXRoZnVsRmFjZXMgPC0gcmVhZC5jc3YoIkM6L1VzZXJzL0FsZmEvRG93bmxvYWRzL0ZhaXRoZnVsRmFjZXMoMikuY3N2IikNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoUmNtZHJNaXNjKQ0KDQpGYWl0aGZ1bEZhY2VzIDwtIHdpdGhpbihGYWl0aGZ1bEZhY2VzLCB7DQogIGF0dHJhY3RfZ3JvdXAgPC0gUmVjb2RlKEF0dHJhY3QsIA0KICAnMDoyLjAgPSJsb3ciOzIuMDEgOiAzLjUgPSAibWlkIjsgMy41MSA6IDEwMCA9ICJoaWdoIjsnLCANCiAgYXMuZmFjdG9yPVRSVUUpDQp9KQ0KDQpoZWFkKEZhaXRoZnVsRmFjZXMpDQpgYGANCg0KDQoNCioqVmFyMjoqKg0KYGBge3Igd2FybmluZz0gRkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9DQpGYWl0aGZ1bEZhY2VzIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9BbGZhL0Rvd25sb2Fkcy9GYWl0aGZ1bEZhY2VzKDIpLmNzdiIpDQpgYGANCg0KYGBge3J9DQojbGlicmFyeShkcGx5cikNCg0KRmFpdGhmdWxGYWNlcyRBdHRyYWN0PC0NCiAgY2FzZV93aGVuKChGYWl0aGZ1bEZhY2VzJEF0dHJhY3QgPD0gMil+IDEsDQogKEZhaXRoZnVsRmFjZXMkQXR0cmFjdCA+IDIpICYgKEZhaXRoZnVsRmFjZXMkQXR0cmFjdCA8PSAzKSB+IDIsDQogKEZhaXRoZnVsRmFjZXMkQXR0cmFjdCA+IDMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+IDMpDQpoZWFkKEZhaXRoZnVsRmFjZXMpDQoNCmBgYA0KDQoqKnZhcjM6KioNCg0KYGBge3J9DQpsaWJyYXJ5KFJjbWRyTWlzYykNCiBhdHRyYWN0X2dyb3VwIDwtIFJlY29kZShGYWl0aGZ1bEZhY2VzJEF0dHJhY3QsIA0KICAnMDoyLjAgPSJsb3ciOzIuMDEgOiAzLjUgPSAibWlkIjsgMy41MSA6IDEwMCA9ICJoaWdoIjsnLCANCiAgYXMuZmFjdG9yPVRSVUUpDQpGYWl0aGZ1bEZhY2VzWyJhdHRyYWN0X2dyb3VwIl0gPSBhdHRyYWN0X2dyb3VwDQoNCmBgYA0KDQojIyMgIERhdGVuYXVzd2FobCAvIFN1YnNldHMNCioqVmFyMToqKg0KYGBge3J9DQojc3BhbHRlbiAxICwgc293aWUgNSw2LDcNCkZhaXRoZnVsRmFjZXNfdGVzdCA8LSBGYWl0aGZ1bEZhY2VzW2MoMSw1OjcpXSANCmhlYWQoRmFpdGhmdWxGYWNlc190ZXN0KQ0KYGBgDQoNCg0KDQpgYGB7ciB3YXJuaW5nPSBGQUxTRSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRX0NCkZhaXRoZnVsRmFjZXMgPC0gcmVhZC5jc3YoIkM6L1VzZXJzL0FsZmEvRG93bmxvYWRzL0ZhaXRoZnVsRmFjZXMoMikuY3N2IikNCmBgYA0KKipWYXIyOioqIEZpbHRlciBpc3QgZWluZSBNw7ZnbGljaGtlaXQNCg0KYGBge3J9DQojUmF0ZXJzZXggbnVyIE3DpG5uZXIgdW5kIEF0dHJhY3Qgw7xiZXIgMy41IHVuZCBDaGVhdGVyIGdsZWljaCAxIA0KIyBsaWJyYXJ5KGRwbHlyKQ0KbGlzdF9vZl92YWx1ZXMgPC0gYygiTSIpICNPYmpla3RlIGvDtm5uZW4gYXVzZ2VsYWdlcnQgd2VyZGVuLiANCkZhaXRoZnVsRmFjZXMxIDwtIGZpbHRlcihGYWl0aGZ1bEZhY2VzLCBSYXRlclNleCAlaW4lIGxpc3Rfb2ZfdmFsdWVzICYgIEF0dHJhY3QgPCAzLjUgJiBDaGVhdGVyID09IDEgKQ0KYGBgDQoNCg0KYGBge3J9DQojUmF0ZXJzZXggbnVyIE3DpG5uZXIgdW5kIEZhaXRoZnVsIHVudGVyIDYNCmxpYnJhcnkoZHBseXIpDQpsaXN0X29mX3ZhbHVlcyA8LSBjKCJNIikgDQpGYWl0aGZ1bEZhY2VzMiA8LSBmaWx0ZXIoRmFpdGhmdWxGYWNlcywgUmF0ZXJTZXggJWluJSBsaXN0X29mX3ZhbHVlcyAmICBGYWl0aGZ1bCA8IDYpDQpgYGANCg0KKipWYXIzOioqIHN1YnNldCANCg0KYGBge3J9DQojUmF0ZXJzZXggbnVyIEZyYXVlbiB1bmQgRmFpdGhmdWwgw7xiZXIgNSAsIGFsbGUgc3BhbHRlbiB3ZXJkZW4gYW5nZXplaWd0DQpGYWl0aGZ1bEZhY2VzX3cgPC0gc3Vic2V0KEZhaXRoZnVsRmFjZXMsIEZhY2VTZXggPT0gIldlaWJsaWNoIiAmIEZhaXRoZnVsID4gNSkNCg0KYGBgDQoNCg0KYGBge3J9DQojUmF0ZXJzZXggbnVyIEZyYXVlbiBvZGVyIEZhaXRoZnVsIMO8YmVyIDUgLCBlcyB3ZXJkZW4gbnVyIGRpZSBTcGFsdGVuOiBGYWl0aGZ1bCxGYWNlU2V4DQpGYWl0aGZ1bEZhY2VzX3Rlc3QgPC0gc3Vic2V0KEZhaXRoZnVsRmFjZXMsIEZhY2VTZXggPT0gIldlaWJsaWNoIiB8IEZhaXRoZnVsID4gNSwgIHNlbGVjdD1jKEZhaXRoZnVsLEZhY2VTZXgpICkNCiNoZWFkKEZhaXRoZnVsRmFjZXNfdGVzdCkNCmBgYA0KYGBge3J9DQpGYWl0aGZ1bEZhY2VzIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9BbGZhL0Rvd25sb2Fkcy9GYWl0aGZ1bEZhY2VzKDIpLmNzdiIpDQojaGVhZChGYWl0aGZ1bEZhY2VzKQ0KDQojUmF0ZXJzZXggbnVyIEZyYXVlbiB1bmQgRmFpdGhmdWwgw7xiZXIgNSAsIGVzIHdlcmRlbiBhbGxlICBTcGFsdGVuIHZvbiBYMSBiaXMgRmFpdGhmdWwgYXVzZ2VnZWJlbg0KRmFpdGhmdWxGYWNlc190ZXN0IDwtIHN1YnNldChGYWl0aGZ1bEZhY2VzLCBGYWNlU2V4ID09ICJGIiwgc2VsZWN0PWMoWDpGYWl0aGZ1bCkpDQojaGVhZChGYWl0aGZ1bEZhY2VzX3Rlc3QpDQpgYGANCg0KDQojIyMgT2JqZWt0aGFuZGxpbmcgDQoNCg0KYGBge3J9DQphIDwtIGMoMSwyLDMsNCw5KSAjIGMgc3RlaHQgZsO8ciBDb21iaW5lIFZhbHVlcyBpbnRvIGEgVmVjdG9yIG9yIExpc3QNCnByaW50KGEpDQpgYGANCg0KDQpgYGB7cn0NCmFbMV0gIyBFcnN0ZXIgV2VydCBhbnN0ZXVlcm4gDQpgYGANCg0KIyMjIElmLUVsc2UgLSBCZWRpbmd1bmdlbg0KDQpgYGB7cn0NCg0KI1dpZSBhbHQgc2luZCBTaWU/IA0KYWx0ZXIgPC0gIDE5DQoNCmlmKCAyMCA+IGFsdGVyICkgew0KICAgICAgICAgICBwcmludCgiRHUgVGVlbmFnZXIhISEgIikNCn1lbHNlIGlmICg1MCA+IGFsdGVyICYgYWx0ZXIgPj0gMjAgKSB7DQogICAgICAgICAgIHByaW50KCJEdSB3aXJzdCBhdWNoIG5pY2h0IG1laHIgasO8bmdlci4iKQ0KfWVsc2V7IA0KICAgICAgICAgICBwcmludCgiSWNoIHrDpGhsZSBkaWUgVGFnZSBiaXMgenVyIFJlbnRlLiIpDQogIH0NCg0KYGBgDQoNCg0KDQoNCiMjIyBkcmVpZmFjSCBBcnJheS4gDQpgYGB7cn0NCmFyciAgPC0gYXJyYXkoYygxOjkpLCBkaW09YygzLDMsNCwyKSkgIyBaZWlsZSB8IFNwYWx0ZSB8IFRpZWZlICB8IFdpZWRlcmhvbHVuZw0KYXJyDQpgYGANCg0KDQpgYGB7cn0NCmFyclssICwgNCwgMl0gWywzXSNBbnN0ZXVlcm4gZGVzIFdlcnRlcyANCmBgYA0KDQpTY2hsZWlmZW4NCg0KIyBFcyBnaWJ0IGRyZWkgU2NobGVpZmVuYXJ0ZW4NCg0KIyAxLiBTY2hsZWlmZTogcmVwZWF0DQpgYGB7cn0NCnJldmFyMSA9IDENCg0KDQpyZXBlYXR7DQoNCiAgICAgICAgICBwcmludChyZXZhcjEpDQogICAgICAgICAgcmV2YXIxID0gcmV2YXIxICsyDQogICAgICAgICAgDQogICAgICAgICAgaWYgKHJldmFyMSA+IDkpDQogICAgICAgICAgICBicmVhaw0KICAgICAgICAgIA0KICANCn0NCmBgYA0KDQoNCiMgMi4gU2NobGVpZmU6IFdoaWxlDQoNCmBgYHtyfQ0Kd2hpbGV2YXIxPTANCg0Kd2hpbGUod2hpbGV2YXIxIDwgMTUpDQp7DQogIA0KICBwcmludCh3aGlsZXZhcjEpDQogIHdoaWxldmFyMSA9IHdoaWxldmFyMSArMjsNCiAgDQp9DQpgYGANCg0KDQoNCiMgMy4gU2NobGVpZmU6IGZvcg0KYGBge3J9DQphbnphaGwgPC0gNQ0KZW5kZSA8LSAxMA0KZm9yIChpIGluIGVuZGU6YW56YWhsKQ0Kew0KICANCiAjYW56YWhsID0gYW56YWhsICsxOw0KICBwcmludCAoaSkNCiAgDQp9DQoNCmBgYA0KIyBVbXN0ZWxsZW4gZGVyIE51bGxzdGVsbGVuIHZvbiBFeHBvbmVudCBhdWYgS29tbWF6YWhsZW4NCmBgYHtyfQ0KcmFuMiA8LSBjKDEuNjQ2ZS0wNSkgDQogb3B0aW9ucygic2NpcGVuIj0tMTAwLCAiZGlnaXRzIj00KQ0KIHJhbjINCg0KIG9wdGlvbnMoInNjaXBlbiI9MTAwLCAiZGlnaXRzIj00KQ0KIHJhbjINCg0KYGBgDQoNCg0KDQoNCg0KIyMjIG5ldHRlciBMaW5rOiBodHRwczovL3I0ZHMuaGFkLmNvLm56L3JlbGF0aW9uYWwtZGF0YS5odG1sDQoNCg==