Importar base de datos
#file.choose()
bd12 <- read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Excel y CSV\\Maestrodatos_clientes.csv")
summary(bd12)
## CustomerID Total Visitas
## Min. :12346 Min. : 3.45 Min. : 1.000
## 1st Qu.:13832 1st Qu.: 178.30 1st Qu.: 1.000
## Median :15322 Median : 292.00 Median : 2.000
## Mean :15316 Mean : 415.62 Mean : 4.227
## 3rd Qu.:16790 3rd Qu.: 426.63 3rd Qu.: 5.000
## Max. :18287 Max. :84236.25 Max. :209.000
Herramienta “El Generador de Valor de
Datos”
Paso 1. Definir el área del negocio que buscamos impactar o
mejorar y su KPI
El área serían directamente las ventas de nuestros productos pero con
relación a los clientes.
Los KPI´s a impactar son:
a. Compras del cliente (Ventas) b. Retención del
cliente
Paso 2. Seleccionar plantilla(-s) para crear valor a partir
de los datos de los clientes.
Visión / Segmentación / Personalización /
Contextualización
Paso 3. Generar ideas o conceptos específicos.
Creación de estrategía para mantener a los clientes y generar un
incremento en sus compras.
Paso 4. Reunir los datos requeridos. Se necesita una base de
datos limpia de tickets de ventas a clientes con numeros de
clientes.
Paso 5. Plan de ejecución. a. Recabar los datos, selecciónar
los últimos años para recabar esta informacion para trabajarla.
b.Limpiar la base de datos. c.Hacer una segmentación en clusters de los
clientes. d. Definir las ubicaciones con más retorno de clientes. e.
Generar estratégias para seguir reteniendo clientes y premiar la
lealtad.
Limpiar base de datos
Agregar el CustomerID como nombre de los
renglones
bd13<-bd12
rownames(bd13)<- bd13$CustomerID
Eliminar la columna de customer ID
bd14<-bd13
bd14<- subset(bd14, select = -c (CustomerID))
Revisar presencia de datos anormales
summary(bd14)
## Total Visitas
## Min. : 3.45 Min. : 1.000
## 1st Qu.: 178.30 1st Qu.: 1.000
## Median : 292.00 Median : 2.000
## Mean : 415.62 Mean : 4.227
## 3rd Qu.: 426.63 3rd Qu.: 5.000
## Max. :84236.25 Max. :209.000
plot(bd14$Total, bd14$visitas)

#Los datos fuera de lo normal estan fuera de los siguientes límites:
#Límite inferior = Q1 - 1.5*IQR
#Límite superior = Q3 + 1.5*IQR
#Q1: Cuartil 1, Q3: Cuartil 3, IQR: Rango Intercuartil =Q3-Q1
Calcular el límite superior del total
iqr_total<-IQR(bd14$Total)
limite_superior_total<- 426.63+ 1.5*iqr_total
limite_superior_total
## [1] 799.1277
Conservar solo los tickets promedios
menores a 800
bd15 <-bd14
bd15 <- bd15[bd15$Total<800, ]
summary(bd15)
## Total Visitas
## Min. : 3.45 Min. : 1.000
## 1st Qu.:172.96 1st Qu.: 1.000
## Median :272.23 Median : 2.000
## Mean :298.21 Mean : 4.125
## 3rd Qu.:390.24 3rd Qu.: 5.000
## Max. :799.62 Max. :209.000
Calcular el límite superior de las
visitas
iqr_Visitas<-IQR(bd14$Visitas)
limite_superior_visitas<- 5+ 1.5*iqr_Visitas
limite_superior_visitas
## [1] 11
Conservar sólo las visitas menores a
12
bd16<-bd15
bd16<-bd16[bd16$Visitas < 12, ]
summary(bd16)
## Total Visitas
## Min. : 3.45 Min. : 1.000
## 1st Qu.:168.67 1st Qu.: 1.000
## Median :267.13 Median : 2.000
## Mean :293.99 Mean : 2.971
## 3rd Qu.:384.80 3rd Qu.: 4.000
## Max. :799.62 Max. :11.000
plot(bd16$Total, bd16$Visitas)

K-means clustering
Paso 1. Normalizar Variables
bd17<-bd16
bd17<-as.data.frame(scale(bd17))
plot(bd17$Total, bd17$Visitas)

