Entregable 2.4 Equipo 2

3. Delivery Plan

EQUIPO 2: Jimena Miguel | Vanessa Elizondo | Ricardo Galicia | José Luis Elizondo | Daniela Cárdenas

Importar la base de datos

#file.choose()
delivery<-read.csv("/Users/vanessaelizondo/Desktop/Tec/Semestre 7/FORM/DELIVERY PLAN bd_Prueba.csv")
summary(delivery)
##     ID_Fecha        Fecha             CLIENTE             Pedidos       
##  Min.   : 1.00   Length:228         Length:228         Min.   :    0.0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:    0.0  
##  Median : 6.50   Mode  :character   Mode  :character   Median :    0.0  
##  Mean   : 6.50                                         Mean   : 1703.1  
##  3rd Qu.: 9.25                                         3rd Qu.:  233.8  
##  Max.   :12.00                                         Max.   :52779.0

Observaciones

1.Se hizo limpieza manual de la base de datos para acomodar los clientes como variables y las fechas como registros.

2.Se sustituyeron NAs por cero.

3.Se eliminaron columnas no usadas y que no agreegan valor para el analisis que se busca hacer.

Descargar librerías y paquetes

library(foreign)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(forcats)
library(ggplot2)
library(readr)
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(naniar)
library(dlookr)
## 
## Attaching package: 'dlookr'
## The following object is masked from 'package:base':
## 
##     transform

Cuantas variables y registros hay

str(delivery)
## 'data.frame':    228 obs. of  4 variables:
##  $ ID_Fecha: int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Fecha   : chr  "31/01/22" "31/01/22" "31/01/22" "31/01/22" ...
##  $ CLIENTE : chr  "STB3" "STB 1" "YF RAMOS" "INOAC POLYTEC" ...
##  $ Pedidos : int  481 0 227 0 400 328 393 0 8975 449 ...

Contamos con 3 variables y 380 observaciones.

Contar total de pedidos por cliente

deliverySUM = colSums(delivery[4])

as.data.frame(deliverySUM)
##         deliverySUM
## Pedidos      388317

Contamos con 52,0281 pedidos

#file.choose()
deliveryCLIENTS<-read.csv("/Users/vanessaelizondo/Desktop/Tec/Semestre 7/FORM/CSV/DELIVERY PLAN bd_entrega2.4.csv")
summary(deliveryCLIENTS)
##     Fecha                STB3            STB.1           YF.RAMOS   
##  Length:19          Min.   :   0.0   Min.   : 0.000   Min.   :   0  
##  Class :character   1st Qu.:  13.5   1st Qu.: 0.000   1st Qu.:  54  
##  Mode  :character   Median : 200.0   Median : 0.000   Median : 100  
##                     Mean   : 297.1   Mean   : 2.632   Mean   : 211  
##                     3rd Qu.: 460.5   3rd Qu.: 0.000   3rd Qu.: 230  
##                     Max.   :1015.0   Max.   :50.000   Max.   :1243  
##  INOAC.POLYTEC       MERIDIAN     YANFENG.sm          YFTO       
##  Min.   : 0.000   Min.   :  0   Min.   :  0.00   Min.   : 138.0  
##  1st Qu.: 0.000   1st Qu.:  0   1st Qu.:  0.00   1st Qu.: 358.5  
##  Median : 0.000   Median :  0   Median : 41.00   Median : 628.0  
##  Mean   : 2.684   Mean   : 33   Mean   : 95.05   Mean   : 869.6  
##  3rd Qu.: 0.000   3rd Qu.:  0   3rd Qu.:142.50   3rd Qu.: 871.5  
##  Max.   :40.000   Max.   :400   Max.   :328.00   Max.   :2556.0  
##      YF.QRO            TRMX           DENSO           SEGROVE      
##  Min.   : 0.000   Min.   :    0   Min.   :   0.0   Min.   :  0.00  
##  1st Qu.: 0.000   1st Qu.: 2822   1st Qu.: 150.5   1st Qu.:  0.00  
##  Median : 0.000   Median : 6240   Median : 372.0   Median :  0.00  
##  Mean   : 2.737   Mean   : 5796   Mean   :1241.3   Mean   : 38.74  
##  3rd Qu.: 0.000   3rd Qu.: 8374   3rd Qu.:1083.0   3rd Qu.:  0.00  
##  Max.   :36.000   Max.   :11833   Max.   :8834.0   Max.   :736.00  
##      HANON        ANTOLIN.TOLUCA ANTOLIN.ARTEAGA     HELLA      
##  Min.   :  0.00   Min.   :0      Min.   :0       Min.   :    0  
##  1st Qu.:  0.00   1st Qu.:0      1st Qu.:0       1st Qu.: 4160  
##  Median :  0.00   Median :0      Median :0       Median : 8580  
##  Mean   : 21.58   Mean   :0      Mean   :0       Mean   :15013  
##  3rd Qu.:  0.00   3rd Qu.:0      3rd Qu.:0       3rd Qu.:21191  
##  Max.   :360.00   Max.   :0      Max.   :0       Max.   :52779  
##       UFI              ISRI            TRMX.1  ABC.QUERETARO        VARROC    
##  Min.   :  0.00   Min.   :   0.0   Min.   :0   Min.   :0.0000   Min.   :   0  
##  1st Qu.:  0.00   1st Qu.:   0.0   1st Qu.:0   1st Qu.:0.0000   1st Qu.:2078  
##  Median :  0.00   Median :   0.0   Median :0   Median :0.0000   Median :3509  
##  Mean   : 45.74   Mean   : 157.9   Mean   :0   Mean   :0.4211   Mean   :3555  
##  3rd Qu.:  3.50   3rd Qu.:   0.0   3rd Qu.:0   3rd Qu.:0.0000   3rd Qu.:4974  
##  Max.   :492.00   Max.   :3000.0   Max.   :0   Max.   :8.0000   Max.   :8810  
##  Total.pedidos.mes 
##  Length:19         
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
deliveryCLIENTS = colSums(deliveryCLIENTS[2:21])
as.data.frame(deliveryCLIENTS)
##                 deliveryCLIENTS
## STB3                       5644
## STB.1                        50
## YF.RAMOS                   4009
## INOAC.POLYTEC                51
## MERIDIAN                    627
## YANFENG.sm                 1806
## YFTO                      16522
## YF.QRO                       52
## TRMX                     110127
## DENSO                     23584
## SEGROVE                     736
## HANON                       410
## ANTOLIN.TOLUCA                0
## ANTOLIN.ARTEAGA               0
## HELLA                    285238
## UFI                         869
## ISRI                       3000
## TRMX.1                        0
## ABC.QUERETARO                 8
## VARROC                    67548
barplot.default(deliveryCLIENTS)

