Trabajo elaborado para la asignatura “Programación y manejo de datos en la era del Big Data” de la Universitat de València durante el curso 2020-2021. El repo del trabajo está aquí. La página web de la asignatura y los trabajos de mis compañeros pueden verse aquí.


1. Introducción

En este trabajo enseñare los resultados del campeonato mundial de la Formula 1 en el año 2019, donde se podra mostrar un claro dominio por parte de la escudería Mercedes integrado por los pilots Lewis Hamilton y Valterri Bottas, con respecto al resto de escuderías que no le pudieron hacer frente a estos veloces coches. También resaltaremos diferentes datos interesantes respecto al tema como la ubicación de los circuitos de carrera, el rendimiento de los pilotos de forma individual y de las escuderías.

2. Posiciones de los Pilotos

En la siguiente tabla se destacara a los 9 pilotos que tuvieron una mayor cantidad de puntos comparado a los 20 que compiten a lo largo de la serie mundial. Como se puede apreciar hay nombres de talla mundial como los de Lewis Hamilton y el de su eterno rival Sebastian Vettel que conduce el famoso coche rojo de Ferrari, pero que durante esta temporada no pudo destacar como lo hace habitualmente y termino obtniendo un 5to lugar en la claisifación mundial. Por otro lado se puede apreciar como su compañero de equipo un rookie llamado Charles Leclerc siendo el segundo piloto más joven que ha pertenecido a la escudería de Ferrari haya logrado vencer en su debut al 4 veces campeón mundial de la formula 1.

Posiciones

Posicion Piloto Puntos R01 R02 R03 R04 R05 R06 R07 R08 R09 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21
1. Lewis Hamilton 413 18 25 25 18 26 25 25 25 10 26 2 25 18 16 12 26 16 25 18 6 26
2. Valtteri Bottas 326 26 18 18 25 18 15 13 18 15 18 - 4 15 18 10 18 25 15 25 - 12
3. Max Verstappen 278 15 12 12 12 15 12 10 12 26 10 26 19 - 4 15 12 - 8 15 25 18
4. Charles Leclerc 264 10 16 10 11 10 - 15 15 18 15 - 12 25 25 18 15 8 13 13 - 15
5. Sebastian Vettel 240 12 10 15 15 12 18 18 11 12 - 18 15 13 - 25 - 18 18 - - 10
6. Carlos Sainz 96 - - - 6 4 8 - 8 4 8 10 10 - - - 8 10 - 4 15 1
7. Pierre Gasly 95 - 4 9 - 8 11 4 1 6 12 - 8 2 - 4 - 6 2 - 18 -
8. Alexander Albon 92 - 2 1 - - 4 - - - - 8 1 10 8 8 10 12 10 10 - 8
9. Daniel Ricciardo 54 - - 6 - - 2 8 - - 6 - - - 12 - - - 4 8 8 -

Posiciones de cada Carrera

Posicion Piloto Race Puntos
1 Lewis Hamilton R01 18
2 Valtteri Bottas R01 26
3 Max Verstappen R01 15
4 Charles Leclerc R01 10
5 Sebastian Vettel R01 12
6 Carlos Sainz R01 0
7 Pierre Gasly R01 0
8 Alexander Albon R01 0
9 Daniel Ricciardo R01 0
1 Lewis Hamilton R02 25
2 Valtteri Bottas R02 18
3 Max Verstappen R02 12
4 Charles Leclerc R02 16
5 Sebastian Vettel R02 10
6 Carlos Sainz R02 0
7 Pierre Gasly R02 4
8 Alexander Albon R02 2
9 Daniel Ricciardo R02 0
1 Lewis Hamilton R03 25
2 Valtteri Bottas R03 18
3 Max Verstappen R03 12
4 Charles Leclerc R03 10
5 Sebastian Vettel R03 15
6 Carlos Sainz R03 0
7 Pierre Gasly R03 9
8 Alexander Albon R03 1
9 Daniel Ricciardo R03 6
1 Lewis Hamilton R04 18
2 Valtteri Bottas R04 25
3 Max Verstappen R04 12
4 Charles Leclerc R04 11
5 Sebastian Vettel R04 15
6 Carlos Sainz R04 6
7 Pierre Gasly R04 0
8 Alexander Albon R04 0
9 Daniel Ricciardo R04 0
1 Lewis Hamilton R05 26
2 Valtteri Bottas R05 18
3 Max Verstappen R05 15
4 Charles Leclerc R05 10
5 Sebastian Vettel R05 12
6 Carlos Sainz R05 4
7 Pierre Gasly R05 8
8 Alexander Albon R05 0
9 Daniel Ricciardo R05 0
1 Lewis Hamilton R06 25
2 Valtteri Bottas R06 15
3 Max Verstappen R06 12
4 Charles Leclerc R06 0
5 Sebastian Vettel R06 18
6 Carlos Sainz R06 8
7 Pierre Gasly R06 11
8 Alexander Albon R06 4
9 Daniel Ricciardo R06 2
1 Lewis Hamilton R07 25
2 Valtteri Bottas R07 13
3 Max Verstappen R07 10
4 Charles Leclerc R07 15
5 Sebastian Vettel R07 18
6 Carlos Sainz R07 0
7 Pierre Gasly R07 4
8 Alexander Albon R07 0
9 Daniel Ricciardo R07 8
1 Lewis Hamilton R08 25
2 Valtteri Bottas R08 18
3 Max Verstappen R08 12
4 Charles Leclerc R08 15
5 Sebastian Vettel R08 11
6 Carlos Sainz R08 8
7 Pierre Gasly R08 1
8 Alexander Albon R08 0
9 Daniel Ricciardo R08 0
1 Lewis Hamilton R09 10
2 Valtteri Bottas R09 15
3 Max Verstappen R09 26
4 Charles Leclerc R09 18
5 Sebastian Vettel R09 12
6 Carlos Sainz R09 4
7 Pierre Gasly R09 6
8 Alexander Albon R09 0
9 Daniel Ricciardo R09 0
1 Lewis Hamilton R10 26
2 Valtteri Bottas R10 18
3 Max Verstappen R10 10
4 Charles Leclerc R10 15
5 Sebastian Vettel R10 0
6 Carlos Sainz R10 8
7 Pierre Gasly R10 12
8 Alexander Albon R10 0
9 Daniel Ricciardo R10 6
1 Lewis Hamilton R11 2
2 Valtteri Bottas R11 0
3 Max Verstappen R11 26
4 Charles Leclerc R11 0
5 Sebastian Vettel R11 18
6 Carlos Sainz R11 10
7 Pierre Gasly R11 0
8 Alexander Albon R11 8
9 Daniel Ricciardo R11 0
1 Lewis Hamilton R12 25
2 Valtteri Bottas R12 4
3 Max Verstappen R12 19
4 Charles Leclerc R12 12
5 Sebastian Vettel R12 15
6 Carlos Sainz R12 10
7 Pierre Gasly R12 8
8 Alexander Albon R12 1
9 Daniel Ricciardo R12 0
1 Lewis Hamilton R13 18
2 Valtteri Bottas R13 15
3 Max Verstappen R13 0
4 Charles Leclerc R13 25
5 Sebastian Vettel R13 13
6 Carlos Sainz R13 0
7 Pierre Gasly R13 2
8 Alexander Albon R13 10
9 Daniel Ricciardo R13 0
1 Lewis Hamilton R14 16
2 Valtteri Bottas R14 18
3 Max Verstappen R14 4
4 Charles Leclerc R14 25
5 Sebastian Vettel R14 0
6 Carlos Sainz R14 0
7 Pierre Gasly R14 0
8 Alexander Albon R14 8
9 Daniel Ricciardo R14 12
1 Lewis Hamilton R15 12
2 Valtteri Bottas R15 10
3 Max Verstappen R15 15
4 Charles Leclerc R15 18
5 Sebastian Vettel R15 25
6 Carlos Sainz R15 0
7 Pierre Gasly R15 4
8 Alexander Albon R15 8
9 Daniel Ricciardo R15 0
1 Lewis Hamilton R16 26
2 Valtteri Bottas R16 18
3 Max Verstappen R16 12
4 Charles Leclerc R16 15
5 Sebastian Vettel R16 0
6 Carlos Sainz R16 8
7 Pierre Gasly R16 0
8 Alexander Albon R16 10
9 Daniel Ricciardo R16 0
1 Lewis Hamilton R17 16
2 Valtteri Bottas R17 25
3 Max Verstappen R17 0
4 Charles Leclerc R17 8
5 Sebastian Vettel R17 18
6 Carlos Sainz R17 10
7 Pierre Gasly R17 6
8 Alexander Albon R17 12
9 Daniel Ricciardo R17 0
1 Lewis Hamilton R18 25
2 Valtteri Bottas R18 15
3 Max Verstappen R18 8
4 Charles Leclerc R18 13
5 Sebastian Vettel R18 18
6 Carlos Sainz R18 0
7 Pierre Gasly R18 2
8 Alexander Albon R18 10
9 Daniel Ricciardo R18 4
1 Lewis Hamilton R19 18
2 Valtteri Bottas R19 25
3 Max Verstappen R19 15
4 Charles Leclerc R19 13
5 Sebastian Vettel R19 0
6 Carlos Sainz R19 4
7 Pierre Gasly R19 0
8 Alexander Albon R19 10
9 Daniel Ricciardo R19 8
1 Lewis Hamilton R20 6
2 Valtteri Bottas R20 0
3 Max Verstappen R20 25
4 Charles Leclerc R20 0
5 Sebastian Vettel R20 0
6 Carlos Sainz R20 15
7 Pierre Gasly R20 18
8 Alexander Albon R20 0
9 Daniel Ricciardo R20 8
1 Lewis Hamilton R21 26
2 Valtteri Bottas R21 12
3 Max Verstappen R21 18
4 Charles Leclerc R21 15
5 Sebastian Vettel R21 10
6 Carlos Sainz R21 1
7 Pierre Gasly R21 0
8 Alexander Albon R21 8
9 Daniel Ricciardo R21 0