Paso 2. k-means Clustering
#segmentos <- kmeans(bd17, 3)
#segmentos
asignacion <- cbind(bd16, cluster = segmentos$cluster)
head(asignacion, 10)
## Total Visitas cluster
## 12347 615.7143 7 2
## 12350 334.4000 1 1
## 12352 313.2550 8 2
## 12353 89.0000 1 1
## 12355 459.4000 1 3
## 12358 584.0300 2 3
## 12361 189.9000 1 1
## 12362 522.6230 10 2
## 12363 276.0000 2 1
## 12364 328.2750 4 1
Exportar csv
#write.csv(asignacion,"clientes_segmentados.csv")
Visualizar Segmentos
#install.packages("factoextra")
library(factoextra)
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
fviz_cluster(segmentos, data = bd17,
palette=c("red","blue", "black", "dark green"),
ellipse.type= "euclid",
star.plot = T ,
repel = T,
ggtheme = theme())
## Warning: ggrepel: 3734 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

#install.packages("Cluster")
library(data.table)
library(cluster)
library(factoextra)
Optimizar k
set.seed(123)
optimizacion <- clusGap(bd17, FUN = kmeans, nstart = 25, K.max= 10, B = 50)
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
plot(optimizacion, xlab = "Numero de Clusters k")

Conclusión y Aprendizaje
Dentro de los clusters para el supermercado pudimos visualizar la
manera en la que los clientes del cluster superior en color rojo son los
más leales y con unas compras superiores a los demás pero debido a que
la visualización del primer cluster era muy incierta por el
amontonamiento de los datos, se hizo la segunda optimización de K-means
la cual también reduce el error de los clusters en un 6-15% al decirnos
cuál es el grupo de clusters mas óptimo para nuestro análisis, esto se
complementaría con la herramienta de manera en que segmentando a los
clientes por individual se les pueden dar distintos tipos de
bonificaciónes o complementos adicionales para retenerlos de la
competencia.
Ya visualizando los datos, esta herramienta la podríamos utilizar
generalmente en el area de mercadotecnia y ventas ya que va muy
relacionada con la generación de insights para distintos clusters en el
mercado y al mismo tiempo la generación de estrategias. De igual manera
se puede integrar esta información con un CRM para personalizar las
promociones que se les dan a sus segmentos de clientes y aumentar las
ventas en el area de interés del cliente, asi como lo hace Costco o
Rappi al estudiar el comportamiento del consumidor con sus datos y dando
ofertas que probablemente pudieran aceptar.
LS0tDQp0aXRsZTogPHNwYW4gc3R5bGU9IkNvbG9yOiNFOEJDMDAiPiAiQ2x1c3RlcnMgU3VwZXJtZXJjYWRvcyI8L3NwYW4+DQphdXRob3I6ICJEYW5pZWxhIEPDoXJkZW5hcyBaIC8vIEEwMTcyMDUzNSINCmRhdGU6ICIyMDIyLTA5LTIwIg0Kb3V0cHV0OiANCiAgICAgIGh0bWxfZG9jdW1lbnQ6DQogICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICAgICAgY29kZV9mb2xkaW5nOiAiaGlkZSINCiAgICAgICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoqKioNCg0KIyA8aW1nIHNyYz0gIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcbWFya2V0LmpwZyIgLz4NCg0KIyA8c3BhbiBzdHlsZT0iQ29sb3I6cmVkIj5JbXBvcnRhciBiYXNlIGRlIGRhdG9zIDwvc3Bhbj4NCmBgYHtyfQ0KI2ZpbGUuY2hvb3NlKCkNCmJkMTIgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXE9uZURyaXZlIC0gSW5zdGl0dXRvIFRlY25vbG9naWNvIHkgZGUgRXN0dWRpb3MgU3VwZXJpb3JlcyBkZSBNb250ZXJyZXlcXERlc2t0b3BcXEV4Y2VsIHkgQ1NWXFxNYWVzdHJvZGF0b3NfY2xpZW50ZXMuY3N2IikNCnN1bW1hcnkoYmQxMikNCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJDb2xvcjpyZWQiPiBIZXJyYW1pZW50YSDigJxFbCBHZW5lcmFkb3IgZGUgVmFsb3IgZGUgRGF0b3PigJ0gPC9zcGFuPg0KPHN0eWxlPg0KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiM1ODk4MWY7IGJvcmRlci1yYWRpdXM6IDVweDsgcGFkZGluZzogMjBweDt9DQo8L3N0eWxlPg0KPGRpdiBjbGFzcyA9ICJibHVlIj4NCg0KKlBhc28gMS4qIERlZmluaXIgZWwgw6FyZWEgZGVsIG5lZ29jaW8gcXVlIGJ1c2NhbW9zIGltcGFjdGFyIG8gbWVqb3JhciB5IHN1IEtQSSANCg0KRWwgw6FyZWEgc2Vyw61hbiBkaXJlY3RhbWVudGUgbGFzIHZlbnRhcyBkZSBudWVzdHJvcyBwcm9kdWN0b3MgcGVybyBjb24gcmVsYWNpw7NuIGEgbG9zIGNsaWVudGVzLiAgDQoNCkxvcyBLUEnCtHMgYSBpbXBhY3RhciBzb246ICANCg0KKiphLiBDb21wcmFzIGRlbCBjbGllbnRlIChWZW50YXMpIA0KYi4gUmV0ZW5jacOzbiBkZWwgY2xpZW50ZSoqDQoNCipQYXNvIDIuKiBTZWxlY2Npb25hciBwbGFudGlsbGEoLXMpIHBhcmEgY3JlYXIgdmFsb3IgYSBwYXJ0aXIgZGUgbG9zIGRhdG9zIGRlIGxvcyBjbGllbnRlcy4gICAgIA0KDQpWaXNpw7NuIC8gKipTZWdtZW50YWNpw7NuKiogLyBQZXJzb25hbGl6YWNpw7NuIC8gQ29udGV4dHVhbGl6YWNpw7NuICAgICAgIA0KDQoqUGFzbyAzLiogR2VuZXJhciBpZGVhcyBvIGNvbmNlcHRvcyBlc3BlY8OtZmljb3MuICAgDQpDcmVhY2nDs24gZGUgZXN0cmF0ZWfDrWEgcGFyYSBtYW50ZW5lciBhIGxvcyBjbGllbnRlcyB5IGdlbmVyYXIgdW4gaW5jcmVtZW50byBlbiBzdXMgY29tcHJhcy4gDQoNCipQYXNvIDQuKiBSZXVuaXIgbG9zIGRhdG9zIHJlcXVlcmlkb3MuIA0KU2UgbmVjZXNpdGEgdW5hIGJhc2UgZGUgZGF0b3MgbGltcGlhIGRlIHRpY2tldHMgZGUgdmVudGFzIGEgY2xpZW50ZXMgY29uIG51bWVyb3MgZGUgY2xpZW50ZXMuDQoNCipQYXNvIDUuKiBQbGFuIGRlIGVqZWN1Y2nDs24uIA0KYS4gUmVjYWJhciBsb3MgZGF0b3MsIHNlbGVjY2nDs25hciBsb3Mgw7psdGltb3MgYcOxb3MgcGFyYSByZWNhYmFyIGVzdGEgaW5mb3JtYWNpb24gcGFyYSB0cmFiYWphcmxhLiANCmIuTGltcGlhciBsYSBiYXNlIGRlIGRhdG9zLiANCmMuSGFjZXIgdW5hIHNlZ21lbnRhY2nDs24gZW4gY2x1c3RlcnMgZGUgbG9zIGNsaWVudGVzLiANCmQuIERlZmluaXIgbGFzIHViaWNhY2lvbmVzIGNvbiBtw6FzIHJldG9ybm8gZGUgY2xpZW50ZXMuIA0KZS4gR2VuZXJhciBlc3RyYXTDqWdpYXMgcGFyYSBzZWd1aXIgcmV0ZW5pZW5kbyBjbGllbnRlcyB5IHByZW1pYXIgbGEgbGVhbHRhZC4gDQo8L2Rpdj4gDQoNCiMgPHNwYW4gc3R5bGU9IkNvbG9yOnJlZCI+TGltcGlhciBiYXNlIGRlIGRhdG9zPC9zcGFuPg0KDQojIyA8c3BhbiBzdHlsZT0iQ29sb3I6b3JhbmdlIj5BZ3JlZ2FyIGVsIEN1c3RvbWVySUQgY29tbyBub21icmUgZGUgbG9zIHJlbmdsb25lcyA8L3NwYW4+IA0KYGBge3J9DQpiZDEzPC1iZDEyDQpyb3duYW1lcyhiZDEzKTwtIGJkMTMkQ3VzdG9tZXJJRA0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9IkNvbG9yOm9yYW5nZSI+RWxpbWluYXIgbGEgY29sdW1uYSBkZSBjdXN0b21lciBJRCA8L3NwYW4+IA0KYGBge3J9DQpiZDE0PC1iZDEzDQpiZDE0PC0gc3Vic2V0KGJkMTQsIHNlbGVjdCA9IC1jIChDdXN0b21lcklEKSkNCg0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlPSJDb2xvcjpvcmFuZ2UiPiBSZXZpc2FyIHByZXNlbmNpYSBkZSBkYXRvcyBhbm9ybWFsZXMgPC9zcGFuPiANCmBgYHtyfQ0Kc3VtbWFyeShiZDE0KQ0KcGxvdChiZDE0JFRvdGFsLCBiZDE0JHZpc2l0YXMpDQoNCiNMb3MgZGF0b3MgZnVlcmEgZGUgbG8gbm9ybWFsIGVzdGFuIGZ1ZXJhIGRlIGxvcyBzaWd1aWVudGVzIGzDrW1pdGVzOg0KICAgI0zDrW1pdGUgaW5mZXJpb3IgPSBRMSAtIDEuNSpJUVINCiAgICNMw61taXRlIHN1cGVyaW9yID0gUTMgKyAxLjUqSVFSDQojUTE6IEN1YXJ0aWwgMSwgUTM6IEN1YXJ0aWwgMywgSVFSOiBSYW5nbyBJbnRlcmN1YXJ0aWwgPVEzLVExDQpgYGANCg0KDQoNCiMjIDxzcGFuIHN0eWxlPSJDb2xvcjpvcmFuZ2UiPkNhbGN1bGFyIGVsIGzDrW1pdGUgc3VwZXJpb3IgZGVsIHRvdGFsIDwvc3Bhbj4gDQpgYGB7cn0NCmlxcl90b3RhbDwtSVFSKGJkMTQkVG90YWwpDQpsaW1pdGVfc3VwZXJpb3JfdG90YWw8LSA0MjYuNjMrIDEuNSppcXJfdG90YWwNCmxpbWl0ZV9zdXBlcmlvcl90b3RhbA0KYGBgDQoNCg0KIyMgPHNwYW4gc3R5bGU9IkNvbG9yOm9yYW5nZSI+Q29uc2VydmFyIHNvbG8gbG9zIHRpY2tldHMgcHJvbWVkaW9zIG1lbm9yZXMgYSA4MDA8L3NwYW4+IA0KYGBge3J9DQpiZDE1IDwtYmQxNA0KYmQxNSA8LSBiZDE1W2JkMTUkVG90YWw8ODAwLCBdDQpzdW1tYXJ5KGJkMTUpDQpgYGANCg0KDQojIyA8c3BhbiBzdHlsZT0iQ29sb3I6b3JhbmdlIj5DYWxjdWxhciBlbCBsw61taXRlIHN1cGVyaW9yIGRlIGxhcyB2aXNpdGFzPC9zcGFuPiANCmBgYHtyfQ0KaXFyX1Zpc2l0YXM8LUlRUihiZDE0JFZpc2l0YXMpDQpsaW1pdGVfc3VwZXJpb3JfdmlzaXRhczwtIDUrIDEuNSppcXJfVmlzaXRhcw0KbGltaXRlX3N1cGVyaW9yX3Zpc2l0YXMNCmBgYA0KDQoNCiMjIDxzcGFuIHN0eWxlPSJDb2xvcjpvcmFuZ2UiPkNvbnNlcnZhciBzw7NsbyBsYXMgdmlzaXRhcyBtZW5vcmVzIGEgMTI8L3NwYW4+IA0KYGBge3J9DQpiZDE2PC1iZDE1DQpiZDE2PC1iZDE2W2JkMTYkVmlzaXRhcyA8IDEyLCBdDQoNCnN1bW1hcnkoYmQxNikNCnBsb3QoYmQxNiRUb3RhbCwgYmQxNiRWaXNpdGFzKQ0KYGBgDQoNCg0KDQojIDxzcGFuIHN0eWxlPSJDb2xvcjpyZWQiPkstbWVhbnMgY2x1c3RlcmluZzwvc3Bhbj4NCg0KIyMgPHNwYW4gc3R5bGU9IkNvbG9yOm9yYW5nZSI+UGFzbyAxLiBOb3JtYWxpemFyIFZhcmlhYmxlczwvc3Bhbj4gDQpgYGB7cn0NCmJkMTc8LWJkMTYNCmJkMTc8LWFzLmRhdGEuZnJhbWUoc2NhbGUoYmQxNykpDQoNCnBsb3QoYmQxNyRUb3RhbCwgYmQxNyRWaXNpdGFzKQ0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9IkNvbG9yOm9yYW5nZSI+UGFzbyAyLiBrLW1lYW5zIENsdXN0ZXJpbmc8L3NwYW4+IA0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpzZWdtZW50b3MgPC0ga21lYW5zKGJkMTcsIDMpDQpzZWdtZW50b3MNCmBgYA0KDQpgYGB7cn0NCiNzZWdtZW50b3MgPC0ga21lYW5zKGJkMTcsIDMpDQojc2VnbWVudG9zDQoNCmFzaWduYWNpb24gPC0gY2JpbmQoYmQxNiwgY2x1c3RlciA9IHNlZ21lbnRvcyRjbHVzdGVyKQ0KaGVhZChhc2lnbmFjaW9uLCAxMCkNCmBgYA0KDQoNCiMjIDxzcGFuIHN0eWxlPSJDb2xvcjpvcmFuZ2UiPiBFeHBvcnRhciBjc3Y8L3NwYW4+IA0KYGBge3J9DQojd3JpdGUuY3N2KGFzaWduYWNpb24sImNsaWVudGVzX3NlZ21lbnRhZG9zLmNzdiIpDQpgYGANCg0KDQojIyA8c3BhbiBzdHlsZT0iQ29sb3I6b3JhbmdlIj5WaXN1YWxpemFyIFNlZ21lbnRvcyA8L3NwYW4+IA0KDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJmYWN0b2V4dHJhIikNCmxpYnJhcnkoZmFjdG9leHRyYSkNCmZ2aXpfY2x1c3RlcihzZWdtZW50b3MsIGRhdGEgPSBiZDE3LA0KICAgICAgICAgICAgIHBhbGV0dGU9YygicmVkIiwiYmx1ZSIsICJibGFjayIsICJkYXJrIGdyZWVuIiksDQogICAgICAgICAgICAgZWxsaXBzZS50eXBlPSAiZXVjbGlkIiwNCiAgICAgICAgICAgICBzdGFyLnBsb3QgPSBUICwNCiAgICAgICAgICAgICByZXBlbCA9IFQsDQogICAgICAgICAgICAgZ2d0aGVtZSA9IHRoZW1lKCkpDQoNCiNpbnN0YWxsLnBhY2thZ2VzKCJDbHVzdGVyIikNCg0KbGlicmFyeShkYXRhLnRhYmxlKQ0KbGlicmFyeShjbHVzdGVyKQ0KbGlicmFyeShmYWN0b2V4dHJhKQ0KYGBgDQoNCg0KIyMgPHNwYW4gc3R5bGU9IkNvbG9yOm9yYW5nZSI+T3B0aW1pemFyIGs8L3NwYW4+ICANCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKQ0Kb3B0aW1pemFjaW9uIDwtIGNsdXNHYXAoYmQxNywgRlVOID0ga21lYW5zLCBuc3RhcnQgPSAyNSwgSy5tYXg9IDEwLCBCID0gNTApDQpwbG90KG9wdGltaXphY2lvbiwgeGxhYiA9ICJOdW1lcm8gZGUgQ2x1c3RlcnMgayIpDQpgYGANCg0KDQojIDxzcGFuIHN0eWxlPSJDb2xvcjojRThCQzAwIj4gQ29uY2x1c2nDs24geSBBcHJlbmRpemFqZSA8L3NwYW4+DQoNCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjpiZWlnZTsgYm9yZGVyLXJhZGl1czogNXB4OyBwYWRkaW5nOiAyMHB4O30NCjwvc3R5bGU+DQo8ZGl2IGNsYXNzID0gImJsdWUiPg0KDQpEZW50cm8gZGUgbG9zIGNsdXN0ZXJzIHBhcmEgZWwgc3VwZXJtZXJjYWRvIHB1ZGltb3MgdmlzdWFsaXphciBsYSBtYW5lcmEgZW4gbGEgcXVlIGxvcyBjbGllbnRlcyBkZWwgY2x1c3RlciBzdXBlcmlvciBlbiBjb2xvciByb2pvIHNvbiBsb3MgbcOhcyBsZWFsZXMgeSBjb24gdW5hcyBjb21wcmFzIHN1cGVyaW9yZXMgYSBsb3MgZGVtw6FzIHBlcm8gZGViaWRvIGEgcXVlIGxhIHZpc3VhbGl6YWNpw7NuIGRlbCBwcmltZXIgY2x1c3RlciBlcmEgbXV5IGluY2llcnRhIHBvciBlbCBhbW9udG9uYW1pZW50byBkZSBsb3MgZGF0b3MsIHNlIGhpem8gbGEgc2VndW5kYSBvcHRpbWl6YWNpw7NuIGRlIEstbWVhbnMgbGEgY3VhbCB0YW1iacOpbiByZWR1Y2UgZWwgZXJyb3IgZGUgbG9zIGNsdXN0ZXJzIGVuIHVuIDYtMTUlIGFsIGRlY2lybm9zIGN1w6FsIGVzIGVsIGdydXBvIGRlIGNsdXN0ZXJzIG1hcyDDs3B0aW1vIHBhcmEgbnVlc3RybyBhbsOhbGlzaXMsIGVzdG8gc2UgY29tcGxlbWVudGFyw61hIGNvbiBsYSBoZXJyYW1pZW50YSBkZSBtYW5lcmEgZW4gcXVlIHNlZ21lbnRhbmRvIGEgbG9zIGNsaWVudGVzIHBvciBpbmRpdmlkdWFsIHNlIGxlcyBwdWVkZW4gZGFyIGRpc3RpbnRvcyB0aXBvcyBkZSBib25pZmljYWNpw7NuZXMgbyBjb21wbGVtZW50b3MgYWRpY2lvbmFsZXMgcGFyYSByZXRlbmVybG9zIGRlIGxhIGNvbXBldGVuY2lhLg0KDQpZYSB2aXN1YWxpemFuZG8gbG9zIGRhdG9zLCBlc3RhIGhlcnJhbWllbnRhIGxhIHBvZHLDrWFtb3MgdXRpbGl6YXIgZ2VuZXJhbG1lbnRlIGVuIGVsIGFyZWEgZGUgbWVyY2Fkb3RlY25pYSB5IHZlbnRhcyB5YSBxdWUgdmEgbXV5IHJlbGFjaW9uYWRhIGNvbiBsYSBnZW5lcmFjacOzbiBkZSBpbnNpZ2h0cyBwYXJhIGRpc3RpbnRvcyBjbHVzdGVycyBlbiBlbCBtZXJjYWRvIHkgYWwgbWlzbW8gdGllbXBvIGxhIGdlbmVyYWNpw7NuIGRlIGVzdHJhdGVnaWFzLiBEZSBpZ3VhbCBtYW5lcmEgc2UgcHVlZGUgaW50ZWdyYXIgZXN0YSBpbmZvcm1hY2nDs24gY29uIHVuIENSTSBwYXJhIHBlcnNvbmFsaXphciBsYXMgcHJvbW9jaW9uZXMgcXVlIHNlIGxlcyBkYW4gYSBzdXMgc2VnbWVudG9zIGRlIGNsaWVudGVzIHkgYXVtZW50YXIgbGFzIHZlbnRhcyBlbiBlbCBhcmVhIGRlIGludGVyw6lzIGRlbCBjbGllbnRlLCBhc2kgY29tbyBsbyBoYWNlIENvc3RjbyBvIFJhcHBpIGFsIGVzdHVkaWFyIGVsIGNvbXBvcnRhbWllbnRvIGRlbCBjb25zdW1pZG9yIGNvbiBzdXMgZGF0b3MgeSBkYW5kbyBvZmVydGFzIHF1ZSBwcm9iYWJsZW1lbnRlIHB1ZGllcmFuIGFjZXB0YXIuDQoNCjwvZGl2Pg0K