Con este plot podemos ver que hay muchos clientes con muy pocos pedidos.

Técnicas de Limpieza

Técnica 1: eliminar NAs

Se decidió realizar está técnica para asegurarnos de que no se tenga falta de datos y en caso de tenerlos evitar que estas eviten tener un analisis asertivo al no agregar valor a la base de datos.

¿Cuantos NA tengo en la base de datos?

sum(is.na(delivery))
## [1] 0

Cuantos NA tengo por variable?

Sapply: Para contar los NA.

sapply(delivery, function(x) sum(is.na(x)))
## ID_Fecha    Fecha  CLIENTE  Pedidos 
##        0        0        0        0

Se encontró un solo NA

Técnica 2: eliminar filas

Se decidó realizar está técnica para eliminar los clientes que tienen menos de 5,000 pedidos.

Eliminar filas con el nombre de los clientes que se desean eliminar.

#delivery1 <- subset (delivery1,  CLIENTE == "STB3") #Para conservar ciertas filas

delivery1<-delivery

delivery1<-delivery1[delivery1$CLIENTE!="STB 1", ]
delivery1<-delivery1[delivery1$CLIENTE!="YF RAMOS", ]
delivery1<-delivery1[delivery1$CLIENTE!="INOAC POLYTEC", ]
delivery1<-delivery1[delivery1$CLIENTE!="MERIDIAN", ]
delivery1<-delivery1[delivery1$CLIENTE!="YANFENG sm", ]
delivery1<-delivery1[delivery1$CLIENTE!="YF QRO", ]
delivery1<-delivery1[delivery1$CLIENTE!="SEGROVE", ]
delivery1<-delivery1[delivery1$CLIENTE!="HANON", ]
delivery1<-delivery1[delivery1$CLIENTE!="ANTOLIN TOLUCA", ]
delivery1<-delivery1[delivery1$CLIENTE!="ANTOLIN ARTEAGA", ]
delivery1<-delivery1[delivery1$CLIENTE!="ABC QUERETARO", ]
delivery1<-delivery1[delivery1$CLIENTE!="UFI", ]
delivery1<-delivery1[delivery1$CLIENTE!="ISRI", ]

summary(delivery1)
##     ID_Fecha        Fecha             CLIENTE             Pedidos     
##  Min.   : 1.00   Length:72          Length:72          Min.   :    0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:   99  
##  Median : 6.50   Mode  :character   Mode  :character   Median : 1009  
##  Mean   : 6.50                                         Mean   : 5339  
##  3rd Qu.: 9.25                                         3rd Qu.: 5928  
##  Max.   :12.00                                         Max.   :52779

Tabla de Media, Moda y Mediana

describe(delivery1)
## # A tibble: 2 × 26
##   describ…¹     n    na   mean     sd se_mean    IQR skewn…² kurto…³   p00   p01
##   <chr>     <int> <int>  <dbl>  <dbl>   <dbl>  <dbl>   <dbl>   <dbl> <dbl> <dbl>
## 1 ID_Fecha     72     0    6.5 3.48e0 4.10e-1    5.5    0      -1.22     1     1
## 2 Pedidos      72     0 5339.  1.01e4 1.19e+3 5830.     3.13   10.7      0     0
## # … with 15 more variables: p05 <dbl>, p10 <dbl>, p20 <dbl>, p25 <dbl>,
## #   p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>, p75 <dbl>,
## #   p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and abbreviated
## #   variable names ¹​described_variables, ²​skewness, ³​kurtosis

Identificar variables

Cuantitativa: Discreta, Continua Escala de medición:Intervalo, Razón Cualitativa Escala de medición: Nominales, Ordinales

Variable<-c("Fecha","STB3","YFTO", "TRMX", "DENSO","HELLA","VARROC","Total.pedidos.mes")
Type<-c("Cuantitativa (discreta)", "Cualitativa", "Cualitativa", "Cualitativa","Cualitativa","Cualitativa","Cualitativa","Cuantitativa (discreta)")
Measurement<-c("Razón","Nominal","Nominal","Nominal","Nominal","Nominal","Nominal","Razón")
table<-data_frame(Variable,Type,Measurement)
## Warning: `data_frame()` was deprecated in tibble 1.1.0.
## Please use `tibble()` instead.
knitr::kable(table)
Variable Type Measurement
Fecha Cuantitativa (discreta) Razón
STB3 Cualitativa Nominal
YFTO Cualitativa Nominal
TRMX Cualitativa Nominal
DENSO Cualitativa Nominal
HELLA Cualitativa Nominal
VARROC Cualitativa Nominal
Total.pedidos.mes Cuantitativa (discreta) Razón

Gráfica Cualitativa

#install.packages("plyr")
library(plyr)
## ------------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## ------------------------------------------------------------------------------
## 
## Attaching package: 'plyr'
## The following objects are masked from 'package:dplyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
delivery2<-delivery1

delivery2<- aggregate(delivery2$Pedidos, by=list(category=delivery2$CLIENTE), FUN=sum)
pie(delivery2$x, labels = delivery2$category)

Con esta gráfica podemos darnos cuenta de los clientes que tienen mayores pedidos y en este caso es HELLA en primer lugar y TRMX en segundo lugar.

Gráfica Cuantitativa

delivery2<-delivery2 %>% dplyr::rename(pedidos="x")
delivery2<-delivery2 %>% dplyr::rename(Clientes="category")

delivery2$Clientes<-as.factor(delivery2$Clientes)
ggplot(delivery2, aes(x=Clientes, y=pedidos, fill=pedidos))+
         geom_bar(stat="identity")+
         theme_minimal()+
         labs(title="Pedidos por cliente")

Esta gráfica sirve para tener de manera más visual el impacto que tiene cada uno de los clientes en la empresa FORM. Podemos ver que HELLA es el cliente más significativo con casi el triple de pedidos que el siguiente cliente con mayores pedidos, TRMX. De lado derecho se tiene un legend que muestra la tonalidad de los plots para ver que tantos pedidos tiene, por ello HELLAS tiene un color azul claro, representando más de 250,000 pedidos.

