METHODOLOGIE

Cetta page a pour but de présenter la méthodologie développée dans le cadre du projet TLI.

SCORE

Lignes étudiées



Carte 1 : Localisation des 17 lignes étudiées



Sélection des points kilométriques sur l’Etoile de Saint-Pol

Carte 2 : Localisation des points kilométriques sur l’Etoile de Saint-Pol
if (!requireNamespace("pacman", quietly = TRUE)) install.packages("pacman")
pacman::p_load(sf, dplyr, mapview, tmap, knitr)
mapview(points_kms_decoup)



Calcul des isochrones



Carte 3 : Buffers isochrones sur l’Etoile de Saint-Pol




Tableau des variables calculées pour chaque buffer

knitr::kable(donnees) # caption = "Informations et leurs fournisseurs"
Variables Fournisseurs
Nombre d’habitants (données carroyées) INSEE
Total population active (données communales) INSEE
Lits, emplacements dans les campings et chambres d’hôtels Fichier communal du tourisme (INSEE)
Arrêts de transport en commun Point d’Accès National (données GTFS)
Aménités : loisirs, santé, commerces, restauration, sport SIRENE
Nombre d’élèves (collèges, lycées, BTS) (données communales) Ministère de l’Education nationale
Pistes cyclables (longueur kilométrique) OpenStreetMap
Réseau pédestre (longueur kilométrique) IGN BD TOPO
Routes (longueur kilométrique) IGN BD TOPO
Nombre d’intersections de routes IGN BD TOPO
Ronds-points OpenStreetMap
Nombre de place de parking (données estimées) IGN BD TOPO
Passage à niveau SNCF
Zones artificialisées (données reconstruites) IGN BD TOPO
Pente (pour le vélo) IGN RGE ALTI
Tableau 1 : Liste des variables




Normalisation Min-Max
La normalisation Min-Max redimensionne les données dans un intervalle fixe, souvent [0, 1], en ajustant chaque valeur selon les valeurs minimales et maximales de l’ensemble de données, ce qui est utile pour les modèles sensibles aux variations d’échelle entre les variables. Elle est particulièrement utile pour les algorithmes sensibles aux échelles des variables, comme les algorithmes basés sur les distances. La normalisation Min-Max est souvent utilisée dans les contextes où l’uniformité de l’échelle entre les variables est cruciale.

 normalized_data <- as.data.frame(lapply(dt, function(x) {
   (x - min(x, na.rm = TRUE)) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
 }))




Analyse en composantes principales

Nous disposions de 15 variables pour la voiture et de 16 variables pour la marche et le vélo. Afin de réduire leur nombre nous avons procédé à une ACP sur les données issues des isochrones. Pour commencer, nous observons les variances cumulées des trois ACP. Nous mettons également en évidence les graphiques des variables composants les premières dimensions des axes et nous sélectionnons un ensemble de variables pour chaque mode de déplacement. Cette démarche nous permet d’identifier et de réduire le nombre de variables initialement sélectionnées.

L’ACP à partir des données pédestres révèle que les deux premiers axes cumulent 58% de la variance totale, offrant ainsi une représentation significative des données originales. De cette première analyse nous conservons les valeurs suivantes, qui permettent d’accumuler plus de 50% de la variance expliquée pour chaque dimension : la population, la longueur des routes carrossables, le nombre d’arrêts de transport en commun, le nombre de commerces, le nombre de loisirs, le nombre de restaurants, la surface artificialisée et le nombre de passages à niveau.

gridExtra::grid.arrange(plot1, plot2, 
                        # plot3, 
                        ncol = 2)


Tableau des variables retenues

knitr::kable(donnees) # caption = "Informations et leurs fournisseurs"
Thématiques Variables Fournisseur Intérêts
Démographie Nombre d’habitants (données carroyées 200m) INSEE Indique la densité de population autour des gares, reflétant potentiellement un besoin élevé de services de transport.
Transport Longueurs du réseau routier carrossable IGN BD TOPO Indique l’accessibilité de la gare : un réseau routier plus dense et étendu peut faciliter l’accès
Transport Arrêts de transport en commun Point d’Accès National (données GTFS) Permet de comprendre l’intégration et la connectivité de la gare au sein du réseau de transport local et régional.
Économie locale Aménités : commerces, santé, loisirs, sports, restauration BD SIRENE Donne une idée de la vitalité économique et de l’accessibilité des services autour des gares.
Éducation Nombre d’élèves (collèges, lycées, BTS) (données communales) Ministère de l’Education nationale Indique la présence d’institutions éducatives, suggérant des flux réguliers d’élèves nécessitant des services de transport.
Sécurité et infrastructure Passage à niveau SNCF Souligne les points potentiels de conflit entre le transport ferroviaire et routier, importants pour la planification de la sécurité et l’aménagement urbain.
Urbanisme Zones artificialisées IGN BD TOPO Montre les possibilités de d’aménagement des espaces fonciers.
Topographie Pente (pour la marche et le vélo) IGN RGE ALTI Important pour évaluer l’accessibilité à vélo des gares, influençant la mobilité douce et les choix de transport multimodal.
Tableau 2 : Liste des variables sélectionnées





Somme des variables pour la création d’un score

all_data$total_sum_allegee <-
  all_data$sum_population_carreau+
  all_data$longueur_route+
  all_data$nombre_loisirs+
  all_data$nombre_arrets+
  all_data$nombre_commerces+
  all_data$nombre_restauration+
  all_data$nombre_sports+
  all_data$nombre_sante+
  all_data$nombre_loisirs+
  all_data$ZA+
  all_data$passage_niveau-
  all_data$pente_moyenne

Cartographie du score pour chaque point kilométrique


Carte 4 : Cartographie de l’Etoile de Saint-Pol avec les points sélectionnés – résultats du modèle 10 minutes à pied


Pour plus de détails sur la cartographie vous pouvez consulter ce lien.



ISOCHRONES

tmap_mode('view')
tm_basemap(c(leaflet::providers$Esri.WorldTopoMap,
             leaflet::providers$OpenStreetMap, 
             leaflet::providers$Esri.WorldImageryiders, 
             leaflet::providers$GeoportailFrance.orthos)) + 
  
  tm_shape(isochrones_foot_osrm) + tm_fill('#e77148') + 
  tm_shape(isochrones_foot_geofer) + tm_fill('#75a993') + 
  tm_shape(isochrones_foot_r5r) + tm_fill('#e5b636') + 
  tm_shape(isochrones_OTP) + tm_fill('cornflowerblue') + 
  tm_shape(isochrones_ORS_TOOLS) + tm_fill('brown2') + 
  
  tm_shape(gares_st_pol) + tm_dots()
sup_osrm <- st_area(isochrones_foot_osrm) 
sup_geofer <- st_area(isochrones_foot_geofer) 
sup_r5r <- st_area(isochrones_foot_r5r) 
sup_OTP <- st_area(isochrones_OTP) 
sup_ORSTOOLS <- st_area(isochrones_ORS_TOOLS) 
# Affichage du tableau final
print(total_df_sup)
##          OSRM     GeoFer        R5R        OTP    ORS_Tools
## 1   1301222.8   817358.9  1402476.6  1413534.4 2.627185e+06
## 2    963162.0  1671378.0   654716.2  1767125.5 2.627185e+06
## 3   1635508.9  1216875.2  1890295.8  1675161.8 1.899020e+06
## 4   1546948.5  1004533.7  1405527.9  1772783.4 1.899020e+06
## 5   1359716.6   997720.6  1452324.5  1599670.6 2.488645e+06
## 6   1481211.5  1471163.1  1251927.8   657654.3 2.488645e+06
## 7   1340876.3  1142564.9  1733130.6  1548406.7 2.204523e+06
## 8   1125438.6  1107989.4  1080463.4  1551556.7 2.204523e+06
## 9   1897253.7   989006.7  1978419.7  1831937.7 2.369811e+06
## 10  1424314.3  1249952.5  1363379.8  1570571.0 2.369811e+06
## 11  1541528.6   798649.4  1875319.6  1932814.9 1.972898e+06
## 12  1565308.9  1023062.7  1233608.6  1570571.0 1.972898e+06
## 13  1625501.5   880936.9  1304231.8  1835030.7 1.771767e+06
## 14  1730707.4  1023062.7  1708250.8   995113.5 1.771767e+06
## 15  1610468.0  1358245.0  1809129.0  1441914.9 2.924069e+06
## 16  1722988.0  1530825.4  1890295.8  1551733.7 3.015802e+06
## 17  1635508.9  1360043.7  2895376.6  1912115.5 2.361438e+06
## 18  2577515.8  1483750.7  1087108.5  1550268.8 2.361438e+06
## 19  1036679.1   493971.3  1715659.7  1570571.0 2.364815e+06
## 20  1462742.3  1068565.1  1765202.2  1083763.0 2.364815e+06
## 21  2599206.5   930983.2  1055199.3  1331193.7 2.243323e+06
## 22  1221425.1   879670.4  1890295.8  1671352.8 2.243323e+06
## 23  1635508.9   998850.2  2276807.0  1413534.4 5.377787e+03
## 24  1381397.9   440961.0  2057955.4  1767125.5 5.377787e+03
## 25  1635799.9  1023062.7   721922.3  1675161.8 2.338455e+06
## 26   770438.8  1753109.3  1742870.6  1772783.4 2.338455e+06
## 27  1452460.2  1118685.2  1402476.6  1599670.6 2.488645e+06
## 28  1301222.8   817358.9   654716.2   657654.3 2.488645e+06
## 29   963162.0  1671378.0  1890295.8  1548406.7 3.965363e+06
## 30  1635508.9  1216875.2  1405527.9  1551556.7 3.965363e+06
## 31  1546948.5  1004533.7  1452324.5  1831937.7 6.726445e+03
## 32  1359716.6   997720.6  1251927.8  1570571.0 6.726445e+03
## 33  1481211.5  1471163.1  1733130.6  1932814.9 5.975208e+03
## 34  1340876.3  1142564.9  1080463.4  1570571.0 5.975208e+03
## 35  1125438.6  1107989.4  1978419.7  1835030.7 4.138729e+06
## 36  1897253.7   989006.7  1363379.8   995113.5 4.138729e+06
## 37  1424314.3  1249952.5  1875319.6  1441914.9 2.074481e+06
## 38  1541528.6   798649.4  1233608.6  1551733.7 2.074481e+06
## 39  1565308.9  1023062.7  1304231.8  1912115.5 2.488645e+06
## 40  1625501.5   880936.9  1708250.8  1550268.8 2.488645e+06
## 41  1730707.4  1023062.7  1809129.0  1570571.0 2.548840e+06
## 42  1610468.0  1358245.0  1890295.8  1083763.0 2.548840e+06
## 43  1722988.0  1530825.4  2895376.6  1331193.7 2.479157e+06
## 44  1635508.9  1360043.7  1087108.5  1671352.8 2.479157e+06
## 45  2577515.8  1483750.7  1715659.7  1413534.4 1.320903e+06
## 46  1036679.1   493971.3  1765202.2  1767125.5 1.320903e+06
## 47  1462742.3  1068565.1  1055199.3  1675161.8 2.886865e+06
## 48  2599206.5   930983.2  1890295.8  1772783.4 2.886865e+06
## 49 74464646.9 53455617.1 75684235.7 74298296.7 1.040430e+08

Buffer vs. Iso

# Packages ----
pacman::p_load(sf, mapview, tmap, dplyr, GGally)

# Chargement de la couche des régions de la France métropolitaine
regions_FR_2154 <- sf::st_read("C:/Users/otheureaux/Documents/OT/DECOUPAGES_FR/REGION.shp")
## Reading layer `REGION' from data source 
##   `C:\Users\otheureaux\Documents\OT\DECOUPAGES_FR\REGION.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 13 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 99040 ymin: 6046546 xmax: 1242443 ymax: 7110479
## Projected CRS: RGF93 Lambert 93
# Filter sur la région des Hauts-de-France
hauts_de_france <- regions_FR_2154 %>%   filter(INSEE_REG == 32)
zone_etude <- hauts_de_france

# Chargement des gares
gares <- sf::st_read("C:/Users/otheureaux/Documents/OT/RAILENIUM/BDD_TELLI/GEOFER/gares_2154.gpkg")
## Reading layer `gares' from data source 
##   `C:\Users\otheureaux\Documents\OT\RAILENIUM\BDD_TELLI\GEOFER\gares_2154.gpkg' 
##   using driver `GPKG'
## Simple feature collection with 3489 features and 65 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: 147139.3 ymin: 6147218 xmax: 1079190 ymax: 7108435
## Projected CRS: RGF93 v1 / Lambert-93
gares_select <- gares %>% 
  select(nom_gare, voy_2022)

