Definición PDF

Una distribución bivariada es de la forma \[p(y_1,y_2)=P(Y_1=y_1,Y_2=y_2)\] la cual podemos ver tiene dos variables aleatorias.

Propiedades

  1. \(p(y_1.y_2)\geq 0\)
  2. \(\sum_{y_1}\sum_{y_2}p(y_1,y_2)=1, \forall (y_1,y_2)\)

Definición CDF

La funcion de distribución acumulada se define como, \[F(y_1,y_2)=P(Y_1 \leq y_1, Y_2 \leq y_2)\]

Caso Discreto

\[\sum_{t_1 \in (-\infty,y_1]}\sum_{t_2 \in (-\infty,y_2]}f(t_1,t_2)\]

Caso continuo

\[\int_{-\infty}^{y_1}\int_{-\infty}^{y_2}f(t_1,t_2)dt_2dt_1\]

Propiedades

  1. \(F(-\infty,-\infty)=F(-\infty,y_2)=F(y_1,-\infty)=0\)
  2. \(F(\infty, \infty)=1\)

Ejemplo clase

La administración en un restaurante de comida rápida está interesada en el comportamiento conjunto de las variables aleatorias \(Y_1\), definidas como el tiempo total entre la llegada de un cliente a la tienda y la salida de la ventanilla de servicio y \(Y_2\), el tiempo que un cliente espera en la fila antes de llegar a la ventanilla de servicio. Como \(Y_1\) incluye el tiempo que un cliente espera en la fila, debemos tener \(Y_1 \geq Y_2\). La distribución de frecuencia relativa de valores observados de \(Y_1\) y \(Y_2\) puede ser modelada por la función de densidad de probabilidad \[f(y_1,y_2)=\begin{cases} e^{-y_1} & \text{ , } 0 \leq y_2 \leq y_1 < \infty \\ 0 & \text{ , en cualquier otro punto} \end{cases}\]

Con el tiempo medido en minutos. Encuentre

  1. \(P(Y_1<2, Y_2>1)\)
  2. \(P(Y_1 \geq 2Y_2)\)
  3. \(P(Y_1-Y_2 \geq 1)\) (Observese que \(Y_1-Y_2\) denota el tiempo que se pasa en la ventanilla de servicio)

Laboratorio en R

Usaremos el dataset demanda de bicicletas. Para determinar demostrar la utilizacion en campo de la teoria aprendidad en clase. El dataset lo puede encontrar en el GES.

bici<- read.csv("hour.csv",
                na.strings = FALSE,
                strip.white = TRUE)
colnames(bici)
 [1] "instant"    "dteday"     "season"     "yr"         "mnth"       "hr"         "holiday"   
 [8] "weekday"    "workingday" "weathersit" "temp"       "atemp"      "hum"        "windspeed" 
[15] "casual"     "registered" "cnt"       

datetime - hourly date + timestamp

season - 1 = spring, 2 = summer, 3 = fall, 4 = winter

holiday - whether the day is considered a holiday

workingday - whether the day is neither a weekend nor holiday

weather - 1: Clear, Few clouds, Partly cloudy, Partly cloudy 2: Mist + Cloudy, Mist + Broken clouds, Mist + Few clouds, Mist 3: Light Snow, Light Rain + Thunderstorm + Scattered clouds, Light Rain + Scattered clouds 4: Heavy Rain + Ice Pallets + Thunderstorm + Mist, Snow + Fog

temp - temperature in Celsius

atemp - “feels like” temperature in Celsius

humidity - relative humidity

windspeed - wind speed

casual - number of non-registered user rentals initiated

registered - number of registered user rentals initiated

count - number of total rentals

library(dplyr)
package <U+393C><U+3E31>dplyr<U+393C><U+3E32> was built under R version 3.3.3
Attaching package: <U+393C><U+3E31>dplyr<U+393C><U+3E32>

The following objects are masked from <U+393C><U+3E31>package:stats<U+393C><U+3E32>:

    filter, lag

The following objects are masked from <U+393C><U+3E31>package:base<U+393C><U+3E32>:

    intersect, setdiff, setequal, union
library(ggplot2)
library(MASS)

Attaching package: <U+393C><U+3E31>MASS<U+393C><U+3E32>

The following object is masked from <U+393C><U+3E31>package:dplyr<U+393C><U+3E32>:

    select