3. Evolución de las Posiciones de los Pilotos

Aquí podemos observar a los 9 corredores que hicieron más puntos a lo largo de la temporada. Observando los altos y bajos que han obtenido a lo largo de las 21 carreras realizadas. Se podrá destacar 2 gráficas donde en la primera se observara el rendimientos de los pilotos en relación de los puntos obtenidos con respecto a cada carrera del campeonato mundial, mientras que en la segunda gráfica se detallara el rednimiento de forma individual de cada piloto.

Gráfica

Gráfica por Piloto

4. Posiciones de las Escuerías

En este apartado del trabajo dejaremos al lado a los pilotos y nos enfocaremos en las escuderías. En el siguiente gráfico se podrá observar de forma ordenada las posiciones que obtuvieron los equipos de la formula 1, con un claro dominio de Mercedes al resto de escuderías obteniendo más de 200 puntos con respecto al segundo lugar. Otro dato interesante que se podría obtener a partir de esta información es que no es coincidencia que la ventaja de los primeros 3 equipos sea tan supeior al resto de las escuderías, ya que el presupuesto que poseen sea mayor al resto. De forma más detallada el equipo de Mercedes tuvo una inversión durante este año de 700 millones, Ferrari de 500 millones, Red Bull de 300 millones y el resto de los 7 participantes su presupuesto no llega ni siquiera a los 150 millones. Por esta razón, la FIA la organización encargada de regular las competiciones de automovilismo deicidió implantar para el 2022 un límite al presupuesto de las escuderías que sería igual a 150 millones, para buscar que exista más competitividad y no de que siempre domine una escudería a lo largo del tiempo, sino para que también los pilotos demuestren su habilidad de conducción al tener coches más similares.

Tabla de las Escuderías

Posición Escudería Puntos R01 R02 R03 R04 R05 R06 R07 R08 R09 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22
1 Mercedes 739 44 43 43 43 44 40 38 43 25 44 2 29 33 34 22 44 41 40 43 6 38 NA
2 Ferrari 504 22 26 25 26 22 18 33 26 30 15 18 27 38 25 43 15 26 31 13 - 25 NA
3 Red Bull Racing 417 15 16 21 12 23 23 14 13 32 22 26 27 10 12 23 22 12 18 25 25 26 NA
4 McLaren F1 145 - 8 - 10 4 8 - 10 12 8 10 12 - 1 6 12 10 - 10 19 5 NA
5 Renault F1 Team 91 6 - 6 - - 2 14 4 - 7 - - 4 22 2 1 - 5 10 8 - NA
6 Scuderia Toro Rosso 85 1 2 1 - 2 10 1 - - 2 23 1 8 - 4 - 7 2 - 19 2 NA
7 Racing Point 73 2 1 4 10 - - 2 - - - 12 - 9 6 - 6 6 6 1 2 6 NA
8 Alfa Romeo 57 4 6 2 1 - - - 6 3 4 - 6 - 2 1 - - - - 22 - NA
9 Haas F1 Team 28 8 - - - 7 1 - - - - 10 - - - - 2 - - - - - NA
10 Williams 1 - - - - - - - - - - 1 - - - - - - - - - - NA

Gráfico de las Escuderías

#>  [1] " Williams"            " Haas F1 Team"        " Alfa Romeo"         
#>  [4] " Racing Point"        " Scuderia Toro Rosso" " Renault F1 Team"    
#>  [7] " McLaren F1"          " Red Bull Racing"     " Ferrari"            
#> [10] " Mercedes"

5. Mapa de los Circuitos de la F1

Aquí se puede observar un mapa de los 21 circuitos que pertenecen al mundial de la Formula 1. Como se puede ver en el mapa de la formula 1, los grandes premios se realizan en diferentes partes del mundo para que los aficionados no tengan que trasladarse a un único país para observar estas carreras, sino que ofrecen esta oportunidad para que las diferentes culturas del mundo se unan a este deporte y lo puedan apreciar. Lo normal de esto grandes premios es que se celebre una carrera por país por las razones mencionadas anteriormente. Por otro lado se puede destacar, como los circuitos se encuentran ubicados en diferentes continentes como América del Norte y del Sur, Europa, Asia, Oceanía, pero en el único continente que no incluye en sus competiciones es África, por lo cual es fuertemente críticado.

6.Datos Interesantes

Entre los datos interesantes se podran destacar una serie de variables importantes que obtuvieron los pilotos a lo largo de este año. Entre entas variables encontraremos el número de vicotrias que obtuvieron al igual que los podios que siginifica cuando terminas entre los 3 primeros, también destacaremos las poles que es cuando en la ronda de clasificación para obtener el orden de salida en una carrera, el piloto que se clasifica de primero se gana lo que se llama una “pole position” y por último destacaremos lo que sería las vueltas rápidas que es cuando a lo largo de la carrera el piloto que haga la vuelta más rápida se gana 1 punto más para el mundial.

Con respecto a la relación entre vicotrias y podios se puede apreciar como Lewis Hamilton fue el gran dominante con respecto a estas 2 variables obteniendo un total de 11 victorias y 17 podios. Dos casos especiales serían el Charles Leclerc y Max Verstappen, el primero obtuvo un total 10 podios siendo supeior a su rival Verstappen, pero este obtuvo una vicotria más que Leclerc provocando que en la clasificatoria mundial Verstappen quedar una posición arriba que Leclerc.