# Découpage gares HDF
gares_HDR <- sf::st_intersection(gares_select, zone_etude)
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
mapview(gares_HDR)
# Création des buffers
buffers_gares_HDR <- st_buffer(gares_HDR, 1000)
buffers_gares_HDR$superficie <- st_area(buffers_gares_HDR)

# Création des isochones
all_isochrones <- sf::st_read('C:/Users/otheureaux/Documents/OT/6T/R/database_sf/processed_data/isochrones_gares_HDF_foot_15min_20240206.geojson')
## Reading layer `isochrones_gares_HDF_foot_15min_20240206' from data source 
##   `C:\Users\otheureaux\Documents\OT\6T\R\database_sf\processed_data\isochrones_gares_HDF_foot_15min_20240206.geojson' 
##   using driver `GeoJSON'
## Warning in CPL_read_ogr(dsn, layer, query, as.character(options), quiet, : GDAL
## Message 1: Several features with id = 1 have been found. Altering it to be
## unique. This warning will not be emitted anymore for this layer
## Simple feature collection with 393 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 1.523141 ymin: 48.96067 xmax: 4.149771 ymax: 51.07936
## Geodetic CRS:  WGS 84
all_isochrones <- st_transform(all_isochrones, 2154)
all_isochrones$superficie <- st_area(all_isochrones)

# Carto des buffers et des iso
mapview(buffers_gares_HDR) + mapview(all_isochrones)
# Dataframe des superficies
dt <- data.frame(
  buffers_gares_HDR$superficie,
  all_isochrones$superficie
)

dt$rapport <-all_isochrones$superficie / buffers_gares_HDR$superficie*100


all_isochrones$rapport <- dt$rapport
all_isochrones$rapport <- as.numeric(all_isochrones$rapport)
str(all_isochrones)
## Classes 'sf' and 'data.frame':   393 obs. of  7 variables:
##  $ id            : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ isomin        : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ isomax        : num  15 15 15 15 15 15 15 15 15 15 ...
##  $ point.nom_gare: chr  "Pont de la Deûle" "Outreau" "Sous le Bois" "Les Bons-Pères" ...
##  $ geometry      :sfc_MULTIPOLYGON of length 393; first list element: List of 2
##   ..$ :List of 2
##   .. ..$ : num [1:91, 1:2] 705919 705911 705905 705902 705999 ...
##   .. ..$ : num [1:7, 1:2] 706330 706318 706330 706440 706463 ...
##   ..$ :List of 1
##   .. ..$ : num [1:5, 1:2] 706588 706552 706515 706552 706588 ...
##   ..- attr(*, "class")= chr [1:3] "XY" "MULTIPOLYGON" "sfg"
##  $ superficie    : Units: [m^2] num  1303139 401835 1247953 1236118 1557454 ...
##  $ rapport       : num  41.5 12.8 39.7 39.4 49.6 ...
##  - attr(*, "sf_column")= chr "geometry"
##  - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA
##   ..- attr(*, "names")= chr [1:6] "id" "isomin" "isomax" "point.nom_gare" ...
all_isochrones_filter <- all_isochrones %>% 
  filter(rapport < 45)