seasonx<-2
bici_data<-
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum) 
hist(bici_data$atemp)

hist(bici_data$hum)

bici_data %>% 
  ggplot(aes(atemp))+
  geom_histogram(bins=30, aes(y = ..density..) )+
  geom_rug()+
  geom_density()

bici_data %>% 
  ggplot(aes(hum))+
  geom_histogram(bins=30, aes(y = ..density..) )+
  geom_rug()+
  geom_density()

Grafica de contorno spring

seasonx<-1
bici_data<-
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum)
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum) %>%
  ggplot( aes(atemp, hum) ) +
  geom_raster(aes(fill=cnt), interpolate = FALSE)+
  geom_point(size=0.1)+
  geom_density_2d()+
  geom_rug()

NA
bici_density <- kde2d(bici_data$atemp,bici_data$hum, n=100)
bici_density$z <- bici_density$z/sum( bici_density$z) 
sum(bici_density$z)
[1] 1

Heatmap spring

cols1 <- colorRampPalette(c("red", "white", "blue"),
                                    space = "Lab")(256)
cols2 <- colorRampPalette(c("#FFFFD4", "#FED98E", "#FE9929", "#D95F0E", "#993404"),space="Lab")(256)
cols3<-colorRampPalette(c("black","blue","green","orange","red"))(1000)
image(bici_density$z,  
      col = cols3, 
      zlim=c(min(bici_density$z), max(bici_density$z)))

Grafica de contorno summer

seasonx<-2
bici_data<-
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum)
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum) %>%
  ggplot( aes(atemp, hum) ) +
  geom_raster(aes(fill=cnt), interpolate = FALSE)+
  geom_point(size=0.1)+
  geom_density_2d()+
  geom_rug()

NA
bici_density <- kde2d(bici_data$atemp,bici_data$hum, n=100)
bici_density$z <- bici_density$z/sum( bici_density$z) 
sum(bici_density$z)
[1] 1

Heatmap summer

cols1 <- colorRampPalette(c("red", "white", "blue"),
                                    space = "Lab")(256)
cols2 <- colorRampPalette(c("#FFFFD4", "#FED98E", "#FE9929", "#D95F0E", "#993404"),space="Lab")(256)
cols3<-colorRampPalette(c("black","blue","green","orange","red"))(1000)
image(bici_density$z,  
      col = cols3, 
      zlim=c(min(bici_density$z), max(bici_density$z)))

Grafica de contorno fall

seasonx<-3
bici_data<-
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum)
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum) %>%
  ggplot( aes(atemp, hum) ) +
  geom_raster(aes(fill=cnt), interpolate = FALSE)+
  geom_point(size=0.1)+
  geom_density_2d()+
  geom_rug()

NA
bici_density <- kde2d(bici_data$atemp,bici_data$hum, n=100)
bici_density$z <- bici_density$z/sum( bici_density$z) 
sum(bici_density$z)
[1] 1

Heatmap fall

cols1 <- colorRampPalette(c("red", "white", "blue"),
                                    space = "Lab")(256)
cols2 <- colorRampPalette(c("#FFFFD4", "#FED98E", "#FE9929", "#D95F0E", "#993404"),space="Lab")(256)
cols3<-colorRampPalette(c("black","blue","green","orange","red"))(1000)
image(bici_density$z,  
      col = cols3, 
      zlim=c(min(bici_density$z), max(bici_density$z)))

Grafica de contorno winter

seasonx<-4
bici_data<-
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum)
bici %>%  
  dplyr::select(season, atemp, hum, cnt) %>% 
  filter(season == seasonx) %>%
  group_by(atemp,hum) %>%
  ggplot( aes(atemp, hum) ) +
  geom_raster(aes(fill=cnt), interpolate = FALSE)+
  geom_point(size=0.1)+
  geom_density_2d()+
  geom_rug()

NA
bici_density <- kde2d(bici_data$atemp,bici_data$hum, n=100)
bici_density$z <- bici_density$z/sum( bici_density$z) 
sum(bici_density$z)
[1] 1

Heatmap winter

cols1 <- colorRampPalette(c("red", "white", "blue"),
                                    space = "Lab")(256)