Con la otra gráfica relación entre Victorias y Poles, es bastante inusual que Lewis Hamilton no haya logrado dominar en las 2 variables como sucedió en la anterior gráfica, sino que el piloto que obtuvo más poles fue Charles Leclerc lo cual es bastante inusual de ver en la segunda temporada de un piloto de formula 1, pero esto no le basto para poder obtener una mayor cantidad de victorias durante este año.

Tabla

Pos. Piloto Grandes Premios Victorias Podios Poles Vueltas rápidas Puntos
1 Lewis Hamilton 21 11 17 5 6 413
2 Valtteri Bottas 21 4 15 5 2 326
3 Max Verstappen 21 3 9 2 4 278
4 Charles Leclerc 21 2 10 7 4 264
5 Sebastian Vettel 21 1 9 2 2 240
6 Carlos Sainz Jr. 21 NA 1 NA NA 96
7 Pierre Gasly 21 NA 1 NA 2 95
8 Alexander Albon 21 NA NA NA NA 92
9 Daniel Ricciardo 21 NA NA NA NA 54

Relación entre Victorias y Podios

Relación entre Vicotiras y Poles

7. Imagen

En está imagen podemos apreciar la fuerte competitivdiad que había entre las escudería de Ferrari y Mercedes que estaban pelando para ganar el campeonato mundial. De forma más detallada, se puede observar como en el Gran Premio de Rusia, Charles Leclerc esta compitiendo contra Lewis Hamilton para poder ganar este apreciado Premio.

8. Conclusión

Dentro del trabajo realizado, al final se puede observar como Lewis Hamilton logro conquistar por sexta vez el título mundial de la Formula 1. Además, se pudo observar como logro superar a su compañero de equipo Valtteri Bottas por más de 100 puntos que obtuvo el segundo lugar en la clasificación general. También se puede destacar que este año hay muchos pilotos jóvenes que tienen un gran futuro por delante en esta gran competeción como lo ha demostrado Max Verstappen, Charles Leclerc o Pierre Gasly, con sus incríbles cantidad de puntos y de los cuales los dos primeros lograron vencer a sus compañeros de equipos.