mapview(all_isochrones_filter) + mapview(buffers_gares_HDR)
LS0tDQp0aXRsZTogIiINCm91dHB1dDogaHRtbF9kb2N1bWVudA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRiwgDQogICAgICAgICAgICAgICAgICAgICAgb3V0LndpZHRoID0gJzEwMCUnKQ0KYGBgDQoNCiMgTUVUSE9ET0xPR0lFIHsudGFic2V0IC51bm51bWJlcmVkfQ0KDQpDZXR0YSBwYWdlICBhIHBvdXIgYnV0IGRlIHByw6lzZW50ZXIgbGEgbcOpdGhvZG9sb2dpZSBkw6l2ZWxvcHDDqWUgZGFucyBsZSBjYWRyZSBkdSBwcm9qZXQgVExJLiAgDQoNCg0KIyMgU0NPUkUNCg0KKipMaWduZXMgw6l0dWRpw6llcyoqDQoNCjxicj4NCjxjZW50ZXI+DQohW10oaW1hZ2VzL2xpZ25lc19URUxMSV9GUi5wbmcpICANCipDYXJ0ZSAxIDogTG9jYWxpc2F0aW9uIGRlcyAxNyBsaWduZXMgw6l0dWRpw6llcyogIA0KPC9jZW50ZXI+DQo8YnI+DQo8YnI+DQoNCioqU8OpbGVjdGlvbiBkZXMgcG9pbnRzIGtpbG9tw6l0cmlxdWVzIHN1ciBsJ0V0b2lsZSBkZSBTYWludC1Qb2wqKg0KDQpgYGB7ciwgZWNobyA9IEYsIGluY2x1ZGU9RkFMU0V9DQpwYWNtYW46OnBfbG9hZChzZiwgZHBseXIsIG1hcHZpZXcsIHRtYXAsIGtuaXRyICkNCiMgQ2hhcmdlbWVudCBkZXMgbGlnbmVzIENFUkVNQSAtLS0tDQpsaWduZXNfQ0VSRU1BIDwtIHNmOjpzdF9yZWFkKCdDOi9Vc2Vycy9vdGhldXJlYXV4L0RvY3VtZW50cy9PVC9SQUlMRU5JVU0vQkREX1RFTExJL0dFT0ZFUi9saWduZXMtcGFyLXN0YXR1dF9xdWVFZENfbW9kaWZPVC5ncGtnJykNCmxpZ25lc19DRVJFTUFfMjE1NCA8LSBzZjo6c3RfdHJhbnNmb3JtKGxpZ25lc19DRVJFTUEsIDIxNTQpDQoNCiMgc8OpbGVjdGlvbiBkZSBsYSBsaWduZSBkZSB0cmF2YWlsDQpsaWduZV9maWx0ZXIgPC0gbGlnbmVzX0NFUkVNQV8yMTU0ICU+JSANCiAgZmlsdGVyKMOpdHVkZS5kZS5jYXMgPT0gJ8OpdG9pbGUgU3QgUG9sJykgIyBJQ0kgaW5zY3JpcmUgbGUgbm9tIGRlIGxhIGxpZ25lIMOgIMOpdHVkaWVyDQoNCiMgQ3LDqWF0aW9uIGRlIGwnZW1wcmlzZSBkZSBsYSB6b25lIGQnw6l0dWRlIC0tLS0NCmxpZ25lX2ZpbHRlcl91bmlvbiA8LSBzZjo6c3RfdW5pb24obGlnbmVfZmlsdGVyKQ0Kem9uZV9ldHVkZSA8LSBzZjo6c3RfYnVmZmVyKGxpZ25lX2ZpbHRlcl91bmlvbiwgNTAwMCkNCnpvbmVfZXR1ZGUgPC0gc3RfYXNfc2Yoem9uZV9ldHVkZSkNCg0KIyBDaGFyZ2VtZW50IGRlIGxhIGNvdWNoZSBkZXMgcG9pbnRzIGtpbG9tw6l0cmlxdWVzIC0tLS0NCnBvaW50c19rbXMgPC0gc2Y6OnN0X3JlYWQoJ0M6L1VzZXJzL290aGV1cmVhdXgvRG9jdW1lbnRzL09UL1JBSUxFTklVTS9ET05ORUVTX0NBUlRPL2RhdGEvbGlzdGUtZGVzLXBrcy5nZW9qc29uJykNCnBvaW50c19rbXMgPC0gcG9pbnRzX2ttcyAlPiUgbXV0YXRlKElEX251bWJlciA9IHJvd19udW1iZXIoKSkNCg0KIyBDcsOpYXRpb24gZGUgbCdlbXByaXNlIHBvdXIgbGUgZMOpY291cGFnZSBkZXMgcG9pbnRzIC0tLS0NCnpvbmVfZXR1ZGVfYnVmZmVyIDwtIHN0X2FzX3NmKHN0X2J1ZmZlcihzdF91bmlvbihsaWduZV9maWx0ZXIpLCA1MCkpDQoNCiMgRMOpY291cGFnZSBkZXMgcGtzIHN1ciBsYSBsaWduZSBzw6lsZWN0aW9ubsOpZQ0KcG9pbnRzX2ttc18yMTU0IDwtIHNmOjpzdF90cmFuc2Zvcm0ocG9pbnRzX2ttcywgMjE1NCkNCnBvaW50c19rbXNfMjE1NF9pbnRlciA8LSBzZjo6c3RfaW50ZXJzZWN0aW9uKHBvaW50c19rbXNfMjE1NCwgem9uZV9ldHVkZV9idWZmZXIpICU+JSANCiAgc2VsZWN0KHBrLCBJRF9udW1iZXIpDQpwb2ludHNfa21zIDwtIHBvaW50c19rbXNfMjE1NF9pbnRlcg0KDQojIENvbnZlcnRpciBsZXMgdmFsZXVycyBkZSAncGsnIGVuIG51bcOpcmlxdWUNCnBrX251bSA8LSBhcy5udW1lcmljKHBvaW50c19rbXMkcGspDQoNCiMgQ3LDqWVyIHVuIHZlY3RldXIgbG9naXF1ZSBwb3VyIGZpbHRyZXIgbGVzIHBrIGVudGllcnMgZXQgY2V1eCBzZSB0ZXJtaW5hbnQgcGFyICw1DQpmaWx0ZXJfY29uZGl0aW9uIDwtIHBrX251bSAlJSAxID09IDANCg0KIyBGaWx0cmVyIGxhIGNvbGxlY3Rpb24gZGUgZm9uY3Rpb25zIHNpbXBsZXMgZW4gdXRpbGlzYW50IGxhIGNvbmRpdGlvbg0KZmlsdGVyZWRfcG9pbnRzX2ttcyA8LSBwb2ludHNfa21zW2ZpbHRlcl9jb25kaXRpb24sIF0NCg0KcG9pbnRzX2ttcyA8LSBzdF90cmFuc2Zvcm0oZmlsdGVyZWRfcG9pbnRzX2ttcywgMjE1NCkNCnBvaW50c19rbXNfZGVjb3VwIDwtIHBvaW50c19rbXMNCmBgYA0KPGNlbnRlcj4NCipDYXJ0ZSAyIDogTG9jYWxpc2F0aW9uIGRlcyBwb2ludHMga2lsb23DqXRyaXF1ZXMgc3VyIGwnRXRvaWxlIGRlIFNhaW50LVBvbCogIA0KPC9jZW50ZXI+DQpgYGB7cn0NCmlmICghcmVxdWlyZU5hbWVzcGFjZSgicGFjbWFuIiwgcXVpZXRseSA9IFRSVUUpKSBpbnN0YWxsLnBhY2thZ2VzKCJwYWNtYW4iKQ0KcGFjbWFuOjpwX2xvYWQoc2YsIGRwbHlyLCBtYXB2aWV3LCB0bWFwLCBrbml0cikNCmBgYA0KDQoNCmBgYHtyLCBvdXQud2lkdGg9JzEwMCUnfQ0KbWFwdmlldyhwb2ludHNfa21zX2RlY291cCkNCmBgYA0KDQo8YnI+DQo8YnI+DQoNCg0KKipDYWxjdWwgZGVzIGlzb2Nocm9uZXMqKg0KDQo8YnI+DQo8Y2VudGVyPg0KIVtdKGltYWdlcy9zYWludF9wb2xfY2FydGVfaXNvY2hyb25lc192Mi5wbmcpICANCipDYXJ0ZSAzIDogQnVmZmVycyBpc29jaHJvbmVzIHN1ciBsJ0V0b2lsZSBkZSBTYWludC1Qb2wqICANCjwvY2VudGVyPg0KPGJyPg0KPGJyPg0KPGJyPg0KKipUYWJsZWF1IGRlcyB2YXJpYWJsZXMgY2FsY3Vsw6llcyBwb3VyIGNoYXF1ZSBidWZmZXIqKiAgDQoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpkb25uZWVzIDwtIGRhdGEuZnJhbWUoDQogICJWYXJpYWJsZXMiID0gYygiTm9tYnJlIGTigJloYWJpdGFudHMgKGRvbm7DqWVzIGNhcnJvecOpZXMpIiwgDQogICAgICAgICAgICAgICAgICAiVG90YWwgcG9wdWxhdGlvbiBhY3RpdmUgKGRvbm7DqWVzIGNvbW11bmFsZXMpIiwNCiAgICAgICAgICAgICAgICAgICJMaXRzLCBlbXBsYWNlbWVudHMgZGFucyBsZXMgY2FtcGluZ3MgZXQgY2hhbWJyZXMgZCdow7R0ZWxzIiwgDQogICAgICAgICAgICAgICAgICAiQXJyw6p0cyBkZSB0cmFuc3BvcnQgZW4gY29tbXVuIiwgDQogICAgICAgICAgICAgICAgICAiQW3DqW5pdMOpcyA6IGxvaXNpcnMsIHNhbnTDqSwgY29tbWVyY2VzLCByZXN0YXVyYXRpb24sIHNwb3J0IiwgDQogICAgICAgICAgICAgICAgICAiTm9tYnJlIGTigJnDqWzDqHZlcyAoY29sbMOoZ2VzLCBseWPDqWVzLCBCVFMpIChkb25uw6llcyBjb21tdW5hbGVzKSIsDQogICAgICAgICAgICAgICAgICAiUGlzdGVzIGN5Y2xhYmxlcyAobG9uZ3VldXIga2lsb23DqXRyaXF1ZSkiLA0KICAgICAgICAgICAgICAgICAgIlLDqXNlYXUgcMOpZGVzdHJlIChsb25ndWV1ciBraWxvbcOpdHJpcXVlKSIsDQogICAgICAgICAgICAgICAgICAiUm91dGVzIChsb25ndWV1ciBraWxvbcOpdHJpcXVlKSIsDQogICAgICAgICAgICAgICAgICAiTm9tYnJlIGTigJlpbnRlcnNlY3Rpb25zIGRlIHJvdXRlcyIsDQogICAgICAgICAgICAgICAgICAiUm9uZHMtcG9pbnRzIiwNCiAgICAgICAgICAgICAgICAgICJOb21icmUgZGUgcGxhY2UgZGUgcGFya2luZyAoZG9ubsOpZXMgZXN0aW3DqWVzKSIsDQogICAgICAgICAgICAgICAgICAiUGFzc2FnZSDDoCBuaXZlYXUiLCANCiAgICAgICAgICAgICAgICAgICJab25lcyBhcnRpZmljaWFsaXPDqWVzIChkb25uw6llcyByZWNvbnN0cnVpdGVzKSIsIA0KICAgICAgICAgICAgICAgICAgIlBlbnRlIChwb3VyIGxlIHbDqWxvKSINCiAgICAgICAgICAgICAgICAgICksDQogIA0KICAiRm91cm5pc3NldXJzIiA9IGMoIklOU0VFIiwgDQogICAgICAgICAgICAgICAgICAgICJJTlNFRSIsDQogICAgICAgICAgICAgICAgICAgICJGaWNoaWVyIGNvbW11bmFsIGR1IHRvdXJpc21lIChJTlNFRSkiLCANCiAgICAgICAgICAgICAgICAgICAgIlBvaW50IGTigJlBY2PDqHMgTmF0aW9uYWwgKGRvbm7DqWVzIEdURlMpIiwgDQogICAgICAgICAgICAgICAgICAgICJTSVJFTkUiLCANCiAgICAgICAgICAgICAgICAgICAgIk1pbmlzdMOocmUgZGUgbOKAmUVkdWNhdGlvbiBuYXRpb25hbGUiLCANCiAgICAgICAgICAgICAgICAgICAgIk9wZW5TdHJlZXRNYXAiLA0KICAgICAgICAgICAgICAgICAgICAiSUdOIEJEIFRPUE8iLCANCiAgICAgICAgICAgICAgICAgICAgIklHTiBCRCBUT1BPIiwgDQogICAgICAgICAgICAgICAgICAgICJJR04gQkQgVE9QTyIsIA0KICAgICAgICAgICAgICAgICAgICAiT3BlblN0cmVldE1hcCIsDQogICAgICAgICAgICAgICAgICAgICJJR04gQkQgVE9QTyIsIA0KICAgICAgICAgICAgICAgICAgICAiU05DRiIsDQogICAgICAgICAgICAgICAgICAgICJJR04gQkQgVE9QTyIsIA0KICAgICAgICAgICAgICAgICAgICAiSUdOIFJHRSBBTFRJIg0KICAgICAgICAgICAgICAgICAgICApDQopDQpgYGANCg0KDQpgYGB7cn0NCmtuaXRyOjprYWJsZShkb25uZWVzKSAjIGNhcHRpb24gPSAiSW5mb3JtYXRpb25zIGV0IGxldXJzIGZvdXJuaXNzZXVycyINCmBgYA0KPGNlbnRlcj4NCjwhLS0gIVtdKGltYWdlcy9kYXRhX3RhYmxlLnBuZykgICAtLT4NCipUYWJsZWF1IDEgOiBMaXN0ZSBkZXMgdmFyaWFibGVzKiAgDQo8L2NlbnRlcj4NCjxicj4NCjxicj4NCjxicj4NCioqTm9ybWFsaXNhdGlvbiBNaW4tTWF4KiogIA0KTGEgbm9ybWFsaXNhdGlvbiBNaW4tTWF4IHJlZGltZW5zaW9ubmUgbGVzIGRvbm7DqWVzIGRhbnMgdW4gaW50ZXJ2YWxsZSBmaXhlLCBzb3V2ZW50IFswLCAxXSwgZW4gYWp1c3RhbnQgY2hhcXVlIHZhbGV1ciBzZWxvbiBsZXMgdmFsZXVycyBtaW5pbWFsZXMgZXQgbWF4aW1hbGVzIGRlIGzigJllbnNlbWJsZSBkZSBkb25uw6llcywgY2UgcXVpIGVzdCB1dGlsZSBwb3VyIGxlcyBtb2TDqGxlcyBzZW5zaWJsZXMgYXV4IHZhcmlhdGlvbnMgZOKAmcOpY2hlbGxlIGVudHJlIGxlcyB2YXJpYWJsZXMuIEVsbGUgZXN0IHBhcnRpY3VsacOocmVtZW50IHV0aWxlIHBvdXIgbGVzIGFsZ29yaXRobWVzIHNlbnNpYmxlcyBhdXggw6ljaGVsbGVzIGRlcyB2YXJpYWJsZXMsIGNvbW1lIGxlcyBhbGdvcml0aG1lcyBiYXPDqXMgc3VyIGxlcyBkaXN0YW5jZXMuIExhIG5vcm1hbGlzYXRpb24gTWluLU1heCBlc3Qgc291dmVudCB1dGlsaXPDqWUgZGFucyBsZXMgY29udGV4dGVzIG/DuSBs4oCZdW5pZm9ybWl0w6kgZGUgbOKAmcOpY2hlbGxlIGVudHJlIGxlcyB2YXJpYWJsZXMgZXN0IGNydWNpYWxlLg0KDQpgYGB7ciwgZXZhbCA9IEZ9DQogbm9ybWFsaXplZF9kYXRhIDwtIGFzLmRhdGEuZnJhbWUobGFwcGx5KGR0LCBmdW5jdGlvbih4KSB7DQogICAoeCAtIG1pbih4LCBuYS5ybSA9IFRSVUUpKSAvIChtYXgoeCwgbmEucm0gPSBUUlVFKSAtIG1pbih4LCBuYS5ybSA9IFRSVUUpKQ0KIH0pKQ0KYGBgDQo8YnI+DQo8YnI+DQo8YnI+DQoNCioqQW5hbHlzZSBlbiBjb21wb3NhbnRlcyBwcmluY2lwYWxlcyoqICANCg0KDQpOb3VzIGRpc3Bvc2lvbnMgZGUgMTUgdmFyaWFibGVzIHBvdXIgbGEgdm9pdHVyZSBldCBkZSAxNiB2YXJpYWJsZXMgcG91ciBsYSBtYXJjaGUgZXQgbGUgdsOpbG8uIEFmaW4gZGUgcsOpZHVpcmUgbGV1ciBub21icmUgbm91cyBhdm9ucyBwcm9jw6lkw6kgw6AgdW5lIEFDUCBzdXIgbGVzIGRvbm7DqWVzIGlzc3VlcyBkZXMgaXNvY2hyb25lcy4gUG91ciBjb21tZW5jZXIsIG5vdXMgb2JzZXJ2b25zIGxlcyB2YXJpYW5jZXMgY3VtdWzDqWVzIGRlcyB0cm9pcyBBQ1AuIE5vdXMgbWV0dG9ucyDDqWdhbGVtZW50IGVuIMOpdmlkZW5jZSBsZXMgZ3JhcGhpcXVlcyBkZXMgdmFyaWFibGVzIGNvbXBvc2FudHMgbGVzIHByZW1pw6hyZXMgZGltZW5zaW9ucyBkZXMgYXhlcyBldCBub3VzIHPDqWxlY3Rpb25ub25zIHVuIGVuc2VtYmxlIGRlIHZhcmlhYmxlcyBwb3VyIGNoYXF1ZSBtb2RlIGRlIGTDqXBsYWNlbWVudC4gQ2V0dGUgZMOpbWFyY2hlIG5vdXMgcGVybWV0IGTigJlpZGVudGlmaWVyIGV0IGRlIHLDqWR1aXJlIGxlIG5vbWJyZSBkZSB2YXJpYWJsZXMgaW5pdGlhbGVtZW50IHPDqWxlY3Rpb25uw6llcy4gIA0KPGJyPg0KDQpgYGB7ciwgb3V0LndpZHRoPScxMDAlJywgZWNobz1GQUxTRSwgaW5jbHVkZSA9IEZ9DQojIFBhY2thZ2VzDQpwYWNtYW46OnBfbG9hZChzZiwgZHBseXIsIEZhY3RvTWluZVIsIGZhY3RvZXh0cmEsIGdncGxvdDIsIHRpZHlyLGd0KQ0KDQojIGRhdGEgbG9hZGluZw0KZGF0YV9mb290X2JlemllcnMgPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9iZXppZXJzX2Zvb3RfMTBtaW5fMjAyNDA1MzAuZ3BrZycpDQpkYXRhX2Zvb3RfY2hhbW9uaXggPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9jaGFtb25peF9mb290XzEwbWluXzIwMjQwNTMwLmdwa2cnKQ0KZGF0YV9mb290X2JheW9ubmUgPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9iYXlvbm5lX2Zvb3RfMTBtaW5fMjAyNDA1MzAuZ3BrZycpDQpkYXRhX2Zvb3RfYmVzYW5jb24gPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9iZXNhbmNvbl9mb290XzEwbWluXzIwMjQwNTMwLmdwa2cnKQ0KZGF0YV9mb290X2JvcmRlYXV4IDwtIHNmOjpzdF9yZWFkKCdwcm9jZXNzZWRfZGF0YS9BTExfREFUQV9OT1JNQUxJWkVEL2FsbF9kYXRhX25vcm1hbGl6ZWRfYm9yZGVhdXhfZm9vdF8xMG1pbl8yMDI0MDUzMC5ncGtnJykNCmRhdGFfZm9vdF9jb2xtYXIgPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9jb2xtYXJfZm9vdF8xMG1pbl8yMDI0MDUzMC5ncGtnJykNCmRhdGFfZm9vdF9jbGVybW9udCA8LSBzZjo6c3RfcmVhZCgncHJvY2Vzc2VkX2RhdGEvQUxMX0RBVEFfTk9STUFMSVpFRC9hbGxfZGF0YV9ub3JtYWxpemVkX2NsZXJtb250X2Zvb3RfMTBtaW5fMjAyNDA1MzAuZ3BrZycpDQpkYXRhX2Zvb3RfZGVhdXZpbGxlIDwtIHNmOjpzdF9yZWFkKCdwcm9jZXNzZWRfZGF0YS9BTExfREFUQV9OT1JNQUxJWkVEL2FsbF9kYXRhX25vcm1hbGl6ZWRfZGVhdXZpbGxlX2Zvb3RfMTBtaW5fMjAyNDA1MzAuZ3BrZycpDQpkYXRhX2Zvb3RfbGltb2dlcyA8LSBzZjo6c3RfcmVhZCgncHJvY2Vzc2VkX2RhdGEvQUxMX0RBVEFfTk9STUFMSVpFRC9hbGxfZGF0YV9ub3JtYWxpemVkX2xpbW9nZXNfZm9vdF8xMG1pbl8yMDI0MDUzMC5ncGtnJykNCmRhdGFfZm9vdF9tYXJzZWlsbGUgPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9tYXJzZWlsbGVfZm9vdF8xMG1pbl8yMDI0MDUzMC5ncGtnJykNCmRhdGFfZm9vdF9yZWltcyA8LSBzZjo6c3RfcmVhZCgncHJvY2Vzc2VkX2RhdGEvQUxMX0RBVEFfTk9STUFMSVpFRC9hbGxfZGF0YV9ub3JtYWxpemVkX3JlaW1zX2Zvb3RfMTBtaW5fMjAyNDA1MzAuZ3BrZycpDQpkYXRhX2Zvb3RfbmFudGVzIDwtIHNmOjpzdF9yZWFkKCdwcm9jZXNzZWRfZGF0YS9BTExfREFUQV9OT1JNQUxJWkVEL2FsbF9kYXRhX25vcm1hbGl6ZWRfbmFudGVzX2Zvb3RfMTBtaW5fMjAyNDA1MzAuZ3BrZycpDQpkYXRhX2Zvb3RfbmltZXMgPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9uaW1lc19mb290XzEwbWluXzIwMjQwNTMwLmdwa2cnKQ0KZGF0YV9mb290X3BhaW1wb2wgPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9wYWltcG9sX2Zvb3RfMTBtaW5fMjAyNDA1MzAuZ3BrZycpDQpkYXRhX2Zvb3RfcmVubmVzIDwtIHNmOjpzdF9yZWFkKCdwcm9jZXNzZWRfZGF0YS9BTExfREFUQV9OT1JNQUxJWkVEL2FsbF9kYXRhX25vcm1hbGl6ZWRfcmVubmVzX2Zvb3RfMTBtaW5fMjAyNDA1MzAuZ3BrZycpDQpkYXRhX2Zvb3Rfc3Rwb2wgPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL0FMTF9EQVRBX05PUk1BTElaRUQvYWxsX2RhdGFfbm9ybWFsaXplZF9zdHBvbF9mb290XzEwbWluXzIwMjQwNTMwLmdwa2cnKQ0KZGF0YV9mb290X3RvdXJzIDwtIHNmOjpzdF9yZWFkKCdwcm9jZXNzZWRfZGF0YS9BTExfREFUQV9OT1JNQUxJWkVEL2FsbF9kYXRhX25vcm1hbGl6ZWRfdG91cnNfZm9vdF8xMG1pbl8yMDI0MDUzMC5ncGtnJykNCm5hbWVzKGRhdGFfZm9vdF9jaGFtb25peCkNCg0KIyBkw6l0YWlsIHNjb3JlIFNhaW50IFBvbA0KZGF0YV9mb290X3N0cG9sJHRvdGFsX3N1bV9hbGxlZ2VlDQpzdW1tYXJ5KGRhdGFfZm9vdF9zdHBvbCR0b3RhbF9zdW1fYWxsZWdlZSkNCm5hbWVzKGRhdGFfZm9vdF9iYXlvbm5lKQ0KDQpkYXRhX2Zvb3RfYmV6aWVycyA8LSAgZGF0YV9mb290X2JlemllcnMgJT4lIA0KICBzZWxlY3Qoc3VtX2xpdHMsIGxvbmd1ZXVyX3JvdXRlLGxvbmd1ZXVyX3Bpc3Rlc19jeWNsYWJsZXMsIG5vbWJyZV9hcnJldHMgPSBub21icmVfYXJyZXRzX3YzLCBub21icmVfcGFya2luZ3MsIG5vbWJyZV9jb21tZXJjZXMsIG5vbWJyZV9sb2lzaXJzLCBub21icmVfc2FudGUsbm9tYnJlX3Jlc3RhdXJhdGlvbiwgIG5vbWJyZV9zcG9ydHMsIG5vbWJyZV9yb25kc19wb2ludHMsIG5vbWJyZV9lbGV2ZXMscGFzc2FnZV9uaXZlYXUsIFpBLHN1bV9wb3B1bGF0aW9uX2NhcnJlYXVfZGVjb3VwLCBwZW50ZV9tb3llbm5lKQ0KZGF0YV9mb290X2NoYW1vbml4IDwtIGRhdGFfZm9vdF9jaGFtb25peCAlPiUgDQogIHNlbGVjdChzdW1fbGl0cywgbG9uZ3VldXJfcm91dGUsbG9uZ3VldXJfcGlzdGVzX2N5Y2xhYmxlcywgbm9tYnJlX2FycmV0cyA9IG5vbWJyZV9hcnJldHNfdjIsIG5vbWJyZV9wYXJraW5ncywgbm9tYnJlX2NvbW1lcmNlcywgbm9tYnJlX2xvaXNpcnMsIG5vbWJyZV9zYW50ZSxub21icmVfcmVzdGF1cmF0aW9uLCAgbm9tYnJlX3Nwb3J0cywgbm9tYnJlX3JvbmRzX3BvaW50cywgbm9tYnJlX2VsZXZlcyxwYXNzYWdlX25pdmVhdSwgWkEsc3VtX3BvcHVsYXRpb25fY2FycmVhdV9kZWNvdXAsIHBlbnRlX21veWVubmUpDQpkYXRhX2Zvb3RfYmF5b25uZSA8LSBkYXRhX2Zvb3RfYmF5b25uZSAlPiUgDQogIHNlbGVjdChzdW1fbGl0cywgbG9uZ3VldXJfcm91dGUsbG9uZ3VldXJfcGlzdGVzX2N5Y2xhYmxlcywgbm9tYnJlX2FycmV0cyA9IG5vbWJyZV9hcnJldHNfdjIsIG5vbWJyZV9wYXJraW5ncywgbm9tYnJlX2NvbW1lcmNlcywgbm9tYnJlX2xvaXNpcnMsIG5vbWJyZV9zYW50ZSxub21icmVfcmVzdGF1cmF0aW9uLCAgbm9tYnJlX3Nwb3J0cywgbm9tYnJlX3JvbmRzX3BvaW50cywgbm9tYnJlX2VsZXZlcyxwYXNzYWdlX25pdmVhdSwgWkEsc3VtX3BvcHVsYXRpb25fY2FycmVhdV9kZWNvdXAsIHBlbnRlX21veWVubmUpDQpkYXRhX2Zvb3RfYmVzYW5jb24gPC0gZGF0YV9mb290X2Jlc2FuY29uICU+JSANCiAgc2VsZWN0KHN1bV9saXRzLCBsb25ndWV1cl9yb3V0ZSxsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLCBub21icmVfYXJyZXRzID0gbm9tYnJlX2FycmV0c192Miwgbm9tYnJlX3BhcmtpbmdzLCBub21icmVfY29tbWVyY2VzLCBub21icmVfbG9pc2lycywgbm9tYnJlX3NhbnRlLG5vbWJyZV9yZXN0YXVyYXRpb24sICBub21icmVfc3BvcnRzLCBub21icmVfcm9uZHNfcG9pbnRzLCBub21icmVfZWxldmVzLHBhc3NhZ2Vfbml2ZWF1LCBaQSxzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwgcGVudGVfbW95ZW5uZSkNCmRhdGFfZm9vdF9ib3JkZWF1eCA8LSBkYXRhX2Zvb3RfYm9yZGVhdXggJT4lIA0KICBzZWxlY3Qoc3VtX2xpdHMsIGxvbmd1ZXVyX3JvdXRlLGxvbmd1ZXVyX3Bpc3Rlc19jeWNsYWJsZXMsIG5vbWJyZV9hcnJldHMgPSBub21icmVfYXJyZXRzX3YyLCBub21icmVfcGFya2luZ3MsIG5vbWJyZV9jb21tZXJjZXMsIG5vbWJyZV9sb2lzaXJzLCBub21icmVfc2FudGUsbm9tYnJlX3Jlc3RhdXJhdGlvbiwgIG5vbWJyZV9zcG9ydHMsIG5vbWJyZV9yb25kc19wb2ludHMsIG5vbWJyZV9lbGV2ZXMscGFzc2FnZV9uaXZlYXUsIFpBLHN1bV9wb3B1bGF0aW9uX2NhcnJlYXVfZGVjb3VwLCBwZW50ZV9tb3llbm5lKQ0KZGF0YV9mb290X2NvbG1hciA8LSBkYXRhX2Zvb3RfY29sbWFyICU+JSANCiAgc2VsZWN0KHN1bV9saXRzLCBsb25ndWV1cl9yb3V0ZSxsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLCBub21icmVfYXJyZXRzID0gbm9tYnJlX2FycmV0c192Miwgbm9tYnJlX3BhcmtpbmdzLCBub21icmVfY29tbWVyY2VzLCBub21icmVfbG9pc2lycywgbm9tYnJlX3NhbnRlLG5vbWJyZV9yZXN0YXVyYXRpb24sICBub21icmVfc3BvcnRzLCBub21icmVfcm9uZHNfcG9pbnRzLCBub21icmVfZWxldmVzLHBhc3NhZ2Vfbml2ZWF1LCBaQSxzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwgcGVudGVfbW95ZW5uZSkNCmRhdGFfZm9vdF9jbGVybW9udCA8LSBkYXRhX2Zvb3RfY2xlcm1vbnQgJT4lIA0KICBzZWxlY3Qoc3VtX2xpdHMsIGxvbmd1ZXVyX3JvdXRlLGxvbmd1ZXVyX3Bpc3Rlc19jeWNsYWJsZXMsIG5vbWJyZV9hcnJldHMgPSBub21icmVfYXJyZXRzX3YyLCBub21icmVfcGFya2luZ3MsIG5vbWJyZV9jb21tZXJjZXMsIG5vbWJyZV9sb2lzaXJzLCBub21icmVfc2FudGUsbm9tYnJlX3Jlc3RhdXJhdGlvbiwgIG5vbWJyZV9zcG9ydHMsIG5vbWJyZV9yb25kc19wb2ludHMsIG5vbWJyZV9lbGV2ZXMscGFzc2FnZV9uaXZlYXUsIFpBLHN1bV9wb3B1bGF0aW9uX2NhcnJlYXVfZGVjb3VwLCBwZW50ZV9tb3llbm5lKQ0KZGF0YV9mb290X2RlYXV2aWxsZSA8LSBkYXRhX2Zvb3RfZGVhdXZpbGxlICU+JSANCiAgc2VsZWN0KHN1bV9saXRzLCBsb25ndWV1cl9yb3V0ZSxsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLCBub21icmVfYXJyZXRzID0gbm9tYnJlX2FycmV0c192Miwgbm9tYnJlX3BhcmtpbmdzLCBub21icmVfY29tbWVyY2VzLCBub21icmVfbG9pc2lycywgbm9tYnJlX3NhbnRlLG5vbWJyZV9yZXN0YXVyYXRpb24sICBub21icmVfc3BvcnRzLCBub21icmVfcm9uZHNfcG9pbnRzLCBub21icmVfZWxldmVzLHBhc3NhZ2Vfbml2ZWF1LCBaQSxzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwgcGVudGVfbW95ZW5uZSkNCmRhdGFfZm9vdF9saW1vZ2VzIDwtIGRhdGFfZm9vdF9saW1vZ2VzICU+JSANCiAgc2VsZWN0KHN1bV9saXRzLCBsb25ndWV1cl9yb3V0ZSxsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLCBub21icmVfYXJyZXRzID0gbm9tYnJlX2FycmV0c192Miwgbm9tYnJlX3BhcmtpbmdzLCBub21icmVfY29tbWVyY2VzLCBub21icmVfbG9pc2lycywgbm9tYnJlX3NhbnRlLG5vbWJyZV9yZXN0YXVyYXRpb24sICBub21icmVfc3BvcnRzLCBub21icmVfcm9uZHNfcG9pbnRzLCBub21icmVfZWxldmVzLHBhc3NhZ2Vfbml2ZWF1LCBaQSxzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwgcGVudGVfbW95ZW5uZSkNCmRhdGFfZm9vdF9tYXJzZWlsbGUgPC0gZGF0YV9mb290X21hcnNlaWxsZSAlPiUgDQogIHNlbGVjdChzdW1fbGl0cywgbG9uZ3VldXJfcm91dGUsbG9uZ3VldXJfcGlzdGVzX2N5Y2xhYmxlcywgbm9tYnJlX2FycmV0cyA9IG5vbWJyZV9hcnJldHNfdjIsIG5vbWJyZV9wYXJraW5ncywgbm9tYnJlX2NvbW1lcmNlcywgbm9tYnJlX2xvaXNpcnMsIG5vbWJyZV9zYW50ZSxub21icmVfcmVzdGF1cmF0aW9uLCAgbm9tYnJlX3Nwb3J0cywgbm9tYnJlX3JvbmRzX3BvaW50cywgbm9tYnJlX2VsZXZlcyxwYXNzYWdlX25pdmVhdSwgWkEsc3VtX3BvcHVsYXRpb25fY2FycmVhdV9kZWNvdXAsIHBlbnRlX21veWVubmUpDQpkYXRhX2Zvb3RfcmVpbXMgPC0gZGF0YV9mb290X3JlaW1zICU+JSANCiAgc2VsZWN0KHN1bV9saXRzLCBsb25ndWV1cl9yb3V0ZSxsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLCBub21icmVfYXJyZXRzID0gbm9tYnJlX2FycmV0c192Miwgbm9tYnJlX3BhcmtpbmdzLCBub21icmVfY29tbWVyY2VzLCBub21icmVfbG9pc2lycywgbm9tYnJlX3NhbnRlLG5vbWJyZV9yZXN0YXVyYXRpb24sICBub21icmVfc3BvcnRzLCBub21icmVfcm9uZHNfcG9pbnRzLCBub21icmVfZWxldmVzLHBhc3NhZ2Vfbml2ZWF1LCBaQSxzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwgcGVudGVfbW95ZW5uZSkNCmRhdGFfZm9vdF9uYW50ZXMgPC0gZGF0YV9mb290X25hbnRlcyAlPiUgDQogIHNlbGVjdChzdW1fbGl0cywgbG9uZ3VldXJfcm91dGUsbG9uZ3VldXJfcGlzdGVzX2N5Y2xhYmxlcywgbm9tYnJlX2FycmV0cyA9IG5vbWJyZV9hcnJldHNfdjIsIG5vbWJyZV9wYXJraW5ncywgbm9tYnJlX2NvbW1lcmNlcywgbm9tYnJlX2xvaXNpcnMsIG5vbWJyZV9zYW50ZSxub21icmVfcmVzdGF1cmF0aW9uLCAgbm9tYnJlX3Nwb3J0cywgbm9tYnJlX3JvbmRzX3BvaW50cywgbm9tYnJlX2VsZXZlcyxwYXNzYWdlX25pdmVhdSwgWkEsc3VtX3BvcHVsYXRpb25fY2FycmVhdV9kZWNvdXAsIHBlbnRlX21veWVubmUpDQpkYXRhX2Zvb3RfbmltZXMgPC0gZGF0YV9mb290X25pbWVzICU+JSANCiAgc2VsZWN0KHN1bV9saXRzLCBsb25ndWV1cl9yb3V0ZSxsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLCBub21icmVfYXJyZXRzID0gbm9tYnJlX2FycmV0c192Miwgbm9tYnJlX3BhcmtpbmdzLCBub21icmVfY29tbWVyY2VzLCBub21icmVfbG9pc2lycywgbm9tYnJlX3NhbnRlLG5vbWJyZV9yZXN0YXVyYXRpb24sICBub21icmVfc3BvcnRzLCBub21icmVfcm9uZHNfcG9pbnRzLCBub21icmVfZWxldmVzLHBhc3NhZ2Vfbml2ZWF1LCBaQSxzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwgcGVudGVfbW95ZW5uZSkNCmRhdGFfZm9vdF9wYWltcG9sIDwtIGRhdGFfZm9vdF9wYWltcG9sICU+JSANCiAgc2VsZWN0KHN1bV9saXRzLCBsb25ndWV1cl9yb3V0ZSxsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLCBub21icmVfYXJyZXRzID0gbm9tYnJlX2FycmV0c192Miwgbm9tYnJlX3BhcmtpbmdzLCBub21icmVfY29tbWVyY2VzLCBub21icmVfbG9pc2lycywgbm9tYnJlX3NhbnRlLG5vbWJyZV9yZXN0YXVyYXRpb24sICBub21icmVfc3BvcnRzLCBub21icmVfcm9uZHNfcG9pbnRzLCBub21icmVfZWxldmVzLHBhc3NhZ2Vfbml2ZWF1LCBaQSxzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwgcGVudGVfbW95ZW5uZSkNCmRhdGFfZm9vdF9yZW5uZXMgPC0gZGF0YV9mb290X3Jlbm5lcyAlPiUgDQogIHNlbGVjdChzdW1fbGl0cywgbG9uZ3VldXJfcm91dGUsbG9uZ3VldXJfcGlzdGVzX2N5Y2xhYmxlcywgbm9tYnJlX2FycmV0cyA9IG5vbWJyZV9hcnJldHNfdjIsIG5vbWJyZV9wYXJraW5ncywgbm9tYnJlX2NvbW1lcmNlcywgbm9tYnJlX2xvaXNpcnMsIG5vbWJyZV9zYW50ZSxub21icmVfcmVzdGF1cmF0aW9uLCAgbm9tYnJlX3Nwb3J0cywgbm9tYnJlX3JvbmRzX3BvaW50cywgbm9tYnJlX2VsZXZlcyxwYXNzYWdlX25pdmVhdSwgWkEsc3VtX3BvcHVsYXRpb25fY2FycmVhdV9kZWNvdXAsIHBlbnRlX21veWVubmUpDQpkYXRhX2Zvb3Rfc3Rwb2wgPC0gZGF0YV9mb290X3N0cG9sICU+JSANCiAgc2VsZWN0KHN1bV9saXRzLCBsb25ndWV1cl9yb3V0ZSxsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLCBub21icmVfYXJyZXRzID0gbm9tYnJlX2FycmV0c192Miwgbm9tYnJlX3BhcmtpbmdzLCBub21icmVfY29tbWVyY2VzLCBub21icmVfbG9pc2lycywgbm9tYnJlX3NhbnRlLG5vbWJyZV9yZXN0YXVyYXRpb24sICBub21icmVfc3BvcnRzLCBub21icmVfcm9uZHNfcG9pbnRzLCBub21icmVfZWxldmVzLHBhc3NhZ2Vfbml2ZWF1LCBaQSxzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwgcGVudGVfbW95ZW5uZSkNCmRhdGFfZm9vdF90b3VycyA8LSBkYXRhX2Zvb3RfdG91cnMgJT4lIA0KICBzZWxlY3Qoc3VtX2xpdHMsIGxvbmd1ZXVyX3JvdXRlLGxvbmd1ZXVyX3Bpc3Rlc19jeWNsYWJsZXMsIG5vbWJyZV9hcnJldHMgPSBub21icmVfYXJyZXRzX3YyLCBub21icmVfcGFya2luZ3MsIG5vbWJyZV9jb21tZXJjZXMsIG5vbWJyZV9sb2lzaXJzLCBub21icmVfc2FudGUsbm9tYnJlX3Jlc3RhdXJhdGlvbiwgIG5vbWJyZV9zcG9ydHMsIG5vbWJyZV9yb25kc19wb2ludHMsIG5vbWJyZV9lbGV2ZXMscGFzc2FnZV9uaXZlYXUsIFpBLHN1bV9wb3B1bGF0aW9uX2NhcnJlYXVfZGVjb3VwLCBwZW50ZV9tb3llbm5lKQ0KDQpkYXRhX2FsbDwtIHJiaW5kKA0KICBkYXRhX2Zvb3RfYmV6aWVycywNCiAgZGF0YV9mb290X2NoYW1vbml4LA0KICBkYXRhX2Zvb3RfYmF5b25uZSwNCiAgZGF0YV9mb290X2Jlc2FuY29uLA0KICBkYXRhX2Zvb3RfYm9yZGVhdXgsIA0KICBkYXRhX2Zvb3RfY29sbWFyICwNCiAgZGF0YV9mb290X2NsZXJtb250ICwNCiAgZGF0YV9mb290X2RlYXV2aWxsZSwgDQogIGRhdGFfZm9vdF9saW1vZ2VzICwNCiAgZGF0YV9mb290X21hcnNlaWxsZSwgDQogIGRhdGFfZm9vdF9yZWltcywNCiAgZGF0YV9mb290X25hbnRlcyAsDQogIGRhdGFfZm9vdF9uaW1lcyAsDQogIGRhdGFfZm9vdF9wYWltcG9sLCANCiAgZGF0YV9mb290X3Jlbm5lcywNCiAgZGF0YV9mb290X3N0cG9sLCANCiAgZGF0YV9mb290X3RvdXJzKQ0KDQpuYW1lcyhkYXRhX2FsbCkNCmRhdGFfc2VsZWN0IDwtIGRhdGFfYWxsICU+JQ0KICBzZWxlY3QoDQogICAgcG9wX2NhcnJlYXUgPSBzdW1fcG9wdWxhdGlvbl9jYXJyZWF1X2RlY291cCwNCiAgICBzdW1fbGl0cywNCiAgICBsb25ndWV1cl9yb3V0ZSwNCiAgICBsb25ndWV1cl9waXN0ZXNfY3ljbGFibGVzLA0KICAgIG5vbWJyZV9hcnJldHMsDQogICAgbm9tYnJlX3BhcmtpbmdzLA0KICAgIG5vbWJyZV9yb25kc19wb2ludHMsDQogICAgbm9tYnJlX2NvbW1lcmNlcywNCiAgICBub21icmVfbG9pc2lycywNCiAgICBub21icmVfcmVzdGF1cmF0aW9uLA0KICAgIG5vbWJyZV9zcG9ydHMsDQogICAgbm9tYnJlX3NhbnRlLA0KICAgIG5vbWJyZV9lbGV2ZXMsDQogICAgWkEsDQogICAgcGFzc2FnZV9uaXZlYXUsDQogICAgcGVudGVfbW95ZW5uZQ0KICApICU+JSANCiAgc3RfZHJvcF9nZW9tZXRyeSgpDQpnbGltcHNlKGRhdGFfc2VsZWN0KQ0KDQojIENhbGN1bGUgbGEgY29ycsOpbGF0aW9uIGRlIFBlYXJzb24gZW50cmUgbGUgc2NvcmUgZXQgY2hhcXVlIHZhcmlhYmxlIGV4cGxpY2F0aXZlDQpjb3JyZWxhdGlvbnMgPC0gY29yKGRhdGFfc2VsZWN0KQ0KDQojIEFmZmljaGUgbGVzIGNvcnLDqWxhdGlvbnMNCnByaW50KGNvcnJlbGF0aW9ucykNCg0KIyBBc3N1cmV6LXZvdXMgcXVlIGNvcnJlbGF0aW9ucyBlc3QgdW4gZGF0YWZyYW1lDQpjb3JyZWxhdGlvbnNfZGYgPC0gYXMuZGF0YS5mcmFtZShjb3JyZWxhdGlvbnMpDQpuYW1lcyhjb3JyZWxhdGlvbnNfZGYpDQoNCiMgQ29ycmVsYXRpb25zIGVzdCBsYSBtYXRyaWNlIGRlIGNvcnLDqWxhdGlvbg0KY29ycmVsYXRpb25zX2RmX2xvbmcgPC0gcGl2b3RfbG9uZ2VyKGNvcnJlbGF0aW9uc19kZiwgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHMgPSBldmVyeXRoaW5nKCksICAjIFBpdm90ZXIgdG91dGVzIGxlcyBjb2xvbm5lcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlZhcmlhYmxlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIkNvcnJlbGF0aW9uIikNCg0KIyBDcsOpYXRpb24gZHUgdGFibGVhdQ0KZ3RfdGFibGUgPC0gZ3QoY29ycmVsYXRpb25zX2RmX2xvbmcpICU+JQ0KICBjb2xzX2xhYmVsKA0KICAgIFZhcmlhYmxlID0gIlZhcmlhYmxlIiwNCiAgICBDb3JyZWxhdGlvbiA9ICJDb3JyZWxhdGlvbiINCiAgKQ0KDQpndF90YWJsZQ0KDQojIExhbmNlbWVudCBkZSBsJ0FDUA0KUENBIDwtIFBDQShkYXRhX3NlbGVjdCwgc2NhbGUudW5pdCA9IFQpDQoNCiMgQWZmaWNoYWdlIGRlcyB2YWxldXJzIHByb3ByZXMNCnByaW50KCJWYWxldXJzIHByb3ByZXMgKHZhcmlhbmNlIGV4cGxpcXXDqWUgcGFyIGNoYXF1ZSBjb21wb3NhbnRlKSA6IikNCnByaW50KFBDQSRlaWcpDQoNCiMgQ29udHJpYnV0aW9ucyBkZXMgdmFyaWFibGVzIGF1eCBjb21wb3NhbnRlcyBwcmluY2lwYWxlcw0KY29udHJpYiA8LSBhcy5kYXRhLmZyYW1lKFBDQSR2YXIkY29udHJpYikNCnByaW50KGNvbnRyaWIpDQoNCnRocmVzaG9sZCA8LSBxdWFudGlsZShjb250cmliJERpbS4xLCANCiAgICAgICAgICAgICAgICAgICAgICAwLjUwKQ0KDQojIFPDqWxlY3Rpb24gZGVzIHZhcmlhYmxlcyBpbXBvcnRhbnRlcw0KIyBQYXIgZXhlbXBsZSwgdm91cyBwb3V2ZXogc8OpbGVjdGlvbm5lciBsZXMgdmFyaWFibGVzIGF2ZWMgdW5lIGNvbnRyaWJ1dGlvbiDDqWxldsOpZSDDoCBsYSBwcmVtacOocmUgY29tcG9zYW50ZSBwcmluY2lwYWxlDQpzZWxlY3RlZF92YXJzX2Zvb3RfZGltMSA8LSByb3duYW1lcyhjb250cmliW2NvbnRyaWIkRGltLjEgPiB0aHJlc2hvbGQsIF0pDQpwcmludChzZWxlY3RlZF92YXJzX2Zvb3RfZGltMSkNCnNlbGVjdGVkX3ZhcnNfZm9vdF9kaW0yIDwtIHJvd25hbWVzKGNvbnRyaWJbY29udHJpYiREaW0uMiA+IHRocmVzaG9sZCwgXSkNCnByaW50KHNlbGVjdGVkX3ZhcnNfZm9vdF9kaW0yKQ0KDQpzZWxlY3RlZF92YXJzX2NvciA8LSBkYXRhX3NlbGVjdCAlPiUNCiAgc2VsZWN0KHBvcF9jYXJyZWF1LA0KICAgIGxvbmd1ZXVyX3JvdXRlLA0KICAgIG5vbWJyZV9hcnJldHMgLA0KICAgIG5vbWJyZV9jb21tZXJjZXMsDQogICAgbm9tYnJlX2xvaXNpcnMsDQogICAgbm9tYnJlX3Jlc3RhdXJhdGlvbiwNCiAgICBaQSwgcGFzc2FnZV9uaXZlYXUsIHBlbnRlX21veWVubmUgICkNCg0KIyBDYWxjdWxlIGxhIGNvcnLDqWxhdGlvbiBkZSBQZWFyc29uIGVudHJlIGxlIHNjb3JlIGV0IGNoYXF1ZSB2YXJpYWJsZSBleHBsaWNhdGl2ZQ0Kc2VsZWN0ZWRfdmFyc19jb3JyZWxhdGlvbnMgPC0gY29yKHNlbGVjdGVkX3ZhcnNfY29yKQ0KDQojIEFmZmljaGUgbGVzIGNvcnLDqWxhdGlvbnMNCnByaW50KHNlbGVjdGVkX3ZhcnNfY29ycmVsYXRpb25zKQ0KDQojIElkZW50aWZpY2F0aW9uIGRlcyBjb21wb3NhbnRlcyBkb250IGxhIHZhbGV1ciBwcm9wcmUgZXN0IHN1cMOpcmlldXJlIMOgIDEgKGNyaXTDqHJlIGRlIEthaXNlcikNCmNvbXBvc2FudGVzX3V0aWxlcyA8LSBQQ0EkZWlnW1BDQSRlaWdbLDFdID4gMSwgLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRV0NCnByaW50KCJDb21wb3NhbnRlcyBhdmVjIHVuZSB2YXJpYW5jZSA+IDEgOiIpDQpwcmludChjb21wb3NhbnRlc191dGlsZXMpDQoNCiMgVmlzdWFsaXNhdGlvbiBkZXMgdmFsZXVycyBwcm9wcmVzDQpmdml6X2VpZyhQQ0EsIGFkZGxhYmVscyA9IFRSVUUsIHlsaW0gPSBjKDAsIDUwKSkNCg0KIyBDZXJjbGUgZGVzIGNvcnLDqWxhdGlvbnMNCmZ2aXpfcGNhX3ZhcihQQ0EsIGNvbC52YXI9ImNvbnRyaWIiLCANCiAgICAgICAgICAgICBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjRTdCODAwIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNGQzRFMDciKSwNCiAgICAgICAgICAgICByZXBlbCA9IFRSVUUpDQoNCiMgR3JhcGhpcXVlIGRlcyBpbmRpdmlkdXMNCmZ2aXpfcGNhX2luZChQQ0EsIGNvbC5pbmQgPSAiY29zMiIsIA0KICAgICAgICAgICAgIGdyYWRpZW50LmNvbHMgPSBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiLCAiI0ZDNEUwNyIpLA0KICAgICAgICAgICAgIHJlcGVsID0gVFJVRSkNCg0KIyBDb250cmlidXRpb24gZGUgY2hhcXVlIHZhcmlhYmxlIGF1eCBkZXV4IHByZW1pZXJzIGF4ZXMNCmZ2aXpfY29udHJpYihQQ0EsIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMSkgIyBheGUgMQ0KZnZpel9jb250cmliKFBDQSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAyKSAjIGF4ZSAyDQpmdml6X2NvbnRyaWIoUENBLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDMpICMgYXhlIDMNCg0KIyBDb250cmlidXRpb24gZGUgY2hhcXVlIHZhcmlhYmxlIGF1eCB0cm9pcyBwcmVtaWVycyBheGVzDQpwbG90MSA8LSBmdml6X2NvbnRyaWIoUENBLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDEsIGZpbGwgPSAnbGlnaHRzbGF0ZWdyZXknKQ0KIyA/ZnZpel9jb250cmliDQpwbG90MiA8LSBmdml6X2NvbnRyaWIoUENBLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDIsIGZpbGwgPSAnbGlnaHRzbGF0ZWdyZXknKSAjIGF4ZSAyDQpwbG90MyA8LSBmdml6X2NvbnRyaWIoUENBLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDMsIGZpbGwgPSAnbGlnaHRzbGF0ZWdyZXknKSAjIGF4ZSAzDQoNCmBgYA0KDQpMJ0FDUCDDoCBwYXJ0aXIgZGVzIGRvbm7DqWVzIHDDqWRlc3RyZXMgcsOpdsOobGUgcXVlIGxlcyBkZXV4IHByZW1pZXJzIGF4ZXMgY3VtdWxlbnQgNTglIGRlIGxhIHZhcmlhbmNlIHRvdGFsZSwgb2ZmcmFudCBhaW5zaSB1bmUgcmVwcsOpc2VudGF0aW9uIHNpZ25pZmljYXRpdmUgZGVzIGRvbm7DqWVzIG9yaWdpbmFsZXMuIERlIGNldHRlIHByZW1pw6hyZSBhbmFseXNlIG5vdXMgY29uc2Vydm9ucyBsZXMgdmFsZXVycyBzdWl2YW50ZXMsIHF1aSBwZXJtZXR0ZW50IGTigJlhY2N1bXVsZXIgcGx1cyBkZSA1MCUgZGUgbGEgdmFyaWFuY2UgZXhwbGlxdcOpZSBwb3VyIGNoYXF1ZSBkaW1lbnNpb24gOiBsYSBwb3B1bGF0aW9uLCBsYSBsb25ndWV1ciBkZXMgcm91dGVzIGNhcnJvc3NhYmxlcywgIGxlIG5vbWJyZSBk4oCZYXJyw6p0cyBkZSB0cmFuc3BvcnQgZW4gY29tbXVuLCAgbGUgbm9tYnJlIGRlIGNvbW1lcmNlcywgbGUgbm9tYnJlIGRlIGxvaXNpcnMsIGxlIG5vbWJyZSBkZSByZXN0YXVyYW50cywgbGEgc3VyZmFjZSBhcnRpZmljaWFsaXPDqWUgZXQgbGUgbm9tYnJlIGRlIHBhc3NhZ2VzIMOgIG5pdmVhdS4gIA0KDQpgYGB7ciwgb3V0LndpZHRoPScxMDAlJ30NCmdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKHBsb3QxLCBwbG90MiwgDQogICAgICAgICAgICAgICAgICAgICAgICAjIHBsb3QzLCANCiAgICAgICAgICAgICAgICAgICAgICAgIG5jb2wgPSAyKQ0KDQpgYGANCg0KDQoqKiogDQoqKlRhYmxlYXUgZGVzIHZhcmlhYmxlcyByZXRlbnVlcyoqICANCg0KPCEtLSA8Y2VudGVyPiAtLT4NCjwhLS0gIVtdKGltYWdlcy9kYXRhX3RhYmxlX2FsbGVnZWUucG5nKSAgIC0tPg0KPCEtLSAqVGFibGVhdSAyIDogTGlzdGUgZGVzIHZhcmlhYmxlcyBzw6lsZWN0aW9ubsOpZXMqICAgLS0+DQo8IS0tIDwvY2VudGVyPiAtLT4NCg0KPCEtLSB8IFZhcmlhYmxlcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBGb3Vybmlzc2V1ciAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0tPg0KPCEtLSB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18IC0tPg0KPCEtLSB8IE5vbWJyZSBk4oCZaGFiaXRhbnRzIChkb25uw6llcyBjYXJyb3nDqWVzIDIwMG0pICAgICAgICAgICAgICAgICAgICAgICB8IElOU0VFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgLS0+DQo8IS0tIHwgTGl0cywgZW1wbGFjZW1lbnRzIGRhbnMgbGVzIGNhbXBpbmdzIGV0IGNoYW1icmVzIGQnaMO0dGVscyAgICAgfCBGaWNoaWVyIGNvbW11bmFsIGR1IHRvdXJpc21lIChJTlNFRSkgICB8IC0tPg0KPCEtLSB8IEFycsOqdHMgZGUgdHJhbnNwb3J0IGVuIGNvbW11biAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgUG9pbnQgZCdBY2PDqHMgTmF0aW9uYWwgICAgICAgICAgICAgICAgIHwgLS0+DQo8IS0tIHwgQW3DqW5pdMOpcyA6IGNvbW1lcmNlcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU0lSRU5FICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAtLT4NCjwhLS0gfCBOb21icmUgZOKAmcOpbMOodmVzIChjb2xsw6hnZXMsIGx5Y8OpZXMsIEJUUykgKGRvbm7DqWVzIGNvbW11bmFsZXMpICB8IE1pbmlzdMOocmUgZGUgbOKAmUVkdWNhdGlvbiBuYXRpb25hbGUgICAgIHwgLS0+DQo8IS0tIHwgUGFzc2FnZSDDoCBuaXZlYXUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTTkNGICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0tPg0KPCEtLSB8IFpvbmVzIGFydGlmaWNpYWxpc8OpZXMgKGRvbm7DqWVzIHJlY29uc3RydWl0ZXMpICAgICAgICAgICAgICAgICB8IElHTiBCRCBUT1BPICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgLS0+DQo8IS0tIHwgUGVudGUgKHBvdXIgbGUgdsOpbG8pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBJR04gUkdFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0tPg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmRvbm5lZXMgPC0gZGF0YS5mcmFtZSgNCiAgIlRow6ltYXRpcXVlcyIgPSBjKCJEw6ltb2dyYXBoaWUiLA0KICAgICAgICAgICAgICAgICAgICAiVHJhbnNwb3J0IiwNCiAgICAgICAgICAgICAgICAgICAgIlRyYW5zcG9ydCIsDQogICAgICAgICAgICAgICAgICAgICLDiWNvbm9taWUgbG9jYWxlIiwNCiAgICAgICAgICAgICAgICAgICAgIsOJZHVjYXRpb24iLA0KICAgICAgICAgICAgICAgICAgICAiU8OpY3VyaXTDqSBldCBpbmZyYXN0cnVjdHVyZSIsDQogICAgICAgICAgICAgICAgICAgICJVcmJhbmlzbWUiLA0KICAgICAgICAgICAgICAgICAgICAiVG9wb2dyYXBoaWUiKSwNCiAgIlZhcmlhYmxlcyIgPSBjKCJOb21icmUgZOKAmWhhYml0YW50cyAoZG9ubsOpZXMgY2Fycm95w6llcyAyMDBtKSIsIA0KICAgICAgICAgICAgICAgICAgIkxvbmd1ZXVycyBkdSByw6lzZWF1IHJvdXRpZXIgY2Fycm9zc2FibGUiLA0KICAgICAgICAgICAgICAgICAgIkFycsOqdHMgZGUgdHJhbnNwb3J0IGVuIGNvbW11biIsIA0KICAgICAgICAgICAgICAgICAgIkFtw6luaXTDqXMgOiBjb21tZXJjZXMsIHNhbnTDqSwgbG9pc2lycywgc3BvcnRzLCByZXN0YXVyYXRpb24iLCANCiAgICAgICAgICAgICAgICAgICJOb21icmUgZOKAmcOpbMOodmVzIChjb2xsw6hnZXMsIGx5Y8OpZXMsIEJUUykgKGRvbm7DqWVzIGNvbW11bmFsZXMpIiwgDQogICAgICAgICAgICAgICAgICAiUGFzc2FnZSDDoCBuaXZlYXUiLCANCiAgICAgICAgICAgICAgICAgICJab25lcyBhcnRpZmljaWFsaXPDqWVzIiwNCiAgICAgICAgICAgICAgICAgICJQZW50ZSAocG91ciBsYSBtYXJjaGUgZXQgbGUgdsOpbG8pIiksDQogICJGb3Vybmlzc2V1ciIgPSBjKCJJTlNFRSIsIA0KICAgICAgICAgICAgICAgICAgICAiSUdOIEJEIFRPUE8iLA0KICAgICAgICAgICAgICAgICAgICAiUG9pbnQgZOKAmUFjY8OocyBOYXRpb25hbCAoZG9ubsOpZXMgR1RGUykiLCANCiAgICAgICAgICAgICAgICAgICAgIkJEIFNJUkVORSIsIA0KICAgICAgICAgICAgICAgICAgICAiTWluaXN0w6hyZSBkZSBs4oCZRWR1Y2F0aW9uIG5hdGlvbmFsZSIsIA0KICAgICAgICAgICAgICAgICAgICAiU05DRiIsIA0KICAgICAgICAgICAgICAgICAgICAiSUdOIEJEIFRPUE8iLA0KICAgICAgICAgICAgICAgICAgICAiSUdOIFJHRSBBTFRJIiksDQogICJJbnTDqXLDqnRzIiA9IGMoIkluZGlxdWUgbGEgZGVuc2l0w6kgZGUgcG9wdWxhdGlvbiBhdXRvdXIgZGVzIGdhcmVzLCByZWZsw6l0YW50IHBvdGVudGllbGxlbWVudCB1biBiZXNvaW4gw6lsZXbDqSBkZSBzZXJ2aWNlcyBkZSB0cmFuc3BvcnQuIiwgDQogICAgICAgICAgICAgICAgICJJbmRpcXVlIGwnYWNjZXNzaWJpbGl0w6kgZGUgbGEgZ2FyZSA6IHVuIHLDqXNlYXUgcm91dGllciBwbHVzIGRlbnNlIGV0IMOpdGVuZHUgcGV1dCBmYWNpbGl0ZXIgbCdhY2PDqHMiLA0KICAgICAgICAgICAgICAgICAiUGVybWV0IGRlIGNvbXByZW5kcmUgbCdpbnTDqWdyYXRpb24gZXQgbGEgY29ubmVjdGl2aXTDqSBkZSBsYSBnYXJlIGF1IHNlaW4gZHUgcsOpc2VhdSBkZSB0cmFuc3BvcnQgbG9jYWwgZXQgcsOpZ2lvbmFsLiIsDQogICAgICAgICAgICAgICAgICJEb25uZSB1bmUgaWTDqWUgZGUgbGEgdml0YWxpdMOpIMOpY29ub21pcXVlIGV0IGRlIGwnYWNjZXNzaWJpbGl0w6kgZGVzIHNlcnZpY2VzIGF1dG91ciBkZXMgZ2FyZXMuIiwNCiAgICAgICAgICAgICAgICAgIkluZGlxdWUgbGEgcHLDqXNlbmNlIGQnaW5zdGl0dXRpb25zIMOpZHVjYXRpdmVzLCBzdWdnw6lyYW50IGRlcyBmbHV4IHLDqWd1bGllcnMgZCfDqWzDqHZlcyBuw6ljZXNzaXRhbnQgZGVzIHNlcnZpY2VzIGRlIHRyYW5zcG9ydC4iLA0KICAgICAgICAgICAgICAgICAiU291bGlnbmUgbGVzIHBvaW50cyBwb3RlbnRpZWxzIGRlIGNvbmZsaXQgZW50cmUgbGUgdHJhbnNwb3J0IGZlcnJvdmlhaXJlIGV0IHJvdXRpZXIsIGltcG9ydGFudHMgcG91ciBsYSBwbGFuaWZpY2F0aW9uIGRlIGxhIHPDqWN1cml0w6kgZXQgbCdhbcOpbmFnZW1lbnQgdXJiYWluLiIsDQogICAgICAgICAgICAgICAgICJNb250cmUgbGVzIHBvc3NpYmlsaXTDqXMgZGUgZCdhbcOpbmFnZW1lbnQgZGVzIGVzcGFjZXMgZm9uY2llcnMuIiwNCiAgICAgICAgICAgICAgICAiSW1wb3J0YW50IHBvdXIgw6l2YWx1ZXIgbCdhY2Nlc3NpYmlsaXTDqSDDoCB2w6lsbyBkZXMgZ2FyZXMsIGluZmx1ZW7Dp2FudCBsYSBtb2JpbGl0w6kgZG91Y2UgZXQgbGVzIGNob2l4IGRlIHRyYW5zcG9ydCBtdWx0aW1vZGFsLiIpDQopDQpgYGANCg0KDQpgYGB7cn0NCmtuaXRyOjprYWJsZShkb25uZWVzKSAjIGNhcHRpb24gPSAiSW5mb3JtYXRpb25zIGV0IGxldXJzIGZvdXJuaXNzZXVycyINCmBgYA0KPGNlbnRlcj4NCipUYWJsZWF1IDIgOiBMaXN0ZSBkZXMgdmFyaWFibGVzIHPDqWxlY3Rpb25uw6llcyoNCjwvY2VudGVyPg0KPGJyPg0KPGJyPg0KPGJyPg0KDQoqKioNCg0KKipTb21tZSBkZXMgdmFyaWFibGVzIHBvdXIgbGEgY3LDqWF0aW9uIGQndW4gc2NvcmUqKg0KDQpgYGB7ciwgZXZhbCA9IEZ9DQphbGxfZGF0YSR0b3RhbF9zdW1fYWxsZWdlZSA8LQ0KICBhbGxfZGF0YSRzdW1fcG9wdWxhdGlvbl9jYXJyZWF1Kw0KICBhbGxfZGF0YSRsb25ndWV1cl9yb3V0ZSsNCiAgYWxsX2RhdGEkbm9tYnJlX2xvaXNpcnMrDQogIGFsbF9kYXRhJG5vbWJyZV9hcnJldHMrDQogIGFsbF9kYXRhJG5vbWJyZV9jb21tZXJjZXMrDQogIGFsbF9kYXRhJG5vbWJyZV9yZXN0YXVyYXRpb24rDQogIGFsbF9kYXRhJG5vbWJyZV9zcG9ydHMrDQogIGFsbF9kYXRhJG5vbWJyZV9zYW50ZSsNCiAgYWxsX2RhdGEkbm9tYnJlX2xvaXNpcnMrDQogIGFsbF9kYXRhJFpBKw0KICBhbGxfZGF0YSRwYXNzYWdlX25pdmVhdS0NCiAgYWxsX2RhdGEkcGVudGVfbW95ZW5uZQ0KDQpgYGANCg0KKipDYXJ0b2dyYXBoaWUgZHUgc2NvcmUgcG91ciBjaGFxdWUgcG9pbnQga2lsb23DqXRyaXF1ZSoqDQoNCjxjZW50ZXI+DQohW10oaW1hZ2VzL3BvaW50c19vcHRpbWF1eF9zdHBvbF9mb290LnBuZykgIA0KKkNhcnRlIDQgOiBDYXJ0b2dyYXBoaWUgZGUgbOKAmUV0b2lsZSBkZSBTYWludC1Qb2wgYXZlYyBsZXMgcG9pbnRzIHPDqWxlY3Rpb25uw6lzIOKAkyByw6lzdWx0YXRzIGR1IG1vZMOobGUgMTAgbWludXRlcyDDoCBwaWVkICoNCjwvY2VudGVyPg0KDQo8YnI+DQpQb3VyIHBsdXMgZGUgZMOpdGFpbHMgc3VyIGxhIGNhcnRvZ3JhcGhpZSB2b3VzIHBvdXZleiBjb25zdWx0ZXIgY2UgDQo8YSBocmVmPSJodHRwczovL2NhcnRvLXRsaS1vdGhldXJlYXV4LTk3ZWQ4YTljZGNiY2NhMjU3MTVlNTFkMGJjYTQwMjVmZDUzOGUwM2IxMC5naXRwYWdlcy5odW1hLW51bS5mci9zYWludC1wb2wuaHRtbCIgdGFyZ2V0PSJfYmxhbmsiPmxpZW4uDQo8L2E+DQoNCjxicj4NCjxicj4NCg0KIyMgSVNPQ0hST05FUw0KDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KcGFjbWFuOjpwX2xvYWQocjVyLCBzZiwgZGF0YS50YWJsZSwgZ2dwbG90MiwgdG1hcCwgamFuaXRvcikNCg0KIyBDaGFyZ2VtZW50IGRlcyBsaWduZXMgQ0VSRU1BIC0tLS0NCmxpZ25lc19DRVJFTUEgPC0gc2Y6OnN0X3JlYWQoJ0M6L1VzZXJzL290aGV1cmVhdXgvRG9jdW1lbnRzL09UL1JBSUxFTklVTS9CRERfVEVMTEkvR0VPRkVSL2xpZ25lcy1wYXItc3RhdHV0X3F1ZUVkQ19tb2RpZk9ULmdwa2cnKQ0KbGlnbmVzX0NFUkVNQV8yMTU0IDwtIHNmOjpzdF90cmFuc2Zvcm0obGlnbmVzX0NFUkVNQSwgMjE1NCkNCmxpZ25lX2ZpbHRlciA8LSBsaWduZXNfQ0VSRU1BXzIxNTQgJT4lICANCiAgZmlsdGVyKMOpdHVkZS5kZS5jYXMgPT0gJ8OpdG9pbGUgU3QgUG9sJykgJT4lIA0KICBzdF9idWZmZXIoMjAwMCkNCg0KaXNvY2hyb25lc19mb290X29zcm0gPC0gc2Y6OnN0X3JlYWQoJ3Byb2Nlc3NlZF9kYXRhL2lzb2Nocm9uZXNfZ2FyZXNfSERGX2Zvb3RfMTVtaW5fMjAyNDAyMDYuZ2VvanNvbicpDQppc29jaHJvbmVzX2Zvb3Rfb3NybSA8LSBzZjo6c3RfbWFrZV92YWxpZChpc29jaHJvbmVzX2Zvb3Rfb3NybSkgJT4lIA0KICBzdF90cmFuc2Zvcm0oMjE1NCkNCmlzb2Nocm9uZXNfZm9vdF9vc3JtIDwtIHN0X2ludGVyc2VjdGlvbihpc29jaHJvbmVzX2Zvb3Rfb3NybSxsaWduZV9maWx0ZXIpDQptYXB2aWV3KGlzb2Nocm9uZXNfZm9vdF9vc3JtKQ0KaXNvY2hyb25lc19mb290X2dlb2ZlciA8LSBzZjo6c3RfcmVhZCgnZGF0YS9pc29jaHJvbmVzX2dlb2Zlcl9wMTVfc3RfcG9sLmdlb2pzb24nKQ0KaXNvY2hyb25lc19mb290X2dlb2ZlciA8LSBzZjo6c3RfbWFrZV92YWxpZChpc29jaHJvbmVzX2Zvb3RfZ2VvZmVyKSAlPiUgDQogIHN0X2ludGVyc2VjdGlvbihsaWduZV9maWx0ZXIpDQpgYGANCg0KDQpgYGB7ciwgaW5jbHVkZSA9IEYsIGNhY2hlID0gVH0NCmdhcmVzX3N0X3BvbCA8LSBzZjo6c3RfcmVhZCgnZGF0YS9nYXJlc19zYWludHBvbF9ldGFwbGVzLmdwa2cnKQ0KZ2FyZXNfc3RfcG9sIDwtIHNmOjpzdF90cmFuc2Zvcm0oZ2FyZXNfc3RfcG9sLCA0MzI2KQ0KIyBFeHRyYWlyZSBsZXMgY29vcmRvbm7DqWVzIGV0IGNyw6llciBkZXMgY29sb25uZXMgJ2xhdCcgZXQgJ2xvbicNCmdhcmVzX3N0X3BvbCRsYXQgPC0gc3RfY29vcmRpbmF0ZXMoZ2FyZXNfc3RfcG9sKVssICJZIl0NCmdhcmVzX3N0X3BvbCRsb24gPC0gc3RfY29vcmRpbmF0ZXMoZ2FyZXNfc3RfcG9sKVssICJYIl0NCiMgQWpvdXRlciB1bmUgY29sb25uZSAnaWQnIMOgIHZvcyBwb2ludHMgZCdvcmlnaW5lDQpnYXJlc19zdF9wb2wkaWQgPC0gMTpucm93KGdhcmVzX3N0X3BvbCkNCg0Kb3B0aW9ucyhqYXZhLnBhcmFtZXRlcnMgPSAiLVhteDJHIikNCg0KIyBDb25maWd1cmVyIGxlIGRvc3NpZXIgb8O5IHNlIHRyb3V2ZSBsZXMgw6lsw6ltZW50cw0KcjVyX2NvcmUgPC0gc2V0dXBfcjUoZGF0YV9wYXRoID0gIkM6L1VzZXJzL290aGV1cmVhdXgvRG9jdW1lbnRzL09UL1JBSUxFTklVTS9CRERfVEVMTEkvT1NNX1BCRiIsIHZlcmJvc2UgPSBGQUxTRSkNCiMgZGF0YV9wYXRoIGVzdCBsZSBjaGVtaW4gdmVycyBsZSBkb3NzaWVyIGNvbnRlbmFudCB2b3MgZG9ubsOpZXMgZGUgcsOpc2VhdS4NCg0KIyByb3V0aW5nIGlucHV0cw0KbW9kZSA8LSBjKCJXQUxLIikNCm1heF90cmlwX2R1cmF0aW9uIDwtIDE1ICAgICAgIyBpbiBtaW51dGVzDQoNCiMgQ2FsY3VsIGRlcyBpc29jaHJvbmVzDQppc29jaHJvbmVzX2Zvb3RfcjVyIDwtIHI1cjo6aXNvY2hyb25lKHI1cl9jb3JlLA0KICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5zID0gZ2FyZXNfc3RfcG9sLA0KICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gbW9kZSwNCiAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlX3NpemUgPSAxLCAjIDEwMCUgZHUgcsOpc2VhdQ0KICAgICAgICAgICAgICAgICAgICAgICBtYXhfdHJpcF9kdXJhdGlvbiA9IG1heF90cmlwX2R1cmF0aW9uLA0KICAgICAgICAgICAgICAgICAgICAgICB3YWxrX3NwZWVkID0gNSwNCiAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3MgPSBGQUxTRSkNCmlzb2Nocm9uZXNfZm9vdF9yNXIgPC0gaXNvY2hyb25lc19mb290X3I1ciAlPiUgDQogIGZpbHRlcihpc29jaHJvbmUgPT0gMTUpDQppc29jaHJvbmVzX2Zvb3RfcjVyIDwtIHNmOjpzdF9tYWtlX3ZhbGlkKGlzb2Nocm9uZXNfZm9vdF9yNXIpICU+JSBzdF90cmFuc2Zvcm0oMjE1NCkNCmlzb2Nocm9uZXNfZm9vdF9yNXIgPC0gc3RfaW50ZXJzZWN0aW9uKGlzb2Nocm9uZXNfZm9vdF9yNXIsbGlnbmVfZmlsdGVyKQ0KDQpgYGANCg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmlzb2Nocm9uZXNfT1RQIDwtIHNmOjpzdF9yZWFkKCdwcm9jZXNzZWRfZGF0YS9pc29jaHJvbmVzX3N0X3BvbF9mb290XzE1bWluX09UUC5ncGtnJykgJT4lIHN0X3RyYW5zZm9ybSgyMTU0KSAlPiUgc3RfaW50ZXJzZWN0aW9uKGxpZ25lX2ZpbHRlcikNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmlzb2Nocm9uZXNfT1JTX1RPT0xTIDwtIHNmOjpzdF9yZWFkKCdwcm9jZXNzZWRfZGF0YS9pc29jaHJvbmVzX3N0X3BvbF9mb290XzE1bWluX1FHSVNfT1JTX1RPT0xTLmdwa2cnKSAgJT4lIHN0X3RyYW5zZm9ybSgyMTU0KSAlPiUgc3RfaW50ZXJzZWN0aW9uKGxpZ25lX2ZpbHRlcikNCmBgYA0KDQoNCmBgYHtyfQ0KdG1hcF9tb2RlKCd2aWV3JykNCnRtX2Jhc2VtYXAoYyhsZWFmbGV0Ojpwcm92aWRlcnMkRXNyaS5Xb3JsZFRvcG9NYXAsDQogICAgICAgICAgICAgbGVhZmxldDo6cHJvdmlkZXJzJE9wZW5TdHJlZXRNYXAsIA0KICAgICAgICAgICAgIGxlYWZsZXQ6OnByb3ZpZGVycyRFc3JpLldvcmxkSW1hZ2VyeWlkZXJzLCANCiAgICAgICAgICAgICBsZWFmbGV0Ojpwcm92aWRlcnMkR2VvcG9ydGFpbEZyYW5jZS5vcnRob3MpKSArIA0KICANCiAgdG1fc2hhcGUoaXNvY2hyb25lc19mb290X29zcm0pICsgdG1fZmlsbCgnI2U3NzE0OCcpICsgDQogIHRtX3NoYXBlKGlzb2Nocm9uZXNfZm9vdF9nZW9mZXIpICsgdG1fZmlsbCgnIzc1YTk5MycpICsgDQogIHRtX3NoYXBlKGlzb2Nocm9uZXNfZm9vdF9yNXIpICsgdG1fZmlsbCgnI2U1YjYzNicpICsgDQogIHRtX3NoYXBlKGlzb2Nocm9uZXNfT1RQKSArIHRtX2ZpbGwoJ2Nvcm5mbG93ZXJibHVlJykgKyANCiAgdG1fc2hhcGUoaXNvY2hyb25lc19PUlNfVE9PTFMpICsgdG1fZmlsbCgnYnJvd24yJykgKyANCiAgDQogIHRtX3NoYXBlKGdhcmVzX3N0X3BvbCkgKyB0bV9kb3RzKCkNCg0KYGBgDQoNCmBgYHtyfQ0Kc3VwX29zcm0gPC0gc3RfYXJlYShpc29jaHJvbmVzX2Zvb3Rfb3NybSkgDQpzdXBfZ2VvZmVyIDwtIHN0X2FyZWEoaXNvY2hyb25lc19mb290X2dlb2ZlcikgDQpzdXBfcjVyIDwtIHN0X2FyZWEoaXNvY2hyb25lc19mb290X3I1cikgDQpzdXBfT1RQIDwtIHN0X2FyZWEoaXNvY2hyb25lc19PVFApIA0Kc3VwX09SU1RPT0xTIDwtIHN0X2FyZWEoaXNvY2hyb25lc19PUlNfVE9PTFMpIA0KYGBgDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Kc3VwZXJmaWNpZXNfb3NybSA8LSBhcy5udW1lcmljKHN1cF9vc3JtKQ0Kc3VwZXJmaWNpZXNfZ2VvZmVyIDwtIGFzLm51bWVyaWMoc3VwX2dlb2ZlcikNCnN1cGVyZmljaWVzX3I1ciA8LSBhcy5udW1lcmljKHN1cF9yNXIpDQpzdXBlcmZpY2llc19vdHAgPC0gYXMubnVtZXJpYyhzdXBfT1RQKQ0Kc3VwZXJmaWNpZXNfb3JzX3Rvb2xzIDwtIGFzLm51bWVyaWMoc3VwX09SU1RPT0xTKQ0KDQpzdXBlcmZpY2llc19kZiA8LSBjYmluZChPU1JNID0gc3VwZXJmaWNpZXNfb3NybSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2VvRmVyID0gc3VwZXJmaWNpZXNfZ2VvZmVyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSNVIgPSBzdXBlcmZpY2llc19yNXIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9UUCA9IHN1cGVyZmljaWVzX290cCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1JTX1Rvb2xzID0gc3VwZXJmaWNpZXNfb3JzX3Rvb2xzKQ0KDQojIENhbGN1bCBkdSB0b3RhbCBkZXMgc3VwZXJmaWNpZXMgcG91ciBjaGFxdWUgc2VydmljZQ0KdG90YWxfc3VwZXJmaWNpZXMgPC0gY29sU3VtcyhzdXBlcmZpY2llc19kZiwgbmEucm0gPSBUUlVFKQ0KDQojIEFqb3V0ZXIgbGEgbGlnbmUgZHUgdG90YWwgYXUgZGF0YSBmcmFtZQ0KdG90YWxfZGYgPC0gZGF0YS5mcmFtZShzdXBlcmZpY2llc19kZikNCnRvdGFsX2RmX3N1cCA8LSByYmluZCh0b3RhbF9kZiwgdG90YWxfc3VwZXJmaWNpZXMpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KIyBBZmZpY2hhZ2UgZHUgdGFibGVhdSBmaW5hbA0KcHJpbnQodG90YWxfZGZfc3VwKQ0KYGBgDQoNCg0KIyMgQnVmZmVyIHZzLiBJc28NCg0KYGBge3IsIG91dC53aWR0aD0nMTAwJSd9DQojIFBhY2thZ2VzIC0tLS0NCnBhY21hbjo6cF9sb2FkKHNmLCBtYXB2aWV3LCB0bWFwLCBkcGx5ciwgR0dhbGx5KQ0KDQojIENoYXJnZW1lbnQgZGUgbGEgY291Y2hlIGRlcyByw6lnaW9ucyBkZSBsYSBGcmFuY2UgbcOpdHJvcG9saXRhaW5lDQpyZWdpb25zX0ZSXzIxNTQgPC0gc2Y6OnN0X3JlYWQoIkM6L1VzZXJzL290aGV1cmVhdXgvRG9jdW1lbnRzL09UL0RFQ09VUEFHRVNfRlIvUkVHSU9OLnNocCIpDQoNCiMgRmlsdGVyIHN1ciBsYSByw6lnaW9uIGRlcyBIYXV0cy1kZS1GcmFuY2UNCmhhdXRzX2RlX2ZyYW5jZSA8LSByZWdpb25zX0ZSXzIxNTQgJT4lICAgZmlsdGVyKElOU0VFX1JFRyA9PSAzMikNCnpvbmVfZXR1ZGUgPC0gaGF1dHNfZGVfZnJhbmNlDQoNCiMgQ2hhcmdlbWVudCBkZXMgZ2FyZXMNCmdhcmVzIDwtIHNmOjpzdF9yZWFkKCJDOi9Vc2Vycy9vdGhldXJlYXV4L0RvY3VtZW50cy9PVC9SQUlMRU5JVU0vQkREX1RFTExJL0dFT0ZFUi9nYXJlc18yMTU0Lmdwa2ciKQ0KZ2FyZXNfc2VsZWN0IDwtIGdhcmVzICU+JSANCiAgc2VsZWN0KG5vbV9nYXJlLCB2b3lfMjAyMikNCg0KIyBEw6ljb3VwYWdlIGdhcmVzIEhERg0KZ2FyZXNfSERSIDwtIHNmOjpzdF9pbnRlcnNlY3Rpb24oZ2FyZXNfc2VsZWN0LCB6b25lX2V0dWRlKQ0KbWFwdmlldyhnYXJlc19IRFIpDQoNCiMgQ3LDqWF0aW9uIGRlcyBidWZmZXJzDQpidWZmZXJzX2dhcmVzX0hEUiA8LSBzdF9idWZmZXIoZ2FyZXNfSERSLCAxMDAwKQ0KYnVmZmVyc19nYXJlc19IRFIkc3VwZXJmaWNpZSA8LSBzdF9hcmVhKGJ1ZmZlcnNfZ2FyZXNfSERSKQ0KDQojIENyw6lhdGlvbiBkZXMgaXNvY2hvbmVzDQphbGxfaXNvY2hyb25lcyA8LSBzZjo6c3RfcmVhZCgnQzovVXNlcnMvb3RoZXVyZWF1eC9Eb2N1bWVudHMvT1QvNlQvUi9kYXRhYmFzZV9zZi9wcm9jZXNzZWRfZGF0YS9pc29jaHJvbmVzX2dhcmVzX0hERl9mb290XzE1bWluXzIwMjQwMjA2Lmdlb2pzb24nKQ0KYWxsX2lzb2Nocm9uZXMgPC0gc3RfdHJhbnNmb3JtKGFsbF9pc29jaHJvbmVzLCAyMTU0KQ0KYWxsX2lzb2Nocm9uZXMkc3VwZXJmaWNpZSA8LSBzdF9hcmVhKGFsbF9pc29jaHJvbmVzKQ0KDQojIENhcnRvIGRlcyBidWZmZXJzIGV0IGRlcyBpc28NCm1hcHZpZXcoYnVmZmVyc19nYXJlc19IRFIpICsgbWFwdmlldyhhbGxfaXNvY2hyb25lcykNCg0KIyBEYXRhZnJhbWUgZGVzIHN1cGVyZmljaWVzDQpkdCA8LSBkYXRhLmZyYW1lKA0KICBidWZmZXJzX2dhcmVzX0hEUiRzdXBlcmZpY2llLA0KICBhbGxfaXNvY2hyb25lcyRzdXBlcmZpY2llDQopDQoNCmR0JHJhcHBvcnQgPC1hbGxfaXNvY2hyb25lcyRzdXBlcmZpY2llIC8gYnVmZmVyc19nYXJlc19IRFIkc3VwZXJmaWNpZSoxMDANCg0KDQphbGxfaXNvY2hyb25lcyRyYXBwb3J0IDwtIGR0JHJhcHBvcnQNCmFsbF9pc29jaHJvbmVzJHJhcHBvcnQgPC0gYXMubnVtZXJpYyhhbGxfaXNvY2hyb25lcyRyYXBwb3J0KQ0Kc3RyKGFsbF9pc29jaHJvbmVzKQ0KYWxsX2lzb2Nocm9uZXNfZmlsdGVyIDwtIGFsbF9pc29jaHJvbmVzICU+JSANCiAgZmlsdGVyKHJhcHBvcnQgPCA0NSkNCm1hcHZpZXcoYWxsX2lzb2Nocm9uZXNfZmlsdGVyKSArIG1hcHZpZXcoYnVmZmVyc19nYXJlc19IRFIpDQpgYGANCg0K