Comportamiento de clientes por fecha

summary(delivery1)
##     ID_Fecha        Fecha             CLIENTE             Pedidos     
##  Min.   : 1.00   Length:72          Length:72          Min.   :    0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:   99  
##  Median : 6.50   Mode  :character   Mode  :character   Median : 1009  
##  Mean   : 6.50                                         Mean   : 5339  
##  3rd Qu.: 9.25                                         3rd Qu.: 5928  
##  Max.   :12.00                                         Max.   :52779
ggplot(delivery1,aes(x=ID_Fecha, y=Pedidos, group=CLIENTE,colour=CLIENTE))+
  geom_line()+
  ggtitle("Pedidos por cliente")

Con esta gráfica utilizamos el ID Fecha para conocer los pedidos que se tiene por cliente cada mes y vemos un significativo incremento de pedidos en el mes de septiembre y octubre. contamos con un legen que indica cada línea con un color para nombrar la información de cada uno de los clientes.

Gráfica Boxplot

boxplot(delivery1$Pedidos, main= "Pedidos")

delivery3<-delivery1
delivery3$CLIENTE <-as.factor(delivery3$CLIENTE)
ggplot(delivery3, aes(x=CLIENTE, y=Pedidos))+
  geom_boxplot(color="blue", fill="purple")

En esta gráfica podemos visualizarcuantos pedidos tiene programados cada cliente y los clientes que sobre salen son HELLA y TRMX, algo muy relevante en esta gráfica es que se muestra la mediana de cada uno, así como también la minima de pedidos y la máxima, y en este caso se tiene autliers en los pedidos de los clientes DENSO, TRMX, YFTO lo que nos dice que en ciertas ocasiones se tuvieron pedidos sin estar en el rango de lo que normalmente pide. También se tuvo dispersión principalmente en tres clientes, HELLA, TRMX y VARROC, por otro lado los otros clientes tienen menos dispersión cerca de la media. Esta gráfica nos indica que la cantidad de pedidos que hacen suele variar más en algunos clientes es muy constante.

Conclusión - Delivery Plan

Para realizar el análisis de la base de datos de “Delivery Plan” fué necesario primero hacer un arreglo de la base de datos de manera manual en el excel. Estó para simplificar el uso de la base de datos y permitir que R pueda analizarla y extraer los datos para generar gráficas. Después aplicamos dos diferentes bases de datos, nos aseguramos de que no haya NAs y eliminamos filas que correspondían a los clientes que tenían menos de 5,000 pedidos. Nos quedamos con una base de datos con los 6 clientes más significativos para FORM. Continuamos identificando las variables en dónde 6 de 8 variables eran cualitativas al ser los clientes de FORM.

Graficamos una gráfica de Pie para identificar de manera visual los mayores clientes, los que vienen siendo HELLA y TRMX. También hicimos un “Barplot” para mostrar la cantidad de pedidos programados que tiene cada cliente, Hella siendo el cliente con mayor pedidos con más de 225,000 y TRMX siguiendo con 80,000. Decidimos también visualizar el comportamiento de los clientes según la fecha y nos dimos cuenta que entre el mes de septiembre y octubre hubo un incremento de pedidos establecidos. Y por último se realizó el “Boxplot” para de ese modo ver de manera precisa la moda de clos pedidos que suele hacer cada uno de los clientes.

Reflexión Final:

¿Qué es Business Analytics? Es una combinación de habilidades, tecnologías y prácticas para la exploración e investigación del funcionamiento y los procesos empresariales que se han tenido anteriormente por un empresa, para de ese modo obtener información, poder analizar dicha información que se extrae y así impulsar la planificación estratégica empresarial. Business Analytics puede descubrir patrones y predecir tendencias considerando diferentes factores.

Existen diferentes rubros del “Business Analytics”:

  1. Análisis Descriptivo

  2. Análisis de Diagnóstico

  3. Análisis Predictivo

  4. Análisis Prescriptivo

3 objetivos deL uso de la herramienta de Business Analytics? 1. Determinar qué conjuntos de datos son significantes y útiles para poder analizar y conocer el desempeño de la empresa y cuáles pueden aumentar los ingresos y disminuir los costos.

  • Ejemplo: productividad y eficencia.
  1. Analizar y transformar los datos en información útil, identificar y anticipar tendencias y resultados. Simplificar información para hacerla más sencilla de entender y visual.

  2. Tomar decisiones empresariales más inteligentes basadas en datos.

  • Ejemplo: Análisis del comportamiento de los clientes, disminución de costo, evitar mermas, aprovechamiento de tiempos y materiales, eficiencia y eficacia.

¿Cuál es la relación entre Business Analytics y Business Intelligence? BI sirve para evaluar, optimizar y coordinar las operaciones internas de una empresa. Trata de aprovechar todo el potencial de los datos que genera una empresa en todas sus actividades diarias y analizar estos datos para obtener información de valor sobre la toma de decisiones.Ayuda para entender el histórico y el como evolucionan los datos. Y como mencionamos anteriormente Business Analytics con el analisis de la información de una empresa logra puede llegar a desubrir patrones, explicaciones del porque de los mismos y predecir tendencias o hechos que pueden llegar a pasar en el negocio.

Estos dos términos tienen una alta relación entre ellas ya que en pocas palabras la Inteligencia de Negocios es el hacer análisis de los datos obtenidos y Analítica de Negocios es predicción a partir de los datos que se obtuvieron con el análisis. Una con lleva a la otra y trabajan juntas para obtener el resultado buscado de un análisis de datos que contenga la información relevante y significativa que nos pueda mostrar predicciones del comportamiento ya sea de la empresa, de la economía, de los ingresos, de los clientes y más. Ambas son necesarias para extraer un buen análisis de la información de una empresa, ya que una analis dos, los organiza y extra aquellos relevantes y la otra puede lograr las pedicciones y análisis.