cols2 <- colorRampPalette(c("#FFFFD4", "#FED98E", "#FE9929", "#D95F0E", "#993404"),space="Lab")(256)
cols3<-colorRampPalette(c("black","blue","green","orange","red"))(1000)
image(bici_density$z,  
      col = cols3, 
      zlim=c(min(bici_density$z), max(bici_density$z)))

str(bici_density)
List of 3
 $ x: num [1:100] 0.151 0.157 0.162 0.168 0.173 ...
 $ y: num [1:100] 0.16 0.168 0.177 0.185 0.194 ...
 $ z: num [1:100, 1:100] 3.38e-15 7.71e-15 1.66e-14 3.36e-14 6.44e-14 ...
filterX<-bici_density$x>=0.5
filterY<-bici_density$y<=0.3
bici_density$z[filterX,filterY] %>% sum()
[1] 0.003170821
filterX<-bici_density$x>=0.4 & bici_density$x<=0.8
filterY<-bici_density$y>=0.6 & bici_density$y<=0.85
bici_density$z[filterX,filterY] %>% sum()
[1] 0.2296997
bici_data<-
  bici %>%
  dplyr::select(season,atemp,hum,cnt)%>%
  filter(season==4)
##bici_density$y
x<-matrix(rep(bici_density$y,3),nrow = 3, byrow = TRUE)
sum(x*bici_density$y)
[1] 106.9188
library(expm)
Loading required package: Matrix

Attaching package: <U+393C><U+3E31>expm<U+393C><U+3E32>

The following object is masked from <U+393C><U+3E31>package:Matrix<U+393C><U+3E32>:

    expm
p<-rbind(c(1,0,0,0),c(0.5,0,0.5,0),c(0,0.5,0,0.5),c(0,0,0,1))
w<-matrix(p,nrow = 4)
c(0,0,1,0) %*% (p%^%20)
         [,1] [,2]         [,3]     [,4]