LS0tDQp0aXRsZTogPGNlbnRlcj48Rk9OVCBDT0xPUj0iUkVEIj5Gw5NSTVVSTEEgMSBURU1QT1JBREEgMjAxOTwvRk9OVD48L2NlbnRlcj4NCnN1YnRpdGxlOiAiQmVybmFyZG8gQ2FydHVzY2llbGxvKGNhcnR1c2NpQGFsdW1uaS51di5lcykiIA0KYXV0aG9yOiAiVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIg0KZGF0ZTogIkRpY2llbWJyZSBkZSAyMDIwIChhY3R1YWxpemFkbyBlbCBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkLSVtLSVZJylgKSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICAjY3NzOiAiLi9hc3NldHMvbXlfY3NzX2ZpbGUuY3NzIg0KICAgIHRoZW1lOiBkYXJrbHkNCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlIA0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMyANCiAgICB0b2NfZmxvYXQ6IA0KICAgICAgY29sbGFwc2VkOiB0cnVlDQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQogICAgZGZfcHJpbnQ6IGthYmxlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCmBgYHtyIHBhY2thZ2VzLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoa2xpcHB5KSAgIy0gcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoInJsZXN1ci9rbGlwcHkiKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkocnZlc3QpICAgICMgRm9yIHNjcmFwaW5nIHRoZSB3ZWINCmxpYnJhcnkodGlkeXIpICAgICMgRnVuY3Rpb25zIHRvIHRpZHkgb3VyIGRhdGENCmxpYnJhcnkoZHBseXIpICAgICMgUGlwZSBvcGVyYXRvciwgdGliYmxlIGhhbmRsaW5nDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGd0KQ0KbGlicmFyeShnZ3RoZW1lcykNCmxpYnJhcnkobGVhZmxldCkNCmBgYA0KDQpgYGB7ciBjaHVuay1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBldmFsID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIA0KICAgICAgICAgICAgICAgICAgICAgICNyZXN1bHRzID0gImhvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgIGNhY2hlID0gRkFMU0UsIGNhY2hlLnBhdGggPSAiL2NhY2hlcy8iLCBjb21tZW50ID0gIiM+IiwNCiAgICAgICAgICAgICAgICAgICAgICAjZmlnLndpZHRoID0gNywgI2ZpZy5oZWlnaHQ9IDcsICAgDQogICAgICAgICAgICAgICAgICAgICAgI291dC53aWR0aCA9IDcsIG91dC5oZWlnaHQgPSA3LA0KICAgICAgICAgICAgICAgICAgICAgIGNvbGxhcHNlID0gVFJVRSwgIGZpZy5zaG93ID0gImhvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hc3AgPSA3LzksIG91dC53aWR0aCA9ICI2MCUiLCBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmtuaXRyOjpvcHRzX2NodW5rJHNldChkZXYgPSAicG5nIiwgZGV2LmFyZ3MgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpDQpgYGANCg0KYGBge3Igb3B0aW9ucy1zZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Kb3B0aW9ucyhzY2lwZW4gPSA5OTkpICMtIHBhcmEgcXVpdGFyIGxhIG5vdGFjacOzbiBjaWVudMOtZmljYQ0Kb3B0aW9ucygieWFtbC5ldmFsLmV4cHIiID0gVFJVRSkgDQpgYGANCg0KDQpgYGB7ciBrbGlwcHksIGVjaG8gPSBGQUxTRX0NCmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygidG9wIiwgInJpZ2h0IikpICMtIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikNCmBgYA0KDQo8aHIgY2xhc3M9ImxpbmVhLWJsYWNrIj4NCg0KVHJhYmFqbyBlbGFib3JhZG8gcGFyYSBsYSBhc2lnbmF0dXJhICJQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIGRlIGxhIFVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSBkdXJhbnRlIGVsIGN1cnNvIDIwMjAtMjAyMS4gRWwgcmVwbyBkZWwgdHJhYmFqbyBlc3TDoSBbYXF1w61dKGh0dHBzOi8vZ2l0aHViLmNvbS9iZXJuaWNhcnR1c2NpZWxsby90cmFiYWpvX0JpZ0RhdGEpe3RhcmdldD0iX2JsYW5rIn0uIExhIHDDoWdpbmEgd2ViIGRlIGxhIGFzaWduYXR1cmEgeSBsb3MgdHJhYmFqb3MgZGUgbWlzIGNvbXBhw7Flcm9zIHB1ZWRlbiB2ZXJzZSBbYXF1w61dKGh0dHBzOi8vcGVyZXpwNDQuZ2l0aHViLmlvL2ludHJvLWRzLTIwLTIxLXdlYi8wNy10cmFiYWpvcy5odG1sKXt0YXJnZXQ9Il9ibGFuayJ9Lg0KDQo8IS0tIEVsIHDDoXJyYWZvIGRlIGFycmliYSBoYXMgZGUgZGVqYXJsbyBjYXNpIGlndWFsLCANCiAgICAgICAgc29sbyBIQVMgZGUgU1VTVElUVUlSIGxhcyAyIHZlY2VzIHF1ZSBhcGFyZWNlICJwZXJlenA0NCIgcG9yIHR1IHVzdWFyaW8gZGUgR2l0aHViLS0+DQoNCjxociBjbGFzcz0ibGluZWEtcmVkIj4NCg0KIyMgICA8Rk9OVCBDT0xPUj0icmVkIj4xLiBJbnRyb2R1Y2Npw7NuPC9GT05UPg0KDQpFbiBlc3RlIHRyYWJham8gZW5zZcOxYXJlIGxvcyByZXN1bHRhZG9zIGRlbCBjYW1wZW9uYXRvIG11bmRpYWwgZGUgbGEgRm9ybXVsYSAxIGVuIGVsIGHDsW8gMjAxOSwgZG9uZGUgc2UgcG9kcmEgbW9zdHJhciB1biBjbGFybyBkb21pbmlvIHBvciBwYXJ0ZSBkZSBsYSBlc2N1ZGVyw61hICBNZXJjZWRlcyBpbnRlZ3JhZG8gcG9yIGxvcyBwaWxvdHMgTGV3aXMgSGFtaWx0b24geSBWYWx0ZXJyaSBCb3R0YXMsIGNvbiByZXNwZWN0byBhbCByZXN0byBkZSBlc2N1ZGVyw61hcyBxdWUgbm8gbGUgcHVkaWVyb24gaGFjZXIgZnJlbnRlIGEgZXN0b3MgdmVsb2NlcyBjb2NoZXMuIFRhbWJpw6luIHJlc2FsdGFyZW1vcyBkaWZlcmVudGVzIGRhdG9zIGludGVyZXNhbnRlcyByZXNwZWN0byBhbCB0ZW1hIGNvbW8gbGEgdWJpY2FjacOzbiBkZSBsb3MgY2lyY3VpdG9zIGRlIGNhcnJlcmEsIGVsIHJlbmRpbWllbnRvIGRlIGxvcyBwaWxvdG9zIGRlIGZvcm1hIGluZGl2aWR1YWwgeSBkZSBsYXMgZXNjdWRlcsOtYXMuDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsZXZhbD1UUlVFLCAgb3V0LndpZHRoPSI4MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MgKGhlcmU6OmhlcmUoICIvaW1hZ2VuIiwiY29taWVuem9kZWNhcnJlcmEuanBnIikpDQpgYGANCg0KDQojIyAgIDxGT05UIENPTE9SPSJyZWQiPjIuIFBvc2ljaW9uZXMgZGUgbG9zIFBpbG90b3MgPC9GT05UPiB7LnRhYnNldH0NCg0KDQpFbiBsYSBzaWd1aWVudGUgdGFibGEgc2UgZGVzdGFjYXJhIGEgbG9zIDkgcGlsb3RvcyBxdWUgdHV2aWVyb24gdW5hIG1heW9yIGNhbnRpZGFkIGRlIHB1bnRvcyBjb21wYXJhZG8gYSBsb3MgMjAgcXVlIGNvbXBpdGVuIGEgbG8gbGFyZ28gZGUgbGEgc2VyaWUgbXVuZGlhbC4gQ29tbyBzZSBwdWVkZSBhcHJlY2lhciBoYXkgbm9tYnJlcyBkZSB0YWxsYSBtdW5kaWFsIGNvbW8gbG9zIGRlIExld2lzIEhhbWlsdG9uIHkgZWwgZGUgc3UgZXRlcm5vIHJpdmFsIFNlYmFzdGlhbiBWZXR0ZWwgcXVlIGNvbmR1Y2UgZWwgZmFtb3NvIGNvY2hlIHJvam8gZGUgRmVycmFyaSwgcGVybyBxdWUgZHVyYW50ZSBlc3RhIHRlbXBvcmFkYSBubyBwdWRvIGRlc3RhY2FyIGNvbW8gbG8gaGFjZSBoYWJpdHVhbG1lbnRlIHkgdGVybWlubyBvYnRuaWVuZG8gdW4gNXRvIGx1Z2FyIGVuIGxhIGNsYWlzaWZhY2nDs24gbXVuZGlhbC4gUG9yIG90cm8gbGFkbyBzZSBwdWVkZSBhcHJlY2lhciBjb21vIHN1IGNvbXBhw7Flcm8gZGUgZXF1aXBvIHVuIHJvb2tpZSBsbGFtYWRvIENoYXJsZXMgTGVjbGVyYyBzaWVuZG8gZWwgc2VndW5kbyBwaWxvdG8gbcOhcyBqb3ZlbiBxdWUgaGEgcGVydGVuZWNpZG8gYSBsYSBlc2N1ZGVyw61hIGRlIEZlcnJhcmkgaGF5YSBsb2dyYWRvIHZlbmNlciBlbiBzdSBkZWJ1dCBhbCA0IHZlY2VzIGNhbXBlw7NuIG11bmRpYWwgZGUgbGEgZm9ybXVsYSAxLg0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipQb3NpY2lvbmVzKio8L0ZPTlQ+DQpgYGB7ciwgZWNobz1GQUxTRSwgZXZhbD1UUlVFfQ0KDQpmb3JtdWxhXzEgPC0gcmVhZF9leGNlbCgiLi9kYXRvcy9mb3JtdWxhMS54bHN4Iiwgc2hlZXQgPSAxKQ0KDQpmb3JtdWxhXzEgPC0gYXNfdGliYmxlKGZvcm11bGFfMSkgJT4lIA0KICBmaWx0ZXIoYXMuaW50ZWdlcihQb3NpY2lvbikgPD0gOSkNCiMgTWFrZSBEcml2ZXIgYSBmYWN0b3JpYWwgdmFyaWFibGUsIHJlcGxhY2UgYWxsICctJyB3aXRoIHplcm9zLCBjb252ZXJ0IHRvIGxvbmcgZm9ybWF0DQoNCg0Ka25pdHI6OmthYmxlKGZvcm11bGFfMSkNCg0KDQoNCmBgYA0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0icmVkIj4qKlBvc2ljaW9uZXMgZGUgY2FkYSBDYXJyZXJhKio8L0ZPTlQ+DQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPVRSVUV9DQpmb3JtdWxhXzEkUGlsb3RvIDwtIGFzLmZhY3Rvcihmb3JtdWxhXzEkUGlsb3RvKQ0KZm9ybXVsYV8xWywgLTJdIDwtIGFwcGx5KGZvcm11bGFfMVssIC0yXSwgMiwgZnVuY3Rpb24oeCkgYXMuaW50ZWdlcihnc3ViKCctJywgJzAnLCBhcy5jaGFyYWN0ZXIoeCkpKSkNCg0KZjFfbG9uZyA8LSBnYXRoZXIoZm9ybXVsYV8xLCBSYWNlLCBQdW50b3MsIFIwMTpSMjEpDQoNCmtuaXRyOjprYWJsZShmMV9sb25nKQ0KDQoNCmBgYA0KDQojIyAgIDxGT05UIENPTE9SPSJyZWQiPjMuIEV2b2x1Y2nDs24gZGUgbGFzIFBvc2ljaW9uZXMgZGUgbG9zIFBpbG90b3M8L0ZPTlQ+IHsudGFic2V0fQ0KQXF1w60gcG9kZW1vcyBvYnNlcnZhciBhIGxvcyA5IGNvcnJlZG9yZXMgcXVlIGhpY2llcm9uIG3DoXMgcHVudG9zIGEgbG8gbGFyZ28gZGUgbGEgdGVtcG9yYWRhLiBPYnNlcnZhbmRvIGxvcyBhbHRvcyB5IGJham9zIHF1ZSBoYW4gb2J0ZW5pZG8gYSBsbyBsYXJnbyBkZSBsYXMgMjEgY2FycmVyYXMgcmVhbGl6YWRhcy4gU2UgcG9kcsOhIGRlc3RhY2FyIDIgZ3LDoWZpY2FzIGRvbmRlIGVuIGxhIHByaW1lcmEgc2Ugb2JzZXJ2YXJhIGVsIHJlbmRpbWllbnRvcyBkZSBsb3MgcGlsb3RvcyBlbiByZWxhY2nDs24gZGUgbG9zIHB1bnRvcyBvYnRlbmlkb3MgY29uIHJlc3BlY3RvIGEgY2FkYSBjYXJyZXJhIGRlbCBjYW1wZW9uYXRvIG11bmRpYWwsIG1pZW50cmFzIHF1ZSBlbiBsYSBzZWd1bmRhIGdyw6FmaWNhIHNlIGRldGFsbGFyYSBlbCByZWRuaW1pZW50byBkZSBmb3JtYSBpbmRpdmlkdWFsIGRlIGNhZGEgcGlsb3RvLiANCg0KIyMjIDxGT05UIENPTE9SPSJyZWQiPioqR3LDoWZpY2EqKjwvRk9OVD4NCmBgYHtyIHByZXNzdXJlLCBlY2hvPUZBTFNFLCBldmFsPVRSVUUsICBvdXQud2lkdGg9IjgwJSJ9DQpmMV9sb25nIDwtIGdhdGhlcihmb3JtdWxhXzEsIFJhY2UsIFB1bnRvcywgUjAxOlIyMSkNCg0KDQoNCmcgPC0gZ2dwbG90KGYxX2xvbmcsIGFlcyh4ID0gUmFjZSwgeSA9IFB1bnRvcywgZ3JvdXAgPSBQaWxvdG8sIGNvbG91ciA9IFBpbG90bykpICsgDQogIGdlb21fbGluZSgpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShicmVha3M9YygnUjAxJywgJ1IwNicsICdSMTEnLCAnUjE2JywgJ1IyMScpKSArDQogIGxhYnModGl0bGUgPSAnRjEgcmVzdWx0YWRvcyAyMDE5LCB0b3AgOSBkcml2ZXJzJykgKyBnZW9tX3BvaW50KCkNCg0KZ2dwbG90bHkoZykNCg0KYGBgDQoNCg0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipHcsOhZmljYSBwb3IgUGlsb3RvKio8L0ZPTlQ+DQpgYGB7ciwgZWNobz1GQUxTRSwgZXZhbD1UUlVFLCAgb3V0LndpZHRoPSI4MCUifQ0KZjFfbG9uZyA8LSBnYXRoZXIoZm9ybXVsYV8xLCBSYWNlLCBQdW50b3MsIFIwMTpSMjEpDQoNCg0KICAgICAgICAgIA0KZiA8LSBnZ3Bsb3QoZjFfbG9uZywgYWVzKHggPSBSYWNlLCB5ID0gUHVudG9zLCBncm91cCA9IFBpbG90bywgY29sb3VyID0gUGlsb3RvKSkgKyANCiAgZ2VvbV9saW5lKHNob3cubGVnZW5kID0gRkFMU0UpICsgZmFjZXRfd3JhcCh+IFBpbG90bykgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGJyZWFrcz1jKCdSMDEnLCAnUjA2JywgJ1IxMScsICdSMTYnLCAnUjIxJykpICsNCiAgbGFicyh0aXRsZSA9ICdGMSByZXN1bHRhZG9zIDIwMTksIHRvcCA5IGRyaXZlcnMnKSArIGdlb21fcG9pbnQoKSANCg0KZ2dwbG90bHkoZikNCg0KYGBgDQoNCg0KDQojIyAgIDxGT05UIENPTE9SPSJyZWQiPjQuIFBvc2ljaW9uZXMgZGUgbGFzIEVzY3VlcsOtYXMgPC9GT05UPiB7LnRhYnNldH0NCg0KRW4gZXN0ZSBhcGFydGFkbyBkZWwgdHJhYmFqbyBkZWphcmVtb3MgYWwgbGFkbyBhIGxvcyBwaWxvdG9zIHkgbm9zIGVuZm9jYXJlbW9zIGVuIGxhcyBlc2N1ZGVyw61hcy4gRW4gZWwgc2lndWllbnRlIGdyw6FmaWNvIHNlIHBvZHLDoSBvYnNlcnZhciBkZSBmb3JtYSBvcmRlbmFkYSBsYXMgcG9zaWNpb25lcyBxdWUgb2J0dXZpZXJvbiBsb3MgZXF1aXBvcyBkZSBsYSBmb3JtdWxhIDEsIGNvbiB1biBjbGFybyBkb21pbmlvIGRlIE1lcmNlZGVzIGFsIHJlc3RvIGRlIGVzY3VkZXLDrWFzIG9idGVuaWVuZG8gbcOhcyBkZSAyMDAgcHVudG9zIGNvbiByZXNwZWN0byBhbCBzZWd1bmRvIGx1Z2FyLiBPdHJvIGRhdG8gaW50ZXJlc2FudGUgcXVlIHNlIHBvZHLDrWEgb2J0ZW5lciBhIHBhcnRpciBkZSBlc3RhIGluZm9ybWFjacOzbiBlcyBxdWUgbm8gZXMgY29pbmNpZGVuY2lhIHF1ZSBsYSB2ZW50YWphIGRlIGxvcyBwcmltZXJvcyAzIGVxdWlwb3Mgc2VhIHRhbiBzdXBlaW9yIGFsIHJlc3RvIGRlIGxhcyBlc2N1ZGVyw61hcywgeWEgcXVlIGVsIHByZXN1cHVlc3RvIHF1ZSBwb3NlZW4gc2VhIG1heW9yIGFsIHJlc3RvLiBEZSBmb3JtYSBtw6FzIGRldGFsbGFkYSBlbCBlcXVpcG8gZGUgTWVyY2VkZXMgdHV2byB1bmEgaW52ZXJzacOzbiBkdXJhbnRlIGVzdGUgYcOxbyBkZSA3MDAgbWlsbG9uZXMsIEZlcnJhcmkgZGUgNTAwIG1pbGxvbmVzLCBSZWQgQnVsbCBkZSAzMDAgbWlsbG9uZXMgeSBlbCByZXN0byBkZSBsb3MgNyBwYXJ0aWNpcGFudGVzIHN1IHByZXN1cHVlc3RvIG5vIGxsZWdhIG5pIHNpcXVpZXJhIGEgbG9zIDE1MCBtaWxsb25lcy4gUG9yIGVzdGEgcmF6w7NuLCBsYSBGSUEgbGEgb3JnYW5pemFjacOzbiBlbmNhcmdhZGEgZGUgcmVndWxhciBsYXMgY29tcGV0aWNpb25lcyBkZSBhdXRvbW92aWxpc21vIGRlaWNpZGnDsyBpbXBsYW50YXIgcGFyYSBlbCAyMDIyIHVuIGzDrW1pdGUgYWwgcHJlc3VwdWVzdG8gZGUgbGFzIGVzY3VkZXLDrWFzIHF1ZSBzZXLDrWEgaWd1YWwgYSAxNTAgbWlsbG9uZXMsIHBhcmEgYnVzY2FyIHF1ZSBleGlzdGEgbcOhcyBjb21wZXRpdGl2aWRhZCB5IG5vIGRlIHF1ZSBzaWVtcHJlIGRvbWluZSB1bmEgZXNjdWRlcsOtYSBhIGxvIGxhcmdvIGRlbCB0aWVtcG8sIHNpbm8gcGFyYSBxdWUgdGFtYmnDqW4gbG9zIHBpbG90b3MgZGVtdWVzdHJlbiBzdSBoYWJpbGlkYWQgZGUgY29uZHVjY2nDs24gYWwgdGVuZXIgY29jaGVzIG3DoXMgc2ltaWxhcmVzLg0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipUYWJsYSBkZSBsYXMgRXNjdWRlcsOtYXMqKjwvRk9OVD4NCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPVRSVUV9DQoNCmVzY3VkZXJpYSA8LSByZWFkX2V4Y2VsKCIuL2RhdG9zL2Zvcm11bGExLnhsc3giLCBzaGVldCA9IDIpDQoNCmtuaXRyOjprYWJsZShlc2N1ZGVyaWEpDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9DQpzdHIoZXNjdWRlcmlhKSAgIy0gbGEgdi4gcmVnaW9uIGVzIGRlIHRpcG8gY2hhcmFjdGVyDQoNCmVzY3VkZXJpYSA8LSBlc2N1ZGVyaWEgJT4lIG11dGF0ZShFc2N1ZGVyw61hID0gZm9yY2F0czo6YXNfZmFjdG9yKEVzY3VkZXLDrWEpKSAgICMtIGNvbnZlcnRpbW9zIGxhIHYuIHJlZ2lvbiBlbiBmYWN0b3IgY29uIGxhIGYuIGFzX2ZhY3RvcigpDQoNCnN0cihlc2N1ZGVyaWEpICAjLSBsYSB2LiByZWdpb24gYWhvcmEgZXMgdW4gZmFjdG9yDQpsZXZlbHMoZXNjdWRlcmlhJEVzY3VkZXLDrWEpICMtIGxvcyBsZXZlbHMgZGVsICBlc3TDoW4gb3JkZW5hZG9yIGFsZmFiw6l0aWNhbWVudGUNCg0KZXNjdWRlcmlhIDwtIGVzY3VkZXJpYSAlPiUgbXV0YXRlKEVzY3VkZXLDrWEgPSBmb3JjYXRzOjpmY3RfcmVvcmRlcihFc2N1ZGVyw61hLCBQdW50b3MpKSAjLSByZW9yZGVuYW1vcyBsb3Mgbml2ZWxlcyBkZWwgZmFjdG9yIGVuIGYuIGRlIFBvYl9yZWdpb24NCg0KbGV2ZWxzKGVzY3VkZXJpYSRFc2N1ZGVyw61hKSAjLSBhaG9yYSBsb3MgbGV2ZWxzIGRlbCBmYWN0b3IgZXN0YW4gb3JkZW5hZG9yIGVuIGZ1bmNpb24gZGUgbGEgcG9ibGFjacOzbg0KDQoNCg0KDQoNCmBgYA0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipHcsOhZmljbyBkZSBsYXMgRXNjdWRlcsOtYXMqKjwvRk9OVD4NCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPVRSVUUsICBvdXQud2lkdGg9IjgwJSJ9DQplc2N1ZGVyaWEgPC0gZXNjdWRlcmlhICU+JSBtdXRhdGUoRXNjdWRlcsOtYSA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKEVzY3VkZXLDrWEsIFB1bnRvcykpDQoNCmxldmVscyhlc2N1ZGVyaWEkRXNjdWRlcsOtYSkNCg0KZ2dwbG90KGVzY3VkZXJpYSwgYWVzKHggPSBQdW50b3MsIHkgPSBFc2N1ZGVyw61hKSkgKyBnZW9tX2NvbChmaWxsID0gYygiY3lhbiIsICJyZWQiLCJkYXJrYmx1ZSIsIm9yYW5nZSIsICJ5ZWxsb3ciLCAic3RlZWxibHVlIiwgInBpbmsiLCAiYnJvd24xIiwgImNob2NvbGF0ZTQiLCAiZGFya2dyYXkiKSkgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gUHVudG9zKSwgbnVkZ2VfeCA9IDI1KSANCg0KYGBgDQoNCg0KDQoNCiMjICAgPEZPTlQgQ09MT1I9IlJFRCI+NS4gTWFwYSBkZSBsb3MgQ2lyY3VpdG9zIGRlIGxhIEYxIDwvRk9OVD4NCg0KQXF1w60gc2UgcHVlZGUgb2JzZXJ2YXIgdW4gbWFwYSBkZSBsb3MgMjEgY2lyY3VpdG9zIHF1ZSBwZXJ0ZW5lY2VuIGFsIG11bmRpYWwgZGUgbGEgRm9ybXVsYSAxLiBDb21vIHNlIHB1ZWRlIHZlciBlbiBlbCBtYXBhIGRlIGxhIGZvcm11bGEgMSwgbG9zIGdyYW5kZXMgcHJlbWlvcyBzZSByZWFsaXphbiBlbiBkaWZlcmVudGVzIHBhcnRlcyBkZWwgbXVuZG8gcGFyYSBxdWUgbG9zIGFmaWNpb25hZG9zIG5vIHRlbmdhbiBxdWUgdHJhc2xhZGFyc2UgYSB1biDDum5pY28gcGHDrXMgcGFyYSBvYnNlcnZhciBlc3RhcyBjYXJyZXJhcywgc2lubyBxdWUgb2ZyZWNlbiBlc3RhIG9wb3J0dW5pZGFkIHBhcmEgcXVlIGxhcyBkaWZlcmVudGVzIGN1bHR1cmFzIGRlbCBtdW5kbyBzZSB1bmFuIGEgZXN0ZSBkZXBvcnRlIHkgbG8gcHVlZGFuIGFwcmVjaWFyLiBMbyBub3JtYWwgZGUgZXN0byBncmFuZGVzIHByZW1pb3MgZXMgcXVlIHNlIGNlbGVicmUgdW5hIGNhcnJlcmEgcG9yIHBhw61zIHBvciBsYXMgcmF6b25lcyBtZW5jaW9uYWRhcyBhbnRlcmlvcm1lbnRlLiBQb3Igb3RybyBsYWRvIHNlIHB1ZWRlIGRlc3RhY2FyLCBjb21vIGxvcyBjaXJjdWl0b3Mgc2UgZW5jdWVudHJhbiB1YmljYWRvcyBlbiBkaWZlcmVudGVzIGNvbnRpbmVudGVzIGNvbW8gQW3DqXJpY2EgZGVsIE5vcnRlIHkgZGVsIFN1ciwgRXVyb3BhLCBBc2lhLCBPY2VhbsOtYSwgcGVybyBlbiBlbCDDum5pY28gY29udGluZW50ZSBxdWUgbm8gaW5jbHV5ZSBlbiBzdXMgY29tcGV0aWNpb25lcyBlcyDDgWZyaWNhLCBwb3IgbG8gY3VhbCBlcyBmdWVydGVtZW50ZSBjcsOtdGljYWRvLg0KYGBge3IgZXZhbCA9IFRSVUUsIGVjaG8gPSBGQUxTRSwgIG91dC53aWR0aD0iODAlIn0NCg0KcCA8LSBsZWFmbGV0KCkgJT4lDQogIGFkZFRpbGVzKCkgJT4lIA0KICBzZXRWaWV3KGxuZyA9IC0yLjQzNTk3MywgbGF0ID0gNTIuMzc4MDUxLCB6b29tID0gMSkgJT4lIA0KICBhZGRNYXJrZXJzKGxuZyA9IDUwLjUxNDUyMSwgbGF0ID0gMjYuMDMxNjk5LCBwb3B1cCA9ICJHUCBCQUhSRUlOIikgJT4lIA0KICBhZGRNYXJrZXJzKGxuZyA9IDE0NC45NjMyNiwgbGF0ID0gLTM3Ljg0NDc2LCBwb3B1cCA9ICJHUCBBVVNUUkFMSUEiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAxMjEuMjE5NzIsIGxhdCA9IDMxLjMzODg5LCBwb3B1cCA9ICJHUCBDSElOQSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IDQ5Ljg5MjAxLCBsYXQgPSA0MC4zNzc2NywgcG9wdXAgPSAiR1AgQVpFUkJBSVnDgU4iKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAyLjI1ODA2MywgbGF0ID0gNDEuNTY5NDY5LCBwb3B1cCA9ICJHUCBFU1BBw5FBIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gNy40MjczMiwgbGF0ID0gNDMuNzM5NzYgLCBwb3B1cCA9ICJHUCBNT05BQ08iKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAtNzMuNTI0MTcsIGxhdCA9IDQ1LjUwODM4LCBwb3B1cCA9ICJHUCBDQU5BREEiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAgNS43OTE3NywgbGF0ID0gNDMuMjUzNjQsIHBvcHVwID0gIkdQIEZSQU5DSUEiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAxNC43NjQzMTYsIGxhdCA9IDQ3LjIyMjEzMSwgcG9wdXAgPSAiR1AgQVVTVFJJQSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IC0xLjAxNDI5OSwgbGF0ID0gNTIuMDcxODEyLCBwb3B1cCA9ICJHUCBJTkdMQVRFUlJBIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gIDguNTY2NzUxLCBsYXQgPSA0OS4zMjczMTcsIHBvcHVwID0gIkdQIEFMRU1BTklBIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gMTkuMTUwMSwgbGF0ID0gNDcuMzQ1MCwgcG9wdXAgPSAiR1AgSFVOR1JJQSIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IDUuOTY4MzcsIGxhdCA9IDUwLjQ0NDc0LCBwb3B1cCA9ICJHUCBCRUxHSUNBIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gOS4yODI2NDEsIGxhdCA9IDQ1LjYxOTEwNiwgcG9wdXAgPSAiR1AgSVRBTElBIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gMTAzLjg2Mzk1LCBsYXQgPSAxLjI5MTU2LCBwb3B1cCA9ICJHUCBTSU5HQVBVUiIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IDM5LjcyNTY5LCBsYXQgPSA0My41OTkxNywgcG9wdXAgPSAiR1AgUlVTSUEiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAgMTM2LjU0MTgzOSwgbGF0ID0gIDM0Ljg0NTIwNyAsIHBvcHVwID0gIkdQIEpBUE9OIikgJT4lDQogIGFkZE1hcmtlcnMobG5nID0gLTk5LjA5MjIzOCwgbGF0ID0gMTkuNDAzMzcsIHBvcHVwID0gIkdQIE1FWElDTyIpICU+JQ0KICBhZGRNYXJrZXJzKGxuZyA9IC05Ny42MzY0MDksIGxhdCA9IDMwLjEzNDQxNCwgcG9wdXAgPSAiR1AgRVNUQURPUyBVTklET1MiKSAlPiUNCiAgYWRkTWFya2VycyhsbmcgPSAtNDYuNjk3MTcsIGxhdCA9IC0yMy43MDA1MjIsIHBvcHVwID0gIkdQIEJSQVNJTCIpDQoNCnANCg0KYGBgDQoNCiMjICAgPEZPTlQgQ09MT1I9InJlZCI+Ni5EYXRvcyBJbnRlcmVzYW50ZXMgPC9GT05UPiAgey50YWJzZXR9DQoNCkVudHJlIGxvcyBkYXRvcyBpbnRlcmVzYW50ZXMgc2UgcG9kcmFuIGRlc3RhY2FyIHVuYSBzZXJpZSBkZSB2YXJpYWJsZXMgaW1wb3J0YW50ZXMgcXVlIG9idHV2aWVyb24gbG9zIHBpbG90b3MgYSBsbyBsYXJnbyBkZSBlc3RlIGHDsW8uIEVudHJlIGVudGFzIHZhcmlhYmxlcyBlbmNvbnRyYXJlbW9zIGVsIG7Dum1lcm8gZGUgdmljb3RyaWFzIHF1ZSBvYnR1dmllcm9uIGFsIGlndWFsIHF1ZSBsb3MgcG9kaW9zIHF1ZSBzaWdpbmlmaWNhIGN1YW5kbyB0ZXJtaW5hcyBlbnRyZSBsb3MgMyBwcmltZXJvcywgdGFtYmnDqW4gZGVzdGFjYXJlbW9zIGxhcyBwb2xlcyBxdWUgZXMgY3VhbmRvIGVuIGxhIHJvbmRhIGRlIGNsYXNpZmljYWNpw7NuIHBhcmEgb2J0ZW5lciBlbCBvcmRlbiBkZSBzYWxpZGEgZW4gdW5hIGNhcnJlcmEsIGVsIHBpbG90byBxdWUgc2UgY2xhc2lmaWNhIGRlIHByaW1lcm8gc2UgZ2FuYSBsbyBxdWUgc2UgbGxhbWEgdW5hICJwb2xlIHBvc2l0aW9uIiB5IHBvciDDumx0aW1vIGRlc3RhY2FyZW1vcyBsbyBxdWUgc2Vyw61hIGxhcyB2dWVsdGFzIHLDoXBpZGFzIHF1ZSBlcyBjdWFuZG8gYSBsbyBsYXJnbyBkZSBsYSBjYXJyZXJhIGVsIHBpbG90byBxdWUgaGFnYSBsYSB2dWVsdGEgbcOhcyByw6FwaWRhIHNlIGdhbmEgMSBwdW50byBtw6FzIHBhcmEgZWwgbXVuZGlhbC4NCg0KQ29uIHJlc3BlY3RvIGEgbGEgcmVsYWNpw7NuIGVudHJlIHZpY290cmlhcyB5IHBvZGlvcyBzZSBwdWVkZSBhcHJlY2lhciBjb21vIExld2lzIEhhbWlsdG9uIGZ1ZSBlbCBncmFuIGRvbWluYW50ZSBjb24gcmVzcGVjdG8gYSBlc3RhcyAyIHZhcmlhYmxlcyBvYnRlbmllbmRvIHVuIHRvdGFsIGRlIDExIHZpY3RvcmlhcyB5IDE3IHBvZGlvcy4gRG9zIGNhc29zIGVzcGVjaWFsZXMgc2Vyw61hbiBlbCBDaGFybGVzIExlY2xlcmMgeSBNYXggVmVyc3RhcHBlbiwgZWwgcHJpbWVybyBvYnR1dm8gdW4gdG90YWwgMTAgcG9kaW9zIHNpZW5kbyBzdXBlaW9yIGEgc3Ugcml2YWwgVmVyc3RhcHBlbiwgcGVybyBlc3RlIG9idHV2byB1bmEgdmljb3RyaWEgbcOhcyBxdWUgTGVjbGVyYyBwcm92b2NhbmRvIHF1ZSBlbiBsYSBjbGFzaWZpY2F0b3JpYSBtdW5kaWFsIFZlcnN0YXBwZW4gcXVlZGFyIHVuYSBwb3NpY2nDs24gYXJyaWJhIHF1ZSBMZWNsZXJjLg0KDQpDb24gbGEgb3RyYSBncsOhZmljYSByZWxhY2nDs24gZW50cmUgVmljdG9yaWFzIHkgUG9sZXMsIGVzIGJhc3RhbnRlIGludXN1YWwgcXVlIExld2lzIEhhbWlsdG9uIG5vIGhheWEgbG9ncmFkbyBkb21pbmFyIGVuIGxhcyAyIHZhcmlhYmxlcyBjb21vIHN1Y2VkacOzIGVuIGxhIGFudGVyaW9yIGdyw6FmaWNhLCBzaW5vIHF1ZSBlbCBwaWxvdG8gcXVlIG9idHV2byBtw6FzIHBvbGVzIGZ1ZSBDaGFybGVzIExlY2xlcmMgbG8gY3VhbCBlcyBiYXN0YW50ZSBpbnVzdWFsIGRlIHZlciBlbiBsYSBzZWd1bmRhIHRlbXBvcmFkYSBkZSB1biBwaWxvdG8gZGUgZm9ybXVsYSAxLCBwZXJvIGVzdG8gbm8gbGUgYmFzdG8gcGFyYSBwb2RlciBvYnRlbmVyIHVuYSBtYXlvciBjYW50aWRhZCBkZSB2aWN0b3JpYXMgZHVyYW50ZSBlc3RlIGHDsW8uIA0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipUYWJsYSoqPC9GT05UPg0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9VFJVRX0NCg0KZGF0b3NfaW50ZXJlc2FudGVzIDwtIHJlYWRfZXhjZWwoIi4vZGF0b3MvZm9ybXVsYTEueGxzeCIsIHNoZWV0ID0gMykNCg0Ka25pdHI6OmthYmxlKGRhdG9zX2ludGVyZXNhbnRlcykNCmBgYA0KDQoNCiMjIyA8Rk9OVCBDT0xPUj0icmVkIj4qKlJlbGFjacOzbiBlbnRyZSBWaWN0b3JpYXMgeSBQb2Rpb3MqKjwvRk9OVD4NCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPVRSVUUsICBvdXQud2lkdGg9IjgwJSJ9DQoNCmdncGxvdChkYXRvc19pbnRlcmVzYW50ZXMsIGFlcyh4ID0gVmljdG9yaWFzLCB5ID0gUG9kaW9zLCBjb2xvciA9IFBpbG90bykpICsgZ2VvbV9wb2ludCgpICsNCnNjYWxlX3hfY29udGludW91cyh0cmFucz0nbG9nMTAnLCBsYWJlbHMgPSBzY2FsZXM6OmNvbW1hKSArDQpnZ3JlcGVsOjpnZW9tX2xhYmVsX3JlcGVsKGdncGxvdDI6OmFlcyhsYWJlbCA9IFBpbG90bykpICsgbGFicyh0aXRsZSA9ICJSRUxBQ0nDk04gRU5UUkUgTEFTIFZJQ1RPUklBUyBZIFBPRElPUyBERSBMT1MgUElMT1RPUyBERSBGMSIgLCB5ID0gIlBvZGlvcyIsIHggPSAiVmljdG9yaWFzIikgKw0KdGhlbWVfYncoKSArICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArICB0aGVtZShwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCmBgYA0KDQojIyMgPEZPTlQgQ09MT1I9InJlZCI+KipSZWxhY2nDs24gZW50cmUgVmljb3RpcmFzIHkgUG9sZXMqKjwvRk9OVD4NCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPVRSVUUsICBvdXQud2lkdGg9IjgwJSJ9DQoNCnAgPC0gZ2dwbG90KGRhdG9zX2ludGVyZXNhbnRlcywgYWVzKHggPSBWaWN0b3JpYXMsIHkgPSBQb2xlcywgY29sb3IgPSBQaWxvdG8pKSArIGdlb21fcG9pbnQoKSArDQpzY2FsZV94X2NvbnRpbnVvdXModHJhbnM9J2xvZzEwJywgbGFiZWxzID0gc2NhbGVzOjpjb21tYSkgKw0KZ2dyZXBlbDo6Z2VvbV9sYWJlbF9yZXBlbChnZ3Bsb3QyOjphZXMobGFiZWwgPSBQaWxvdG8pKSArIGxhYnModGl0bGUgPSAiUkVMQUNJw5NOIEVOVFJFIExBUyBWSUNUT1JJQVMgWSBQT0xFUyBERSBMT1MgUElMT1RPUyBERSBGMSIgLCB5ID0gIlBvbGVzIiwgeCA9ICJWaWN0b3JpYXMiKSArDQp0aGVtZV9idygpICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsgIHRoZW1lKHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQ0KDQoNCg0KYGBgDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9VFJVRSwgIG91dC53aWR0aD0iODAlIn0NCg0KZ2dwbG90bHkocCkNCg0KYGBgDQoNCiMjICAgPEZPTlQgQ09MT1I9InJlZCI+Ny4gSW1hZ2VuIDwvRk9OVD4gDQogRW4gZXN0w6EgaW1hZ2VuIHBvZGVtb3MgYXByZWNpYXIgbGEgZnVlcnRlIGNvbXBldGl0aXZkaWFkIHF1ZSBoYWLDrWEgZW50cmUgbGFzIGVzY3VkZXLDrWEgZGUgRmVycmFyaSB5IE1lcmNlZGVzIHF1ZSBlc3RhYmFuIHBlbGFuZG8gcGFyYSBnYW5hciBlbCBjYW1wZW9uYXRvIG11bmRpYWwuIERlIGZvcm1hIG3DoXMgZGV0YWxsYWRhLCBzZSBwdWVkZSBvYnNlcnZhciBjb21vIGVuIGVsIEdyYW4gUHJlbWlvIGRlIFJ1c2lhLCBDaGFybGVzIExlY2xlcmMgZXN0YSBjb21waXRpZW5kbyBjb250cmEgTGV3aXMgSGFtaWx0b24gcGFyYSBwb2RlciBnYW5hciBlc3RlIGFwcmVjaWFkbyBQcmVtaW8uIA0KIA0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9VFJVRSwgIG91dC53aWR0aD0iODAlIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzIChoZXJlOjpoZXJlKCAiL2ltYWdlbiIsImZlcnJhcml2c21lcmNlZGVzLmpwZyIpKQ0KDQpgYGANCg0KDQoNCg0KIyMgIDxGT05UIENPTE9SPSJyZWQiPjguIENvbmNsdXNpw7NuPC9GT05UPg0KDQpEZW50cm8gZGVsIHRyYWJham8gcmVhbGl6YWRvLCBhbCBmaW5hbCBzZSBwdWVkZSBvYnNlcnZhciBjb21vIExld2lzIEhhbWlsdG9uIGxvZ3JvIGNvbnF1aXN0YXIgcG9yIHNleHRhIHZleiBlbCB0w610dWxvIG11bmRpYWwgZGUgbGEgRm9ybXVsYSAxLiBBZGVtw6FzLCBzZSBwdWRvIG9ic2VydmFyIGNvbW8gbG9ncm8gc3VwZXJhciBhIHN1IGNvbXBhw7Flcm8gZGUgZXF1aXBvIFZhbHR0ZXJpIEJvdHRhcyBwb3IgbcOhcyBkZSAxMDAgcHVudG9zIHF1ZSBvYnR1dm8gZWwgc2VndW5kbyBsdWdhciBlbiBsYSBjbGFzaWZpY2FjacOzbiBnZW5lcmFsLiBUYW1iacOpbiBzZSBwdWVkZSBkZXN0YWNhciBxdWUgZXN0ZSBhw7FvIGhheSBtdWNob3MgcGlsb3RvcyBqw7N2ZW5lcyBxdWUgdGllbmVuIHVuIGdyYW4gZnV0dXJvIHBvciBkZWxhbnRlIGVuIGVzdGEgZ3JhbiBjb21wZXRlY2nDs24gY29tbyBsbyBoYSBkZW1vc3RyYWRvIE1heCBWZXJzdGFwcGVuLCBDaGFybGVzIExlY2xlcmMgbyBQaWVycmUgR2FzbHksIGNvbiBzdXMgaW5jcsOtYmxlcyBjYW50aWRhZCBkZSBwdW50b3MgeSBkZSBsb3MgY3VhbGVzIGxvcyBkb3MgcHJpbWVyb3MgbG9ncmFyb24gdmVuY2VyIGEgc3VzIGNvbXBhw7Flcm9zIGRlIGVxdWlwb3MuDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPVRSVUUsICBvdXQud2lkdGg9IjgwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyAoaGVyZTo6aGVyZSggIi9pbWFnZW4iLCJoYW1pbHRvbmdhbmFuZG9sYXVsdGltYWNhcnJlcmEuanBnIikpDQoNCmBgYA0KDQojIyAgIDxGT05UIENPTE9SPSJyZWQiPjkuIFJlZmVyZW5jaWFzIDwvRk9OVD4gDQoiaHR0cHM6Ly93d3cuc3Fsc2VydmVyY2VudHJhbC5jb20vYXJ0aWNsZXMvYW5hbHl6aW5nLWZvcm11bGEtMS1yZXN1bHRzLWluLXIiDQoNCiJodHRwczovL2VzLndpa2lwZWRpYS5vcmcvd2lraS9UZW1wb3JhZGFfMjAxOV9kZV9GJUMzJUIzcm11bGFfMSINCg0KDQoNCg0KDQoNCg0KDQo=