LS0tCnRpdGxlOiA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKkVudHJlZ2FibGUgMi40IEZPUk0qKgphdXRob3I6ICJFcXVpcG8gMiIKZGF0ZTogIjIwMjItMTAtMDMiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBjb3NtbwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCjxpbWcgc3JjPSAiL1VzZXJzL3ZhbmVzc2FlbGl6b25kby9EZXNrdG9wL1RlYy9TZW1lc3RyZSA3L0VudHJlZ2EgMy4xL2ZvdG9zL0xvZ28gRk9STS5qcGVnIj4gCgojICoqRW50cmVnYWJsZSAyLjQgRXF1aXBvIDIqKgoKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKjMuIERlbGl2ZXJ5IFBsYW4qKiAKCiMjIEVRVUlQTyAyOiBKaW1lbmEgTWlndWVsIHwgVmFuZXNzYSBFbGl6b25kbyB8IFJpY2FyZG8gR2FsaWNpYSB8IEpvc8OpIEx1aXMgRWxpem9uZG8gfCBEYW5pZWxhIEPDoXJkZW5hcwoKIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6b3JhbmdlIj4qKkltcG9ydGFyIGxhIGJhc2UgZGUgZGF0b3MqKiAKYGBge3J9CiNmaWxlLmNob29zZSgpCmRlbGl2ZXJ5PC1yZWFkLmNzdigiL1VzZXJzL3ZhbmVzc2FlbGl6b25kby9EZXNrdG9wL1RlYy9TZW1lc3RyZSA3L0ZPUk0vREVMSVZFUlkgUExBTiBiZF9QcnVlYmEuY3N2IikKc3VtbWFyeShkZWxpdmVyeSkKYGBgCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPioqT2JzZXJ2YWNpb25lcyoqIAoKMS4qU2UgaGl6byBsaW1waWV6YSBtYW51YWwgZGUgbGEgYmFzZSBkZSBkYXRvcyBwYXJhIGFjb21vZGFyIGxvcyBjbGllbnRlcyBjb21vIHZhcmlhYmxlcyB5IGxhcyBmZWNoYXMgY29tbyByZWdpc3Ryb3MuKiAKCjIuKlNlIHN1c3RpdHV5ZXJvbiBOQXMgcG9yIGNlcm8uKgoKMy4qU2UgZWxpbWluYXJvbiBjb2x1bW5hcyBubyB1c2FkYXMgeSBxdWUgbm8gYWdyZWVnYW4gdmFsb3IgcGFyYSBlbCBhbmFsaXNpcyBxdWUgc2UgYnVzY2EgaGFjZXIuKgoKIyMgKkRlc2NhcmdhciBsaWJyZXLDrWFzIHkgcGFxdWV0ZXMqCmBgYHtyfQpsaWJyYXJ5KGZvcmVpZ24pCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkobmFuaWFyKQpsaWJyYXJ5KGRsb29rcikKYGBgCgojIyAqQ3VhbnRhcyB2YXJpYWJsZXMgeSByZWdpc3Ryb3MgaGF5KgpgYGB7cn0Kc3RyKGRlbGl2ZXJ5KQpgYGAKKkNvbnRhbW9zIGNvbiAzIHZhcmlhYmxlcyB5IDM4MCBvYnNlcnZhY2lvbmVzLiogCgojIyAqQ29udGFyIHRvdGFsIGRlIHBlZGlkb3MgcG9yIGNsaWVudGUqCmBgYHtyfQpkZWxpdmVyeVNVTSA9IGNvbFN1bXMoZGVsaXZlcnlbNF0pCgphcy5kYXRhLmZyYW1lKGRlbGl2ZXJ5U1VNKQpgYGAKKkNvbnRhbW9zIGNvbiA1MiwwMjgxIHBlZGlkb3MqCgpgYGB7cn0KI2ZpbGUuY2hvb3NlKCkKZGVsaXZlcnlDTElFTlRTPC1yZWFkLmNzdigiL1VzZXJzL3ZhbmVzc2FlbGl6b25kby9EZXNrdG9wL1RlYy9TZW1lc3RyZSA3L0ZPUk0vQ1NWL0RFTElWRVJZIFBMQU4gYmRfZW50cmVnYTIuNC5jc3YiKQpzdW1tYXJ5KGRlbGl2ZXJ5Q0xJRU5UUykKCmRlbGl2ZXJ5Q0xJRU5UUyA9IGNvbFN1bXMoZGVsaXZlcnlDTElFTlRTWzI6MjFdKQphcy5kYXRhLmZyYW1lKGRlbGl2ZXJ5Q0xJRU5UUykKYmFycGxvdC5kZWZhdWx0KGRlbGl2ZXJ5Q0xJRU5UUykKYGBgCgoqQ29uIGVzdGUgcGxvdCBwb2RlbW9zIHZlciBxdWUgaGF5IG11Y2hvcyBjbGllbnRlcyBjb24gbXV5IHBvY29zIHBlZGlkb3MuKgoKIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6b3JhbmdlIj4qKlTDqWNuaWNhcyBkZSBMaW1waWV6YSoqIAoKIyMjIFTDqWNuaWNhIDE6IGVsaW1pbmFyIE5BcwoqU2UgZGVjaWRpw7MgcmVhbGl6YXIgZXN0w6EgdMOpY25pY2EgcGFyYSBhc2VndXJhcm5vcyBkZSBxdWUgbm8gc2UgdGVuZ2EgZmFsdGEgZGUgZGF0b3MgeSBlbiBjYXNvIGRlIHRlbmVybG9zIGV2aXRhciBxdWUgZXN0YXMgZXZpdGVuIHRlbmVyIHVuIGFuYWxpc2lzIGFzZXJ0aXZvIGFsIG5vIGFncmVnYXIgdmFsb3IgYSBsYSBiYXNlIGRlIGRhdG9zLioKCiMjIyMgwr9DdWFudG9zIE5BIHRlbmdvIGVuIGxhIGJhc2UgZGUgZGF0b3M/CmBgYHtyfQpzdW0oaXMubmEoZGVsaXZlcnkpKQpgYGAKCiMjIyMgQ3VhbnRvcyBOQSB0ZW5nbyBwb3IgdmFyaWFibGU/CioqU2FwcGx5OioqIFBhcmEgY29udGFyIGxvcyBOQS4KYGBge3J9CnNhcHBseShkZWxpdmVyeSwgZnVuY3Rpb24oeCkgc3VtKGlzLm5hKHgpKSkKYGBgCipTZSBlbmNvbnRyw7MgdW4gc29sbyBOQSoKCiMjIyBUw6ljbmljYSAyOiBlbGltaW5hciBmaWxhcyAKKlNlIGRlY2lkw7MgcmVhbGl6YXIgZXN0w6EgdMOpY25pY2EgcGFyYSBlbGltaW5hciBsb3MgY2xpZW50ZXMgcXVlIHRpZW5lbiBtZW5vcyBkZSAqKjUsMDAwKiogcGVkaWRvcy4qCgojIyMjIEVsaW1pbmFyIGZpbGFzIGNvbiBlbCBub21icmUgZGUgbG9zIGNsaWVudGVzIHF1ZSBzZSBkZXNlYW4gZWxpbWluYXIuIApgYGB7cn0KCiNkZWxpdmVyeTEgPC0gc3Vic2V0IChkZWxpdmVyeTEsICBDTElFTlRFID09ICJTVEIzIikgI1BhcmEgY29uc2VydmFyIGNpZXJ0YXMgZmlsYXMKCmRlbGl2ZXJ5MTwtZGVsaXZlcnkKCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iU1RCIDEiLCBdCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iWUYgUkFNT1MiLCBdCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iSU5PQUMgUE9MWVRFQyIsIF0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJNRVJJRElBTiIsIF0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJZQU5GRU5HIHNtIiwgXQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IllGIFFSTyIsIF0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJTRUdST1ZFIiwgXQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IkhBTk9OIiwgXQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IkFOVE9MSU4gVE9MVUNBIiwgXQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IkFOVE9MSU4gQVJURUFHQSIsIF0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJBQkMgUVVFUkVUQVJPIiwgXQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IlVGSSIsIF0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJJU1JJIiwgXQoKc3VtbWFyeShkZWxpdmVyeTEpCmBgYAoKCiMjICpUYWJsYSBkZSBNZWRpYSwgTW9kYSB5IE1lZGlhbmEqCmBgYHtyfQpkZXNjcmliZShkZWxpdmVyeTEpCmBgYAoKIyMgKklkZW50aWZpY2FyIHZhcmlhYmxlcyogCgoqKkN1YW50aXRhdGl2YToqKiBEaXNjcmV0YSwgQ29udGludWEKKipFc2NhbGEgZGUgbWVkaWNpw7NuOioqSW50ZXJ2YWxvLCBSYXrDs24gCioqQ3VhbGl0YXRpdmEqKgoqKkVzY2FsYSBkZSBtZWRpY2nDs246KiogTm9taW5hbGVzLCBPcmRpbmFsZXMKCmBgYHtyfQpWYXJpYWJsZTwtYygiRmVjaGEiLCJTVEIzIiwiWUZUTyIsICJUUk1YIiwgIkRFTlNPIiwiSEVMTEEiLCJWQVJST0MiLCJUb3RhbC5wZWRpZG9zLm1lcyIpClR5cGU8LWMoIkN1YW50aXRhdGl2YSAoZGlzY3JldGEpIiwgIkN1YWxpdGF0aXZhIiwgIkN1YWxpdGF0aXZhIiwgIkN1YWxpdGF0aXZhIiwiQ3VhbGl0YXRpdmEiLCJDdWFsaXRhdGl2YSIsIkN1YWxpdGF0aXZhIiwiQ3VhbnRpdGF0aXZhIChkaXNjcmV0YSkiKQpNZWFzdXJlbWVudDwtYygiUmF6w7NuIiwiTm9taW5hbCIsIk5vbWluYWwiLCJOb21pbmFsIiwiTm9taW5hbCIsIk5vbWluYWwiLCJOb21pbmFsIiwiUmF6w7NuIikKdGFibGU8LWRhdGFfZnJhbWUoVmFyaWFibGUsVHlwZSxNZWFzdXJlbWVudCkKCmtuaXRyOjprYWJsZSh0YWJsZSkKYGBgCgojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKkdyw6FmaWNhIEN1YWxpdGF0aXZhKiogCmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlcygicGx5ciIpCmxpYnJhcnkocGx5cikKZGVsaXZlcnkyPC1kZWxpdmVyeTEKCmRlbGl2ZXJ5MjwtIGFnZ3JlZ2F0ZShkZWxpdmVyeTIkUGVkaWRvcywgYnk9bGlzdChjYXRlZ29yeT1kZWxpdmVyeTIkQ0xJRU5URSksIEZVTj1zdW0pCnBpZShkZWxpdmVyeTIkeCwgbGFiZWxzID0gZGVsaXZlcnkyJGNhdGVnb3J5KQpgYGAKCipDb24gZXN0YSBncsOhZmljYSBwb2RlbW9zIGRhcm5vcyBjdWVudGEgZGUgbG9zIGNsaWVudGVzIHF1ZSB0aWVuZW4gbWF5b3JlcyBwZWRpZG9zIHkgZW4gZXN0ZSBjYXNvIGVzIEhFTExBIGVuIHByaW1lciBsdWdhciB5IFRSTVggZW4gc2VndW5kbyBsdWdhci4qCgojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKkdyw6FmaWNhIEN1YW50aXRhdGl2YSoqIApgYGB7cn0KZGVsaXZlcnkyPC1kZWxpdmVyeTIgJT4lIGRwbHlyOjpyZW5hbWUocGVkaWRvcz0ieCIpCmRlbGl2ZXJ5MjwtZGVsaXZlcnkyICU+JSBkcGx5cjo6cmVuYW1lKENsaWVudGVzPSJjYXRlZ29yeSIpCgpkZWxpdmVyeTIkQ2xpZW50ZXM8LWFzLmZhY3RvcihkZWxpdmVyeTIkQ2xpZW50ZXMpCmdncGxvdChkZWxpdmVyeTIsIGFlcyh4PUNsaWVudGVzLCB5PXBlZGlkb3MsIGZpbGw9cGVkaWRvcykpKwogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKwogICAgICAgICB0aGVtZV9taW5pbWFsKCkrCiAgICAgICAgIGxhYnModGl0bGU9IlBlZGlkb3MgcG9yIGNsaWVudGUiKQpgYGAKKkVzdGEgZ3LDoWZpY2Egc2lydmUgcGFyYSB0ZW5lciBkZSBtYW5lcmEgbcOhcyB2aXN1YWwgZWwgaW1wYWN0byBxdWUgdGllbmUgY2FkYSB1bm8gZGUgbG9zIGNsaWVudGVzIGVuIGxhIGVtcHJlc2EgRk9STS4gUG9kZW1vcyB2ZXIgcXVlIEhFTExBIGVzIGVsIGNsaWVudGUgbcOhcyBzaWduaWZpY2F0aXZvIGNvbiBjYXNpIGVsIHRyaXBsZSBkZSBwZWRpZG9zIHF1ZSBlbCBzaWd1aWVudGUgY2xpZW50ZSBjb24gbWF5b3JlcyBwZWRpZG9zLCBUUk1YLiBEZSBsYWRvIGRlcmVjaG8gc2UgdGllbmUgdW4gbGVnZW5kIHF1ZSBtdWVzdHJhIGxhIHRvbmFsaWRhZCBkZSBsb3MgcGxvdHMgcGFyYSB2ZXIgcXVlIHRhbnRvcyBwZWRpZG9zIHRpZW5lLCBwb3IgZWxsbyBIRUxMQVMgdGllbmUgdW4gY29sb3IgYXp1bCBjbGFybywgcmVwcmVzZW50YW5kbyBtw6FzIGRlIDI1MCwwMDAgcGVkaWRvcy4gKgoKIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+KipDb21wb3J0YW1pZW50byBkZSBjbGllbnRlcyBwb3IgZmVjaGEqKiAKYGBge3J9CnN1bW1hcnkoZGVsaXZlcnkxKQoKZ2dwbG90KGRlbGl2ZXJ5MSxhZXMoeD1JRF9GZWNoYSwgeT1QZWRpZG9zLCBncm91cD1DTElFTlRFLGNvbG91cj1DTElFTlRFKSkrCiAgZ2VvbV9saW5lKCkrCiAgZ2d0aXRsZSgiUGVkaWRvcyBwb3IgY2xpZW50ZSIpCmBgYAoKKkNvbiBlc3RhIGdyw6FmaWNhIHV0aWxpemFtb3MgZWwgSUQgRmVjaGEgcGFyYSBjb25vY2VyIGxvcyBwZWRpZG9zIHF1ZSBzZSB0aWVuZSBwb3IgY2xpZW50ZSBjYWRhIG1lcyB5IHZlbW9zIHVuIHNpZ25pZmljYXRpdm8gaW5jcmVtZW50byBkZSBwZWRpZG9zIGVuIGVsIG1lcyBkZSBzZXB0aWVtYnJlIHkgb2N0dWJyZS4gY29udGFtb3MgY29uIHVuIGxlZ2VuIHF1ZSBpbmRpY2EgY2FkYSBsw61uZWEgY29uIHVuIGNvbG9yIHBhcmEgbm9tYnJhciBsYSBpbmZvcm1hY2nDs24gZGUgY2FkYSB1bm8gZGUgbG9zIGNsaWVudGVzLiAqIAoKIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+KipHcsOhZmljYSBCb3hwbG90KiogCmBgYHtyfQpib3hwbG90KGRlbGl2ZXJ5MSRQZWRpZG9zLCBtYWluPSAiUGVkaWRvcyIpCgpkZWxpdmVyeTM8LWRlbGl2ZXJ5MQpkZWxpdmVyeTMkQ0xJRU5URSA8LWFzLmZhY3RvcihkZWxpdmVyeTMkQ0xJRU5URSkKZ2dwbG90KGRlbGl2ZXJ5MywgYWVzKHg9Q0xJRU5URSwgeT1QZWRpZG9zKSkrCiAgZ2VvbV9ib3hwbG90KGNvbG9yPSJibHVlIiwgZmlsbD0icHVycGxlIikKYGBgCgoqRW4gZXN0YSBncsOhZmljYSBwb2RlbW9zIHZpc3VhbGl6YXJjdWFudG9zIHBlZGlkb3MgdGllbmUgcHJvZ3JhbWFkb3MgY2FkYSBjbGllbnRlIHkgbG9zIGNsaWVudGVzIHF1ZSBzb2JyZSBzYWxlbiBzb24gSEVMTEEgeSBUUk1YLCBhbGdvIG11eSByZWxldmFudGUgZW4gZXN0YSBncsOhZmljYSBlcyBxdWUgc2UgbXVlc3RyYSBsYSBtZWRpYW5hIGRlIGNhZGEgdW5vLCBhc8OtIGNvbW8gdGFtYmnDqW4gbGEgbWluaW1hIGRlIHBlZGlkb3MgeSBsYSBtw6F4aW1hLCB5IGVuIGVzdGUgY2FzbyBzZSB0aWVuZSBhdXRsaWVycyBlbiBsb3MgcGVkaWRvcyBkZSBsb3MgY2xpZW50ZXMgREVOU08sIFRSTVgsIFlGVE8gbG8gcXVlIG5vcyBkaWNlIHF1ZSBlbiBjaWVydGFzIG9jYXNpb25lcyBzZSB0dXZpZXJvbiBwZWRpZG9zIHNpbiBlc3RhciBlbiBlbCByYW5nbyBkZSBsbyBxdWUgbm9ybWFsbWVudGUgcGlkZS4gVGFtYmnDqW4gc2UgdHV2byBkaXNwZXJzacOzbiBwcmluY2lwYWxtZW50ZSBlbiB0cmVzIGNsaWVudGVzLCBIRUxMQSwgVFJNWCB5IFZBUlJPQywgcG9yIG90cm8gbGFkbyBsb3Mgb3Ryb3MgY2xpZW50ZXMgdGllbmVuIG1lbm9zIGRpc3BlcnNpw7NuIGNlcmNhIGRlIGxhIG1lZGlhLiBFc3RhIGdyw6FmaWNhIG5vcyBpbmRpY2EgcXVlIGxhIGNhbnRpZGFkIGRlIHBlZGlkb3MgcXVlIGhhY2VuIHN1ZWxlIHZhcmlhciBtw6FzIGVuIGFsZ3Vub3MgY2xpZW50ZXMgZXMgbXV5IGNvbnN0YW50ZS4qIAoKIyMgKipDb25jbHVzacOzbiAtIERlbGl2ZXJ5IFBsYW4qKiAKUGFyYSByZWFsaXphciBlbCBhbsOhbGlzaXMgZGUgbGEgYmFzZSBkZSBkYXRvcyBkZSAiRGVsaXZlcnkgUGxhbiIgZnXDqSBuZWNlc2FyaW8gcHJpbWVybyBoYWNlciB1biBhcnJlZ2xvIGRlIGxhIGJhc2UgZGUgZGF0b3MgZGUgbWFuZXJhIG1hbnVhbCBlbiBlbCBleGNlbC4gRXN0w7MgcGFyYSBzaW1wbGlmaWNhciBlbCB1c28gZGUgbGEgYmFzZSBkZSBkYXRvcyB5IHBlcm1pdGlyIHF1ZSBSIHB1ZWRhIGFuYWxpemFybGEgeSBleHRyYWVyIGxvcyBkYXRvcyBwYXJhIGdlbmVyYXIgZ3LDoWZpY2FzLiBEZXNwdcOpcyBhcGxpY2Ftb3MgZG9zIGRpZmVyZW50ZXMgYmFzZXMgZGUgZGF0b3MsIG5vcyBhc2VndXJhbW9zIGRlIHF1ZSBubyBoYXlhIE5BcyB5IGVsaW1pbmFtb3MgZmlsYXMgcXVlIGNvcnJlc3BvbmTDrWFuIGEgbG9zIGNsaWVudGVzIHF1ZSB0ZW7DrWFuIG1lbm9zIGRlIDUsMDAwIHBlZGlkb3MuIE5vcyBxdWVkYW1vcyBjb24gdW5hIGJhc2UgZGUgZGF0b3MgY29uIGxvcyA2IGNsaWVudGVzIG3DoXMgc2lnbmlmaWNhdGl2b3MgcGFyYSBGT1JNLiBDb250aW51YW1vcyBpZGVudGlmaWNhbmRvIGxhcyB2YXJpYWJsZXMgZW4gZMOzbmRlIDYgZGUgOCB2YXJpYWJsZXMgZXJhbiBjdWFsaXRhdGl2YXMgYWwgc2VyIGxvcyBjbGllbnRlcyBkZSBGT1JNLiAKCkdyYWZpY2Ftb3MgdW5hIGdyw6FmaWNhIGRlIFBpZSBwYXJhIGlkZW50aWZpY2FyIGRlIG1hbmVyYSB2aXN1YWwgbG9zIG1heW9yZXMgY2xpZW50ZXMsIGxvcyBxdWUgdmllbmVuIHNpZW5kbyBIRUxMQSB5IFRSTVguIFRhbWJpw6luIGhpY2ltb3MgdW4gIkJhcnBsb3QiIHBhcmEgbW9zdHJhciBsYSBjYW50aWRhZCBkZSBwZWRpZG9zIHByb2dyYW1hZG9zIHF1ZSB0aWVuZSBjYWRhIGNsaWVudGUsIEhlbGxhIHNpZW5kbyBlbCBjbGllbnRlIGNvbiBtYXlvciBwZWRpZG9zIGNvbiBtw6FzIGRlIDIyNSwwMDAgeSBUUk1YIHNpZ3VpZW5kbyBjb24gODAsMDAwLiBEZWNpZGltb3MgdGFtYmnDqW4gdmlzdWFsaXphciBlbCBjb21wb3J0YW1pZW50byBkZSBsb3MgY2xpZW50ZXMgc2Vnw7puIGxhIGZlY2hhIHkgbm9zIGRpbW9zIGN1ZW50YSBxdWUgZW50cmUgZWwgbWVzIGRlIHNlcHRpZW1icmUgeSBvY3R1YnJlIGh1Ym8gdW4gaW5jcmVtZW50byBkZSBwZWRpZG9zIGVzdGFibGVjaWRvcy4gWSBwb3Igw7psdGltbyBzZSByZWFsaXrDsyBlbCAiQm94cGxvdCIgcGFyYSBkZSBlc2UgbW9kbyB2ZXIgZGUgbWFuZXJhIHByZWNpc2EgbGEgbW9kYSBkZSBjbG9zIHBlZGlkb3MgcXVlIHN1ZWxlIGhhY2VyIGNhZGEgdW5vIGRlIGxvcyBjbGllbnRlcy4gCgoKIyMgKipSZWZsZXhpw7NuIEZpbmFsOioqIAoKKirCv1F1w6kgZXMgQnVzaW5lc3MgQW5hbHl0aWNzPyoqCkVzIHVuYSBjb21iaW5hY2nDs24gZGUgaGFiaWxpZGFkZXMsIHRlY25vbG9nw61hcyB5IHByw6FjdGljYXMgcGFyYSBsYSBleHBsb3JhY2nDs24gZSBpbnZlc3RpZ2FjacOzbiBkZWwgZnVuY2lvbmFtaWVudG8geSBsb3MgcHJvY2Vzb3MgZW1wcmVzYXJpYWxlcyBxdWUgc2UgaGFuIHRlbmlkbyBhbnRlcmlvcm1lbnRlIHBvciB1biBlbXByZXNhLCBwYXJhIGRlIGVzZSBtb2RvIG9idGVuZXIgaW5mb3JtYWNpw7NuLCBwb2RlciBhbmFsaXphciBkaWNoYSBpbmZvcm1hY2nDs24gcXVlIHNlIGV4dHJhZSB5IGFzw60gaW1wdWxzYXIgbGEgcGxhbmlmaWNhY2nDs24gZXN0cmF0w6lnaWNhIGVtcHJlc2FyaWFsLiBCdXNpbmVzcyBBbmFseXRpY3MgcHVlZGUgZGVzY3VicmlyIHBhdHJvbmVzIHkgcHJlZGVjaXIgdGVuZGVuY2lhcyBjb25zaWRlcmFuZG8gZGlmZXJlbnRlcyBmYWN0b3Jlcy4gCgpFeGlzdGVuIGRpZmVyZW50ZXMgcnVicm9zIGRlbCAiQnVzaW5lc3MgQW5hbHl0aWNzIjoKCjEuIEFuw6FsaXNpcyBEZXNjcmlwdGl2bwoKMi4gQW7DoWxpc2lzIGRlIERpYWduw7NzdGljbwoKMy4gQW7DoWxpc2lzIFByZWRpY3Rpdm8KCjQuIEFuw6FsaXNpcyBQcmVzY3JpcHRpdm8KCioqMyBvYmpldGl2b3MgZGVMIHVzbyBkZSBsYSBoZXJyYW1pZW50YSBkZSAqQnVzaW5lc3MgQW5hbHl0aWNzKj8qKgoxLiBEZXRlcm1pbmFyIHF1w6kgY29uanVudG9zIGRlIGRhdG9zIHNvbiBzaWduaWZpY2FudGVzIHkgw7p0aWxlcyBwYXJhIHBvZGVyIGFuYWxpemFyIHkgY29ub2NlciBlbCBkZXNlbXBlw7FvIGRlIGxhIGVtcHJlc2EgeSBjdcOhbGVzIHB1ZWRlbiBhdW1lbnRhciBsb3MgaW5ncmVzb3MgeSBkaXNtaW51aXIgbG9zIGNvc3Rvcy4gCgotICoqRWplbXBsbzoqKiBwcm9kdWN0aXZpZGFkIHkgZWZpY2VuY2lhLgoKMi4gQW5hbGl6YXIgeSB0cmFuc2Zvcm1hciBsb3MgZGF0b3MgZW4gaW5mb3JtYWNpw7NuIMO6dGlsLCBpZGVudGlmaWNhciB5IGFudGljaXBhciB0ZW5kZW5jaWFzIHkgcmVzdWx0YWRvcy4gU2ltcGxpZmljYXIgaW5mb3JtYWNpw7NuIHBhcmEgaGFjZXJsYSBtw6FzIHNlbmNpbGxhIGRlIGVudGVuZGVyIHkgdmlzdWFsLiAgCgozLiBUb21hciBkZWNpc2lvbmVzIGVtcHJlc2FyaWFsZXMgbcOhcyBpbnRlbGlnZW50ZXMgYmFzYWRhcyBlbiBkYXRvcy4KCi0gKipFamVtcGxvOioqIEFuw6FsaXNpcyBkZWwgY29tcG9ydGFtaWVudG8gZGUgbG9zIGNsaWVudGVzLCBkaXNtaW51Y2nDs24gZGUgY29zdG8sIGV2aXRhciBtZXJtYXMsIGFwcm92ZWNoYW1pZW50byBkZSB0aWVtcG9zIHkgbWF0ZXJpYWxlcywgZWZpY2llbmNpYSB5IGVmaWNhY2lhLiAKCioqwr9DdcOhbCBlcyBsYSByZWxhY2nDs24gZW50cmUgQnVzaW5lc3MgQW5hbHl0aWNzIHkgQnVzaW5lc3MgSW50ZWxsaWdlbmNlPyoqCkJJIHNpcnZlIHBhcmEgZXZhbHVhciwgb3B0aW1pemFyIHkgY29vcmRpbmFyIGxhcyBvcGVyYWNpb25lcyBpbnRlcm5hcyBkZSB1bmEgZW1wcmVzYS4gVHJhdGEgZGUgYXByb3ZlY2hhciB0b2RvIGVsIHBvdGVuY2lhbCBkZSBsb3MgZGF0b3MgcXVlIGdlbmVyYSB1bmEgZW1wcmVzYSBlbiB0b2RhcyBzdXMgYWN0aXZpZGFkZXMgZGlhcmlhcyB5IGFuYWxpemFyIGVzdG9zIGRhdG9zIHBhcmEgb2J0ZW5lciBpbmZvcm1hY2nDs24gZGUgdmFsb3Igc29icmUgbGEgdG9tYSBkZSBkZWNpc2lvbmVzLkF5dWRhIHBhcmEgZW50ZW5kZXIgZWwgaGlzdMOzcmljbyB5IGVsIGNvbW8gZXZvbHVjaW9uYW4gbG9zIGRhdG9zLiBZIGNvbW8gbWVuY2lvbmFtb3MgYW50ZXJpb3JtZW50ZSBCdXNpbmVzcyBBbmFseXRpY3MgY29uIGVsIGFuYWxpc2lzIGRlIGxhIGluZm9ybWFjacOzbiBkZSB1bmEgZW1wcmVzYSBsb2dyYSBwdWVkZSBsbGVnYXIgYSBkZXN1YnJpciBwYXRyb25lcywgZXhwbGljYWNpb25lcyBkZWwgcG9ycXVlIGRlIGxvcyBtaXNtb3MgeSBwcmVkZWNpciB0ZW5kZW5jaWFzIG8gaGVjaG9zIHF1ZSBwdWVkZW4gbGxlZ2FyIGEgcGFzYXIgZW4gZWwgbmVnb2Npby4gCgpFc3RvcyBkb3MgdMOpcm1pbm9zIHRpZW5lbiB1bmEgYWx0YSByZWxhY2nDs24gZW50cmUgZWxsYXMgeWEgcXVlIGVuIHBvY2FzIHBhbGFicmFzIGxhIEludGVsaWdlbmNpYSBkZSBOZWdvY2lvcyBlcyBlbCBoYWNlciBhbsOhbGlzaXMgZGUgbG9zIGRhdG9zIG9idGVuaWRvcyB5IEFuYWzDrXRpY2EgZGUgTmVnb2Npb3MgZXMgcHJlZGljY2nDs24gYSBwYXJ0aXIgZGUgbG9zIGRhdG9zIHF1ZSBzZSBvYnR1dmllcm9uIGNvbiBlbCBhbsOhbGlzaXMuIFVuYSBjb24gbGxldmEgYSBsYSBvdHJhIHkgdHJhYmFqYW4ganVudGFzIHBhcmEgb2J0ZW5lciBlbCByZXN1bHRhZG8gYnVzY2FkbyBkZSB1biBhbsOhbGlzaXMgZGUgZGF0b3MgcXVlIGNvbnRlbmdhIGxhIGluZm9ybWFjacOzbiByZWxldmFudGUgeSBzaWduaWZpY2F0aXZhIHF1ZSBub3MgcHVlZGEgbW9zdHJhciBwcmVkaWNjaW9uZXMgZGVsIGNvbXBvcnRhbWllbnRvIHlhIHNlYSBkZSBsYSBlbXByZXNhLCBkZSBsYSBlY29ub23DrWEsIGRlIGxvcyBpbmdyZXNvcywgZGUgbG9zIGNsaWVudGVzIHkgbcOhcy4gQW1iYXMgc29uIG5lY2VzYXJpYXMgcGFyYSBleHRyYWVyIHVuIGJ1ZW4gYW7DoWxpc2lzIGRlIGxhIGluZm9ybWFjacOzbiBkZSB1bmEgZW1wcmVzYSwgeWEgcXVlIHVuYSBhbmFsaXMgZG9zLCBsb3Mgb3JnYW5pemEgeSBleHRyYSBhcXVlbGxvcyByZWxldmFudGVzIHkgbGEgb3RyYSBwdWVkZSBsb2dyYXIgbGFzIHBlZGljY2lvbmVzIHkgYW7DoWxpc2lzLiAKCgo=