[1,] 0.333333    0 9.536743e-07 0.666666
LS0tDQp0aXRsZTogIkRpc3RyaWJ1Y2lvbmVzIGRlIHByb2JhYmlsaWRhZCBiaXZhcmlhZGFzIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQoNCiMjIERlZmluaWNpw4PCs24gUERGDQpVbmEgZGlzdHJpYnVjacODwrNuIGJpdmFyaWFkYSBlcyBkZSBsYSBmb3JtYSAkJHAoeV8xLHlfMik9UChZXzE9eV8xLFlfMj15XzIpJCQNCmxhIGN1YWwgcG9kZW1vcyB2ZXIgdGllbmUgZG9zICp2YXJpYWJsZXMgYWxlYXRvcmlhcyouDQoNCiMjIFByb3BpZWRhZGVzDQoxLiAkcCh5XzEueV8yKVxnZXEgMCQNCjIuICRcc3VtX3t5XzF9XHN1bV97eV8yfXAoeV8xLHlfMik9MSwgXGZvcmFsbCAoeV8xLHlfMikkDQoNCiMjIERlZmluaWNpw4PCs24gQ0RGDQpMYSBmdW5jaW9uIGRlIGRpc3RyaWJ1Y2nDg8KzbiBhY3VtdWxhZGEgc2UgZGVmaW5lIGNvbW8sDQokJEYoeV8xLHlfMik9UChZXzEgXGxlcSB5XzEsIFlfMiBcbGVxIHlfMikkJA0KDQojIyMgQ2FzbyBEaXNjcmV0bw0KDQokJFxzdW1fe3RfMSBcaW4gKC1caW5mdHkseV8xXX1cc3VtX3t0XzIgXGluICgtXGluZnR5LHlfMl19Zih0XzEsdF8yKSQkDQoNCiMjIyBDYXNvIGNvbnRpbnVvDQokJFxpbnRfey1caW5mdHl9Xnt5XzF9XGludF97LVxpbmZ0eX1ee3lfMn1mKHRfMSx0XzIpZHRfMmR0XzEkJA0KDQojIyBQcm9waWVkYWRlcw0KMS4gJEYoLVxpbmZ0eSwtXGluZnR5KT1GKC1caW5mdHkseV8yKT1GKHlfMSwtXGluZnR5KT0wJA0KMi4gJEYoXGluZnR5LCBcaW5mdHkpPTEkDQoNCiMjIEVqZW1wbG8gY2xhc2UNCkxhIGFkbWluaXN0cmFjacODwrNuIGVuIHVuIHJlc3RhdXJhbnRlIGRlIGNvbWlkYSByw4PCoXBpZGEgZXN0w4PCoSBpbnRlcmVzYWRhIGVuIGVsIGNvbXBvcnRhbWllbnRvIGNvbmp1bnRvIGRlIGxhcyB2YXJpYWJsZXMgYWxlYXRvcmlhcyAkWV8xJCwgZGVmaW5pZGFzIGNvbW8gZWwgdGllbXBvIHRvdGFsIGVudHJlIGxhIGxsZWdhZGEgZGUgdW4gY2xpZW50ZSBhIGxhIHRpZW5kYSB5IGxhIHNhbGlkYSBkZSBsYSB2ZW50YW5pbGxhIGRlIHNlcnZpY2lvIHkgJFlfMiQsIGVsIHRpZW1wbyBxdWUgdW4gY2xpZW50ZSBlc3BlcmEgZW4gbGEgZmlsYSBhbnRlcyBkZSBsbGVnYXIgYSBsYSB2ZW50YW5pbGxhIGRlIHNlcnZpY2lvLiBDb21vICRZXzEkIGluY2x1eWUgZWwgdGllbXBvIHF1ZSB1biBjbGllbnRlIGVzcGVyYSBlbiBsYSBmaWxhLCBkZWJlbW9zIHRlbmVyICRZXzEgXGdlcSBZXzIkLiBMYSBkaXN0cmlidWNpw4PCs24gZGUgZnJlY3VlbmNpYSByZWxhdGl2YSBkZSB2YWxvcmVzIG9ic2VydmFkb3MgZGUgJFlfMSQgeSAkWV8yJCBwdWVkZSBzZXIgbW9kZWxhZGEgcG9yIGxhIGZ1bmNpw4PCs24gZGUgZGVuc2lkYWQgZGUgcHJvYmFiaWxpZGFkDQokJGYoeV8xLHlfMik9XGJlZ2lue2Nhc2VzfQ0KZV57LXlfMX0gJiBcdGV4dHsgLCB9IDAgXGxlcSB5XzIgXGxlcSB5XzEgPCBcaW5mdHkgXFwgDQowICYgXHRleHR7ICwgIGVuIGN1YWxxdWllciBvdHJvIHB1bnRvfSAgIA0KXGVuZHtjYXNlc30kJA0KDQoNCg0KQ29uIGVsIHRpZW1wbyBtZWRpZG8gZW4gbWludXRvcy4gRW5jdWVudHJlDQoNCmEuICRQKFlfMTwyLCBZXzI+MSkkDQpiLiAkUChZXzEgXGdlcSAyWV8yKSQNCmMuICRQKFlfMS1ZXzIgXGdlcSAxKSQgKE9ic2VydmVzZSBxdWUgJFlfMS1ZXzIkIGRlbm90YSBlbCB0aWVtcG8gcXVlIHNlIHBhc2EgZW4gbGEgdmVudGFuaWxsYSBkZSBzZXJ2aWNpbykNCg0KDQojIExhYm9yYXRvcmlvIGVuIFINCg0KVXNhcmVtb3MgZWwgZGF0YXNldCBkZW1hbmRhIGRlIGJpY2ljbGV0YXMuIFBhcmEgZGV0ZXJtaW5hciBkZW1vc3RyYXIgbGEgdXRpbGl6YWNpb24gZW4gY2FtcG8gZGUgbGEgdGVvcmlhIGFwcmVuZGlkYWQgZW4gY2xhc2UuIEVsIGRhdGFzZXQgbG8gcHVlZGUgZW5jb250cmFyIGVuIGVsIEdFUy4NCg0KYGBge3J9DQpiaWNpPC0gcmVhZC5jc3YoImhvdXIuY3N2IiwNCiAgICAgICAgICAgICAgICBuYS5zdHJpbmdzID0gRkFMU0UsDQogICAgICAgICAgICAgICAgc3RyaXAud2hpdGUgPSBUUlVFKQ0KYGBgDQoNCmBgYHtyfQ0KY29sbmFtZXMoYmljaSkNCmBgYA0KDQoqKmRhdGV0aW1lKiogLSBob3VybHkgZGF0ZSArIHRpbWVzdGFtcCANCg0KKipzZWFzb24qKiAtICAxID0gc3ByaW5nLCAyID0gc3VtbWVyLCAzID0gZmFsbCwgNCA9IHdpbnRlciANCg0KKipob2xpZGF5KiogLSB3aGV0aGVyIHRoZSBkYXkgaXMgY29uc2lkZXJlZCBhIGhvbGlkYXkNCg0KKip3b3JraW5nZGF5KiogLSB3aGV0aGVyIHRoZSBkYXkgaXMgbmVpdGhlciBhIHdlZWtlbmQgbm9yIGhvbGlkYXkNCg0KKip3ZWF0aGVyKiogLSAqMToqIENsZWFyLCBGZXcgY2xvdWRzLCBQYXJ0bHkgY2xvdWR5LCBQYXJ0bHkgY2xvdWR5DQoqMjoqIE1pc3QgKyBDbG91ZHksIE1pc3QgKyBCcm9rZW4gY2xvdWRzLCBNaXN0ICsgRmV3IGNsb3VkcywgTWlzdCANCiozOiogTGlnaHQgU25vdywgTGlnaHQgUmFpbiArIFRodW5kZXJzdG9ybSArIFNjYXR0ZXJlZCBjbG91ZHMsIExpZ2h0IFJhaW4gKyBTY2F0dGVyZWQgY2xvdWRzIA0KKjQ6KiBIZWF2eSBSYWluICsgSWNlIFBhbGxldHMgKyBUaHVuZGVyc3Rvcm0gKyBNaXN0LCBTbm93ICsgRm9nIA0KICAgICAgICAgICAgDQoqKnRlbXAqKiAtIHRlbXBlcmF0dXJlIGluIENlbHNpdXMNCg0KKiphdGVtcCoqIC0gImZlZWxzIGxpa2UiIHRlbXBlcmF0dXJlIGluIENlbHNpdXMNCg0KKipodW1pZGl0eSoqIC0gcmVsYXRpdmUgaHVtaWRpdHkNCg0KKip3aW5kc3BlZWQqKiAtIHdpbmQgc3BlZWQNCg0KKipjYXN1YWwqKiAtIG51bWJlciBvZiBub24tcmVnaXN0ZXJlZCB1c2VyIHJlbnRhbHMgaW5pdGlhdGVkDQoNCioqcmVnaXN0ZXJlZCoqIC0gbnVtYmVyIG9mIHJlZ2lzdGVyZWQgdXNlciByZW50YWxzIGluaXRpYXRlZA0KDQoqKmNvdW50KiogLSBudW1iZXIgb2YgdG90YWwgcmVudGFscw0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KE1BU1MpDQpgYGANCg0KDQpgYGB7cn0NCnNlYXNvbng8LTINCmJpY2lfZGF0YTwtDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSANCmBgYA0KDQoNCmBgYHtyfQ0KaGlzdChiaWNpX2RhdGEkYXRlbXApDQpgYGANCg0KYGBge3J9DQpoaXN0KGJpY2lfZGF0YSRodW0pDQpgYGANCg0KDQoNCmBgYHtyfQ0KYmljaV9kYXRhICU+JSANCiAgZ2dwbG90KGFlcyhhdGVtcCkpKw0KICBnZW9tX2hpc3RvZ3JhbShiaW5zPTMwLCBhZXMoeSA9IC4uZGVuc2l0eS4uKSApKw0KICBnZW9tX3J1ZygpKw0KICBnZW9tX2RlbnNpdHkoKQ0KYGBgDQoNCg0KYGBge3J9DQpiaWNpX2RhdGEgJT4lIA0KICBnZ3Bsb3QoYWVzKGh1bSkpKw0KICBnZW9tX2hpc3RvZ3JhbShiaW5zPTMwLCBhZXMoeSA9IC4uZGVuc2l0eS4uKSApKw0KICBnZW9tX3J1ZygpKw0KICBnZW9tX2RlbnNpdHkoKQ0KYGBgDQoNCiNHcmFmaWNhIGRlIGNvbnRvcm5vIHNwcmluZw0KDQoNCmBgYHtyfQ0Kc2Vhc29ueDwtMQ0KYmljaV9kYXRhPC0NCmJpY2kgJT4lICANCiAgZHBseXI6OnNlbGVjdChzZWFzb24sIGF0ZW1wLCBodW0sIGNudCkgJT4lIA0KICBmaWx0ZXIoc2Vhc29uID09IHNlYXNvbngpICU+JQ0KICBncm91cF9ieShhdGVtcCxodW0pDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSAlPiUNCiAgZ2dwbG90KCBhZXMoYXRlbXAsIGh1bSkgKSArDQogIGdlb21fcmFzdGVyKGFlcyhmaWxsPWNudCksIGludGVycG9sYXRlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KHNpemU9MC4xKSsNCiAgZ2VvbV9kZW5zaXR5XzJkKCkrDQogIGdlb21fcnVnKCkNCiAgDQpgYGANCg0KDQpgYGB7cn0NCmJpY2lfZGVuc2l0eSA8LSBrZGUyZChiaWNpX2RhdGEkYXRlbXAsYmljaV9kYXRhJGh1bSwgbj0xMDApDQpiaWNpX2RlbnNpdHkkeiA8LSBiaWNpX2RlbnNpdHkkei9zdW0oIGJpY2lfZGVuc2l0eSR6KSANCnN1bShiaWNpX2RlbnNpdHkkeikNCg0KDQpgYGANCg0KI0hlYXRtYXAgc3ByaW5nDQoNCmBgYHtyfQ0KY29sczEgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCJyZWQiLCAid2hpdGUiLCAiYmx1ZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhY2UgPSAiTGFiIikoMjU2KQ0KDQpjb2xzMiA8LSBjb2xvclJhbXBQYWxldHRlKGMoIiNGRkZGRDQiLCAiI0ZFRDk4RSIsICIjRkU5OTI5IiwgIiNEOTVGMEUiLCAiIzk5MzQwNCIpLHNwYWNlPSJMYWIiKSgyNTYpDQoNCmNvbHMzPC1jb2xvclJhbXBQYWxldHRlKGMoImJsYWNrIiwiYmx1ZSIsImdyZWVuIiwib3JhbmdlIiwicmVkIikpKDEwMDApDQoNCg0KaW1hZ2UoYmljaV9kZW5zaXR5JHosICANCiAgICAgIGNvbCA9IGNvbHMzLCANCiAgICAgIHpsaW09YyhtaW4oYmljaV9kZW5zaXR5JHopLCBtYXgoYmljaV9kZW5zaXR5JHopKSkNCg0KYGBgDQoNCg0KI0dyYWZpY2EgZGUgY29udG9ybm8gc3VtbWVyDQoNCmBgYHtyfQ0Kc2Vhc29ueDwtMg0KYmljaV9kYXRhPC0NCmJpY2kgJT4lICANCiAgZHBseXI6OnNlbGVjdChzZWFzb24sIGF0ZW1wLCBodW0sIGNudCkgJT4lIA0KICBmaWx0ZXIoc2Vhc29uID09IHNlYXNvbngpICU+JQ0KICBncm91cF9ieShhdGVtcCxodW0pDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSAlPiUNCiAgZ2dwbG90KCBhZXMoYXRlbXAsIGh1bSkgKSArDQogIGdlb21fcmFzdGVyKGFlcyhmaWxsPWNudCksIGludGVycG9sYXRlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KHNpemU9MC4xKSsNCiAgZ2VvbV9kZW5zaXR5XzJkKCkrDQogIGdlb21fcnVnKCkNCiAgDQpgYGANCg0KYGBge3J9DQpiaWNpX2RlbnNpdHkgPC0ga2RlMmQoYmljaV9kYXRhJGF0ZW1wLGJpY2lfZGF0YSRodW0sIG49MTAwKQ0KYmljaV9kZW5zaXR5JHogPC0gYmljaV9kZW5zaXR5JHovc3VtKCBiaWNpX2RlbnNpdHkkeikgDQpzdW0oYmljaV9kZW5zaXR5JHopDQoNCg0KYGBgDQoNCiNIZWF0bWFwIHN1bW1lcg0KDQpgYGB7cn0NCmNvbHMxIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygicmVkIiwgIndoaXRlIiwgImJsdWUiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlID0gIkxhYiIpKDI1NikNCg0KY29sczIgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCIjRkZGRkQ0IiwgIiNGRUQ5OEUiLCAiI0ZFOTkyOSIsICIjRDk1RjBFIiwgIiM5OTM0MDQiKSxzcGFjZT0iTGFiIikoMjU2KQ0KDQpjb2xzMzwtY29sb3JSYW1wUGFsZXR0ZShjKCJibGFjayIsImJsdWUiLCJncmVlbiIsIm9yYW5nZSIsInJlZCIpKSgxMDAwKQ0KDQoNCmltYWdlKGJpY2lfZGVuc2l0eSR6LCAgDQogICAgICBjb2wgPSBjb2xzMywgDQogICAgICB6bGltPWMobWluKGJpY2lfZGVuc2l0eSR6KSwgbWF4KGJpY2lfZGVuc2l0eSR6KSkpDQoNCmBgYA0KDQojR3JhZmljYSBkZSBjb250b3JubyBmYWxsDQoNCmBgYHtyfQ0Kc2Vhc29ueDwtMw0KYmljaV9kYXRhPC0NCmJpY2kgJT4lICANCiAgZHBseXI6OnNlbGVjdChzZWFzb24sIGF0ZW1wLCBodW0sIGNudCkgJT4lIA0KICBmaWx0ZXIoc2Vhc29uID09IHNlYXNvbngpICU+JQ0KICBncm91cF9ieShhdGVtcCxodW0pDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSAlPiUNCiAgZ2dwbG90KCBhZXMoYXRlbXAsIGh1bSkgKSArDQogIGdlb21fcmFzdGVyKGFlcyhmaWxsPWNudCksIGludGVycG9sYXRlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KHNpemU9MC4xKSsNCiAgZ2VvbV9kZW5zaXR5XzJkKCkrDQogIGdlb21fcnVnKCkNCiAgDQpgYGANCg0KYGBge3J9DQpiaWNpX2RlbnNpdHkgPC0ga2RlMmQoYmljaV9kYXRhJGF0ZW1wLGJpY2lfZGF0YSRodW0sIG49MTAwKQ0KYmljaV9kZW5zaXR5JHogPC0gYmljaV9kZW5zaXR5JHovc3VtKCBiaWNpX2RlbnNpdHkkeikgDQpzdW0oYmljaV9kZW5zaXR5JHopDQoNCg0KYGBgDQoNCiNIZWF0bWFwIGZhbGwNCg0KYGBge3J9DQpjb2xzMSA8LSBjb2xvclJhbXBQYWxldHRlKGMoInJlZCIsICJ3aGl0ZSIsICJibHVlIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjZSA9ICJMYWIiKSgyNTYpDQoNCmNvbHMyIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygiI0ZGRkZENCIsICIjRkVEOThFIiwgIiNGRTk5MjkiLCAiI0Q5NUYwRSIsICIjOTkzNDA0Iiksc3BhY2U9IkxhYiIpKDI1NikNCg0KY29sczM8LWNvbG9yUmFtcFBhbGV0dGUoYygiYmxhY2siLCJibHVlIiwiZ3JlZW4iLCJvcmFuZ2UiLCJyZWQiKSkoMTAwMCkNCg0KDQppbWFnZShiaWNpX2RlbnNpdHkkeiwgIA0KICAgICAgY29sID0gY29sczMsIA0KICAgICAgemxpbT1jKG1pbihiaWNpX2RlbnNpdHkkeiksIG1heChiaWNpX2RlbnNpdHkkeikpKQ0KDQpgYGANCg0KI0dyYWZpY2EgZGUgY29udG9ybm8gd2ludGVyDQoNCmBgYHtyfQ0Kc2Vhc29ueDwtNA0KYmljaV9kYXRhPC0NCmJpY2kgJT4lICANCiAgZHBseXI6OnNlbGVjdChzZWFzb24sIGF0ZW1wLCBodW0sIGNudCkgJT4lIA0KICBmaWx0ZXIoc2Vhc29uID09IHNlYXNvbngpICU+JQ0KICBncm91cF9ieShhdGVtcCxodW0pDQpiaWNpICU+JSAgDQogIGRwbHlyOjpzZWxlY3Qoc2Vhc29uLCBhdGVtcCwgaHVtLCBjbnQpICU+JSANCiAgZmlsdGVyKHNlYXNvbiA9PSBzZWFzb254KSAlPiUNCiAgZ3JvdXBfYnkoYXRlbXAsaHVtKSAlPiUNCiAgZ2dwbG90KCBhZXMoYXRlbXAsIGh1bSkgKSArDQogIGdlb21fcmFzdGVyKGFlcyhmaWxsPWNudCksIGludGVycG9sYXRlID0gRkFMU0UpKw0KICBnZW9tX3BvaW50KHNpemU9MC4xKSsNCiAgZ2VvbV9kZW5zaXR5XzJkKCkrDQogIGdlb21fcnVnKCkNCiAgDQpgYGANCg0KYGBge3J9DQpiaWNpX2RlbnNpdHkgPC0ga2RlMmQoYmljaV9kYXRhJGF0ZW1wLGJpY2lfZGF0YSRodW0sIG49MTAwKQ0KYmljaV9kZW5zaXR5JHogPC0gYmljaV9kZW5zaXR5JHovc3VtKCBiaWNpX2RlbnNpdHkkeikgDQpzdW0oYmljaV9kZW5zaXR5JHopDQoNCg0KYGBgDQoNCiNIZWF0bWFwIHdpbnRlcg0KDQpgYGB7cn0NCmNvbHMxIDwtIGNvbG9yUmFtcFBhbGV0dGUoYygicmVkIiwgIndoaXRlIiwgImJsdWUiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlID0gIkxhYiIpKDI1NikNCg0KY29sczIgPC0gY29sb3JSYW1wUGFsZXR0ZShjKCIjRkZGRkQ0IiwgIiNGRUQ5OEUiLCAiI0ZFOTkyOSIsICIjRDk1RjBFIiwgIiM5OTM0MDQiKSxzcGFjZT0iTGFiIikoMjU2KQ0KDQpjb2xzMzwtY29sb3JSYW1wUGFsZXR0ZShjKCJibGFjayIsImJsdWUiLCJncmVlbiIsIm9yYW5nZSIsInJlZCIpKSgxMDAwKQ0KDQoNCmltYWdlKGJpY2lfZGVuc2l0eSR6LCAgDQogICAgICBjb2wgPSBjb2xzMywgDQogICAgICB6bGltPWMobWluKGJpY2lfZGVuc2l0eSR6KSwgbWF4KGJpY2lfZGVuc2l0eSR6KSkpDQoNCmBgYA0KDQpgYGB7cn0NCnN0cihiaWNpX2RlbnNpdHkpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KZmlsdGVyWDwtYmljaV9kZW5zaXR5JHg+PTAuNQ0KZmlsdGVyWTwtYmljaV9kZW5zaXR5JHk8PTAuMw0KYmljaV9kZW5zaXR5JHpbZmlsdGVyWCxmaWx0ZXJZXSAlPiUgc3VtKCkNCmBgYA0KDQpgYGB7cn0NCmZpbHRlclg8LWJpY2lfZGVuc2l0eSR4Pj0wLjQgJiBiaWNpX2RlbnNpdHkkeDw9MC44DQpmaWx0ZXJZPC1iaWNpX2RlbnNpdHkkeT49MC42ICYgYmljaV9kZW5zaXR5JHk8PTAuODUNCmJpY2lfZGVuc2l0eSR6W2ZpbHRlclgsZmlsdGVyWV0gJT4lIHN1bSgpDQpgYGANCg0KDQoNCmBgYHtyfQ0KYmljaV9kYXRhPC0NCiAgYmljaSAlPiUNCiAgZHBseXI6OnNlbGVjdChzZWFzb24sYXRlbXAsaHVtLGNudCklPiUNCiAgZmlsdGVyKHNlYXNvbj09NCkNCiMjYmljaV9kZW5zaXR5JHkNCng8LW1hdHJpeChyZXAoYmljaV9kZW5zaXR5JHksMyksbnJvdyA9IDMsIGJ5cm93ID0gVFJVRSkNCnN1bSh4KmJpY2lfZGVuc2l0eSR5KQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShleHBtKQ0KcDwtcmJpbmQoYygxLDAsMCwwKSxjKDAuNSwwLDAuNSwwKSxjKDAsMC41LDAsMC41KSxjKDAsMCwwLDEpKQ0KdzwtbWF0cml4KHAsbnJvdyA9IDQpDQpjKDAsMCwxLDApICUqJSAocCVeJTIwKQ0KYGBgDQoNCg==