Folium - Mapa Base


# Crear Mapa Base - Open Street Map - HTML (Save)

mapa_base = fl.Map()

mapa_base.save("mapa_folium_001.html")

mapa_base
Make this Notebook Trusted to load map: File -> Trust Notebook

Latitud - Longitud


# Latitud - Longitud - Una sola ubicación

# Palacio Nacional de La República Dominicana 18.47559892878191, -69.89774247032956

palacio_nacional = fl.Map(location=[18.47559892878191, -69.89774247032956],zoom_start=16)

palacio_nacional.save("mapa_folium_002.html")

palacio_nacional
Make this Notebook Trusted to load map: File -> Trust Notebook

MiniMap - Tiles - Full Screen


# MiniMap  - Tiles - Full Screen

# tiles: stamenterrain - stamentoner - stamenwatercolor - cartodbpositron - OpenStreetMap

# Palacio Nacional de La República Dominicana 18.47559892878191, -69.89774247032956

from folium import plugins

palacio_nacional = fl.Map(location=[18.47559892878191, -69.89774247032956],zoom_start=16,tiles="stamenterrain")

img_001 = "python_logo.png"


fl.Marker(location=[18.47559892878191, -69.89774247032956],
          icon=fl.Icon(color="darkblue",icon="fire")).add_to(palacio_nacional)
fl.Circle(location=[18.47559892878191, -69.89774247032956],
          color="orange",fill_color="red",weight=4,raidus=40,fill_opacity=0.4).add_to(palacio_nacional)
FloatImage(img_001,left=90,bottom=90).add_to(palacio_nacional)
minimap = MiniMap(toggle_display=True,position="bottomleft",tile_layer="stamenterrain")

palacio_nacional.add_child(minimap)
Make this Notebook Trusted to load map: File -> Trust Notebook
plugins.Fullscreen(position="topleft").add_to(palacio_nacional)
draw = plugins.Draw(export=True)

palacio_nacional.save("mapa_folium_004.html")

palacio_nacional
Make this Notebook Trusted to load map: File -> Trust Notebook

Menú Tiles


# Menú Tiles

# tiles: stamenterrain - stamentoner - stamenwatercolor - cartodbpositron - OpenStreetMap

# Palacio Nacional de La República Dominicana 18.47559892878191, -69.89774247032956

palacio_nacional = fl.Map(location=[18.47559892878191, -69.89774247032956],zoom_start=16)

img_001 = "python_logo.png"


fl.Marker(location=[18.47559892878191, -69.89774247032956],
          icon=fl.Icon(color="darkblue",icon="fire")).add_to(palacio_nacional)
fl.Circle(location=[18.47559892878191, -69.89774247032956],
          color="orange",fill_color="red",weight=4,raidus=40,fill_opacity=0.4).add_to(palacio_nacional)
FloatImage(img_001,left=90,bottom=90).add_to(palacio_nacional)
plugins.Fullscreen(position="topleft").add_to(palacio_nacional)
draw = plugins.Draw(export=True)


fl.TileLayer("stamenterrain").add_to(palacio_nacional)
fl.TileLayer("stamentoner").add_to(palacio_nacional)
fl.TileLayer("stamenwatercolor").add_to(palacio_nacional)
fl.TileLayer("cartodbpositron").add_to(palacio_nacional)
fl.TileLayer("OpenStreetMap").add_to(palacio_nacional)
fl.LayerControl(position="bottomright").add_to(palacio_nacional)
palacio_nacional.save("mapa_folium_005.html")

palacio_nacional
Make this Notebook Trusted to load map: File -> Trust Notebook

Múltiples Marcadores - Caso I


# Multiples Marcadores - Caso I

parque_independencia_alrededores = fl.Map(location=[18.471279222825007, -69.89206691553046],zoom_start=16)


img_001 = "python_logo.png"

text_001="<b>Iglesia Nuestra Señora de La Merced</b>"

text_002="<b>Convento Regina Angelorum</b>"

text_003="<b>Puerta de La Misericordia</b>"

fl.Marker(location=[18.47416921486365, -69.88824745014279],
          icon=fl.Icon(color="darkblue",icon="ok-sign"),popup=fl.Popup(text_001,max_width=250)).add_to(parque_independencia_alrededores)
fl.Marker(location=[18.471116404923126, -69.8871531089362],
          icon=fl.Icon(color="orange",icon="ok-sign"),popup=fl.Popup(text_002,max_width=200)).add_to(parque_independencia_alrededores)
fl.Marker(location=[18.468775880481004, -69.89011426748678],
          icon=fl.Icon(color="blue",icon="ok-sign"),popup=fl.Popup(text_003,max_width=200)).add_to(parque_independencia_alrededores)
FloatImage(img_001,left=90,bottom=90).add_to(parque_independencia_alrededores)
parque_independencia_alrededores.save("mapa_folium_007.html")

parque_independencia_alrededores
Make this Notebook Trusted to load map: File -> Trust Notebook

Múltiples Marcadores - Caso II


# Multiples Marcadores - Data Frame - Caso II

parque_independencia_alrededores = fl.Map(location=[18.471279222825007, -69.89206691553046],zoom_start=16)


img_001 = "python_logo.png"

centro_dataframe = pd.DataFrame({'lugar':['Iglesia Nuestra Señora de La Merced','Convento Regina Angelorum','Puerta de la Misericordia'],
                                'latitud':[18.47416921486365,18.471116404923126,18.468775880481004],
                                'longitud':[-69.88824745014279,-69.8871531089362,-69.89011426748678],
                                'simbolo':['ok-sign','ok-sign','ok-sign'],
                                'color':['dark-blue','orange','blue']})

for i in centro_dataframe.itertuples():
    fl.Marker(location=[i.latitud,i.longitud],
              icon=fl.Icon(color=i.color,icon=i.simbolo),popup=fl.Popup(i.lugar,max_width=200)).add_to(parque_independencia_alrededores)
FloatImage(img_001,left=90,bottom=90).add_to(parque_independencia_alrededores)
parque_independencia_alrededores.save("mapa_folium_008.html")

parque_independencia_alrededores
Make this Notebook Trusted to load map: File -> Trust Notebook

Mútliples Marcadores - Caso III


# Multiples Marcadores - Pandas (archivo.txt) - Caso III

parque_independencia_alrededores = fl.Map(location=[18.471279222825007, -69.89206691553046],zoom_start=16)


img_001 = "python_logo.png"


FloatImage(img_001,left=90,bottom=90).add_to(parque_independencia_alrededores)
puntos = pd.read_csv("puntos_dom.txt")

puntos
puntos_frame = pd.DataFrame(puntos)

for i in puntos_frame.itertuples():
    fl.Marker(location=[i.latitud,i.longitud],
              icon=fl.Icon(color=i.color,icon=i.simbolo),popup=fl.Popup(i.lugar,max_width=200)).add_to(parque_independencia_alrededores)
    
parque_independencia_alrededores    
Make this Notebook Trusted to load map: File -> Trust Notebook

Tutorial Folium - YouTube

# Incrustamos al documento un tutorial de YouTube haciendo uso de la librería vembedr

library(vembedr)

embed_url("https://www.youtube.com/watch?v=xl_OFx7BgtA") %>% 
   use_align("center") %>%
   use_rounded(10)
LS0tDQp0aXRsZTogIk1hcGFzIEludGVyYWN0aXZvcyBlbiBQeXRob24iDQphdXRob3I6ICJSZW56byBDw6FjZXJlcyBSb3NzaSINCmRhdGU6ICIyMDIyLzAyLzI1Ig0Kc3VidGl0bGU6IEZvbGl1bSAtIFJNYXJrZG93bg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIHRoZW1lOiBkYXJrbHkNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgc2VsZl9jb250YWluZWQ6IG5vDQotLS0NCg0KPCEtLSBDcmVhbmRvIE1hcGFzIEludGVyYWN0aXZvcyBlbiBQeXRob24gdXNhbmRvIGxhIGxpYnJlcsOtYSBGb2xpdW0geSBzdXMgcGx1Z2lucyBNaW5pTWFwIC0gRmxvYXRJbWFnZSAtLT4NCg0KYGBge3Igc2V0dXAsaW5jbHVkZT1GQUxTRX0NCg0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQoNCmxpYnJhcnkocmV0aWN1bGF0ZSkNCg0KdXNlX3B5dGhvbigiQzovVXNlcnMvcmVuem9yb3NzaXYvQXBwRGF0YS9Mb2NhbC9Qcm9ncmFtcy9QeXRob24vUHl0aG9uMzEwL3B5dGhvbi5leGUiKQ0KYGBgDQoNCmBgYHtweXRob24gZm9saXVtXzAxLGluY2x1ZGU9RkFMU0UscmVzdWx0cz0naGlkZSd9DQoNCiMgQ2FyZ2FyIGxpYnJlcsOtYXMgRm9saXVtIC0gUGFuZGFzIC0gcGx1Z2lucyAoY29tcGxlbWVudG9zIGRlIEZvbGl1bSkNCg0KIyBMYSBDb25maWd1cmFjacOzbiBkZSBlc3RlIHBlcm1pdGUgZWplY3V0YXIgbGFzIGxpYnJlcsOtYXMgcGVybyBubyBzZSBtdWVzdHJhbiBlbiBlbCBkb2N1bWVudG8gZmluYWwNCg0KaW1wb3J0IGZvbGl1bSBhcyBmbA0KDQppbXBvcnQgcGFuZGFzIGFzIHBkDQoNCmZyb20gZm9saXVtIGltcG9ydCBwbHVnaW5zDQoNCmZyb20gZm9saXVtLnBsdWdpbnMgaW1wb3J0IE1pbmlNYXANCg0KZnJvbSBmb2xpdW0ucGx1Z2lucyBpbXBvcnQgRmxvYXRJbWFnZQ0KYGBgDQoNCiMjIEZvbGl1bSAtIE1hcGEgQmFzZQ0KDQpgYGB7cHl0aG9uIGZvbGl1bV8wMixyZXN1bHRzPSdoaWRlJ30NCg0KIyBDcmVhciBNYXBhIEJhc2UgLSBPcGVuIFN0cmVldCBNYXAgLSBIVE1MIChTYXZlKQ0KDQptYXBhX2Jhc2UgPSBmbC5NYXAoKQ0KDQptYXBhX2Jhc2Uuc2F2ZSgibWFwYV9mb2xpdW1fMDAxLmh0bWwiKQ0KDQptYXBhX2Jhc2UNCmBgYA0KDQojIyBMYXRpdHVkIC0gTG9uZ2l0dWQgDQoNCmBgYHtweXRob24gZm9saXVtXzAzLHJlc3VsdHM9J2hpZGUnfQ0KDQojIExhdGl0dWQgLSBMb25naXR1ZCAtIFVuYSBzb2xhIHViaWNhY2nDs24NCg0KIyBQYWxhY2lvIE5hY2lvbmFsIGRlIExhIFJlcMO6YmxpY2EgRG9taW5pY2FuYSAxOC40NzU1OTg5Mjg3ODE5MSwgLTY5Ljg5Nzc0MjQ3MDMyOTU2DQoNCnBhbGFjaW9fbmFjaW9uYWwgPSBmbC5NYXAobG9jYXRpb249WzE4LjQ3NTU5ODkyODc4MTkxLCAtNjkuODk3NzQyNDcwMzI5NTZdLHpvb21fc3RhcnQ9MTYpDQoNCnBhbGFjaW9fbmFjaW9uYWwuc2F2ZSgibWFwYV9mb2xpdW1fMDAyLmh0bWwiKQ0KDQpwYWxhY2lvX25hY2lvbmFsDQpgYGANCg0KDQojIyBNYXJjYWRvciAtIEPDrXJjdWxvIC0gTG9nbw0KDQpgYGB7cHl0aG9uIGZvbGl1bV8wNCxyZXN1bHRzPSdoaWRlJ30NCg0KIyBNYXJjYWRvciAtIEPDrXJjdWxvIC0gbG9nbw0KDQojIFBhbGFjaW8gTmFjaW9uYWwgZGUgTGEgUmVww7pibGljYSBEb21pbmljYW5hIDE4LjQ3NTU5ODkyODc4MTkxLCAtNjkuODk3NzQyNDcwMzI5NTYNCg0KcGFsYWNpb19uYWNpb25hbCA9IGZsLk1hcChsb2NhdGlvbj1bMTguNDc1NTk4OTI4NzgxOTEsIC02OS44OTc3NDI0NzAzMjk1Nl0sem9vbV9zdGFydD0xNikNCg0KaW1nXzAwMSA9ICJweXRob25fbG9nby5wbmciDQoNCg0KZmwuTWFya2VyKGxvY2F0aW9uPVsxOC40NzU1OTg5Mjg3ODE5MSwgLTY5Ljg5Nzc0MjQ3MDMyOTU2XSwNCiAgICAgICAgICBpY29uPWZsLkljb24oY29sb3I9ImRhcmtibHVlIixpY29uPSJmaXJlIikpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpmbC5DaXJjbGUobG9jYXRpb249WzE4LjQ3NTU5ODkyODc4MTkxLCAtNjkuODk3NzQyNDcwMzI5NTZdLA0KICAgICAgICAgIGNvbG9yPSJvcmFuZ2UiLGZpbGxfY29sb3I9InJlZCIsd2VpZ2h0PTQscmFpZHVzPTQwLGZpbGxfb3BhY2l0eT0wLjQpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQoNCkZsb2F0SW1hZ2UoaW1nXzAwMSxsZWZ0PTkwLGJvdHRvbT05MCkuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCg0KcGFsYWNpb19uYWNpb25hbC5zYXZlKCJtYXBhX2ZvbGl1bV8wMDMuaHRtbCIpDQoNCnBhbGFjaW9fbmFjaW9uYWwNCmBgYA0KDQojIyBNaW5pTWFwIC0gVGlsZXMgLSBGdWxsIFNjcmVlbg0KDQpgYGB7cHl0aG9uIGZvbGl1bV8wNSxyZXN1bHRzPSdoaWRlJ30NCg0KIyBNaW5pTWFwICAtIFRpbGVzIC0gRnVsbCBTY3JlZW4NCg0KIyB0aWxlczogc3RhbWVudGVycmFpbiAtIHN0YW1lbnRvbmVyIC0gc3RhbWVud2F0ZXJjb2xvciAtIGNhcnRvZGJwb3NpdHJvbiAtIE9wZW5TdHJlZXRNYXANCg0KIyBQYWxhY2lvIE5hY2lvbmFsIGRlIExhIFJlcMO6YmxpY2EgRG9taW5pY2FuYSAxOC40NzU1OTg5Mjg3ODE5MSwgLTY5Ljg5Nzc0MjQ3MDMyOTU2DQoNCmZyb20gZm9saXVtIGltcG9ydCBwbHVnaW5zDQoNCnBhbGFjaW9fbmFjaW9uYWwgPSBmbC5NYXAobG9jYXRpb249WzE4LjQ3NTU5ODkyODc4MTkxLCAtNjkuODk3NzQyNDcwMzI5NTZdLHpvb21fc3RhcnQ9MTYsdGlsZXM9InN0YW1lbnRlcnJhaW4iKQ0KDQppbWdfMDAxID0gInB5dGhvbl9sb2dvLnBuZyINCg0KDQpmbC5NYXJrZXIobG9jYXRpb249WzE4LjQ3NTU5ODkyODc4MTkxLCAtNjkuODk3NzQyNDcwMzI5NTZdLA0KICAgICAgICAgIGljb249ZmwuSWNvbihjb2xvcj0iZGFya2JsdWUiLGljb249ImZpcmUiKSkuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCmZsLkNpcmNsZShsb2NhdGlvbj1bMTguNDc1NTk4OTI4NzgxOTEsIC02OS44OTc3NDI0NzAzMjk1Nl0sDQogICAgICAgICAgY29sb3I9Im9yYW5nZSIsZmlsbF9jb2xvcj0icmVkIix3ZWlnaHQ9NCxyYWlkdXM9NDAsZmlsbF9vcGFjaXR5PTAuNCkuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCg0KRmxvYXRJbWFnZShpbWdfMDAxLGxlZnQ9OTAsYm90dG9tPTkwKS5hZGRfdG8ocGFsYWNpb19uYWNpb25hbCkNCg0KbWluaW1hcCA9IE1pbmlNYXAodG9nZ2xlX2Rpc3BsYXk9VHJ1ZSxwb3NpdGlvbj0iYm90dG9tbGVmdCIsdGlsZV9sYXllcj0ic3RhbWVudGVycmFpbiIpDQoNCnBhbGFjaW9fbmFjaW9uYWwuYWRkX2NoaWxkKG1pbmltYXApDQoNCnBsdWdpbnMuRnVsbHNjcmVlbihwb3NpdGlvbj0idG9wbGVmdCIpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpkcmF3ID0gcGx1Z2lucy5EcmF3KGV4cG9ydD1UcnVlKQ0KDQpwYWxhY2lvX25hY2lvbmFsLnNhdmUoIm1hcGFfZm9saXVtXzAwNC5odG1sIikNCg0KcGFsYWNpb19uYWNpb25hbA0KYGBgDQoNCg0KIyMgTWVuw7ogVGlsZXMNCg0KYGBge3B5dGhvbiBmb2xpdW1fMDYscmVzdWx0cz0naGlkZSd9DQoNCiMgTWVuw7ogVGlsZXMNCg0KIyB0aWxlczogc3RhbWVudGVycmFpbiAtIHN0YW1lbnRvbmVyIC0gc3RhbWVud2F0ZXJjb2xvciAtIGNhcnRvZGJwb3NpdHJvbiAtIE9wZW5TdHJlZXRNYXANCg0KIyBQYWxhY2lvIE5hY2lvbmFsIGRlIExhIFJlcMO6YmxpY2EgRG9taW5pY2FuYSAxOC40NzU1OTg5Mjg3ODE5MSwgLTY5Ljg5Nzc0MjQ3MDMyOTU2DQoNCnBhbGFjaW9fbmFjaW9uYWwgPSBmbC5NYXAobG9jYXRpb249WzE4LjQ3NTU5ODkyODc4MTkxLCAtNjkuODk3NzQyNDcwMzI5NTZdLHpvb21fc3RhcnQ9MTYpDQoNCmltZ18wMDEgPSAicHl0aG9uX2xvZ28ucG5nIg0KDQoNCmZsLk1hcmtlcihsb2NhdGlvbj1bMTguNDc1NTk4OTI4NzgxOTEsIC02OS44OTc3NDI0NzAzMjk1Nl0sDQogICAgICAgICAgaWNvbj1mbC5JY29uKGNvbG9yPSJkYXJrYmx1ZSIsaWNvbj0iZmlyZSIpKS5hZGRfdG8ocGFsYWNpb19uYWNpb25hbCkNCg0KZmwuQ2lyY2xlKGxvY2F0aW9uPVsxOC40NzU1OTg5Mjg3ODE5MSwgLTY5Ljg5Nzc0MjQ3MDMyOTU2XSwNCiAgICAgICAgICBjb2xvcj0ib3JhbmdlIixmaWxsX2NvbG9yPSJyZWQiLHdlaWdodD00LHJhaWR1cz00MCxmaWxsX29wYWNpdHk9MC40KS5hZGRfdG8ocGFsYWNpb19uYWNpb25hbCkNCg0KDQpGbG9hdEltYWdlKGltZ18wMDEsbGVmdD05MCxib3R0b209OTApLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQoNCnBsdWdpbnMuRnVsbHNjcmVlbihwb3NpdGlvbj0idG9wbGVmdCIpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpkcmF3ID0gcGx1Z2lucy5EcmF3KGV4cG9ydD1UcnVlKQ0KDQoNCmZsLlRpbGVMYXllcigic3RhbWVudGVycmFpbiIpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpmbC5UaWxlTGF5ZXIoInN0YW1lbnRvbmVyIikuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCmZsLlRpbGVMYXllcigic3RhbWVud2F0ZXJjb2xvciIpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpmbC5UaWxlTGF5ZXIoImNhcnRvZGJwb3NpdHJvbiIpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpmbC5UaWxlTGF5ZXIoIk9wZW5TdHJlZXRNYXAiKS5hZGRfdG8ocGFsYWNpb19uYWNpb25hbCkNCg0KZmwuTGF5ZXJDb250cm9sKHBvc2l0aW9uPSJib3R0b21yaWdodCIpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpwYWxhY2lvX25hY2lvbmFsLnNhdmUoIm1hcGFfZm9saXVtXzAwNS5odG1sIikNCg0KcGFsYWNpb19uYWNpb25hbA0KYGBgDQoNCg0KIyMgUG9wdXAgc2V0dXAgLSBUb29sdGlwIA0KDQpgYGB7cHl0aG9uIGZvbGl1bV8wNyxyZXN1bHRzPSdoaWRlJ30NCg0KIyBQb3B1cCAtIFRvb2x0aXAgLSBQb3B1cCBDb25maWd1cmFjacOzbg0KDQojIFBhbGFjaW8gTmFjaW9uYWwgZGUgTGEgUmVww7pibGljYSBEb21pbmljYW5hIDE4LjQ3NTU5ODkyODc4MTkxLCAtNjkuODk3NzQyNDcwMzI5NTYNCg0KcGFsYWNpb19uYWNpb25hbCA9IGZsLk1hcChsb2NhdGlvbj1bMTguNDc1NTk4OTI4NzgxOTEsIC02OS44OTc3NDI0NzAzMjk1Nl0sem9vbV9zdGFydD0xNikNCg0KDQpodG1sPScnJw0KPGI+THVnYXI6UGFsYWNpbyBOYWNpb25hbCBSLkRvbTwvYj48YnI+DQo8Yj5MYXRpdHVkOjE4LjQ3NTU5ODkyODc4MTkxPC9iPjxicj4NCjxiPkxvbmdpdHVkOi02OS44OTc3NDI0NzAzMjk1NjwvYj48YnI+DQo8Yj5XZWI6PGEgaHJlZj0naHR0cHM6Ly9iaXQubHkvM2hnQ3lnMycgdGFyZ2V0PSdfYmxhbmsnPlByZXNpZGVuY2lhIFIuRG9tPC9hPg0KPGJyPjxicj4NCjxjZW50ZXI+PGltZyBzcmM9J2h0dHBzOi8vYml0Lmx5LzM2dTVXTkInIHdpZHRoPTIwMCBoZWlnaHQ9MTAwPjwvY2VudGVyPg0KJycnDQoNCmlmcmFtZSA9IGZsLklGcmFtZShodG1sPWh0bWwsd2lkdGg9MzAwLGhlaWdodD0yNTApDQoNCmltZ18wMDEgPSAicHl0aG9uX2xvZ28ucG5nIg0KDQoNCmZsLk1hcmtlcihsb2NhdGlvbj1bMTguNDc1NTk4OTI4NzgxOTEsIC02OS44OTc3NDI0NzAzMjk1Nl0sDQogICAgICAgICAgaWNvbj1mbC5JY29uKGNvbG9yPSJkYXJrYmx1ZSIsaWNvbj0iZmlyZSIpLHBvcHVwPWZsLlBvcHVwKGlmcmFtZSkpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpmbC5DaXJjbGUobG9jYXRpb249WzE4LjQ3NTU5ODkyODc4MTkxLCAtNjkuODk3NzQyNDcwMzI5NTZdLA0KICAgICAgICAgIGNvbG9yPSJvcmFuZ2UiLGZpbGxfY29sb3I9InJlZCIsd2VpZ2h0PTQscmFpZHVzPTQwLGZpbGxfb3BhY2l0eT0wLjQsdG9vbHRpcD0iU2VkZSBkZSBHb2JpZXJubyIpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQoNCkZsb2F0SW1hZ2UoaW1nXzAwMSxsZWZ0PTkwLGJvdHRvbT05MCkuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCg0KcGx1Z2lucy5GdWxsc2NyZWVuKHBvc2l0aW9uPSJ0b3BsZWZ0IikuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCmRyYXcgPSBwbHVnaW5zLkRyYXcoZXhwb3J0PVRydWUpDQoNCg0KZmwuVGlsZUxheWVyKCJzdGFtZW50ZXJyYWluIikuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCmZsLlRpbGVMYXllcigic3RhbWVudG9uZXIiKS5hZGRfdG8ocGFsYWNpb19uYWNpb25hbCkNCg0KZmwuVGlsZUxheWVyKCJzdGFtZW53YXRlcmNvbG9yIikuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCmZsLlRpbGVMYXllcigiY2FydG9kYnBvc2l0cm9uIikuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCmZsLlRpbGVMYXllcigiT3BlblN0cmVldE1hcCIpLmFkZF90byhwYWxhY2lvX25hY2lvbmFsKQ0KDQpmbC5MYXllckNvbnRyb2wocG9zaXRpb249ImJvdHRvbXJpZ2h0IikuYWRkX3RvKHBhbGFjaW9fbmFjaW9uYWwpDQoNCnBhbGFjaW9fbmFjaW9uYWwuc2F2ZSgibWFwYV9mb2xpdW1fMDA2Lmh0bWwiKQ0KDQpwYWxhY2lvX25hY2lvbmFsDQpgYGANCg0KDQojIyBNw7psdGlwbGVzIE1hcmNhZG9yZXMgLSBDYXNvIEkNCg0KYGBge3B5dGhvbiBmb2xpdW1fMDgscmVzdWx0cz0naGlkZSd9DQoNCiMgTXVsdGlwbGVzIE1hcmNhZG9yZXMgLSBDYXNvIEkNCg0KcGFycXVlX2luZGVwZW5kZW5jaWFfYWxyZWRlZG9yZXMgPSBmbC5NYXAobG9jYXRpb249WzE4LjQ3MTI3OTIyMjgyNTAwNywgLTY5Ljg5MjA2NjkxNTUzMDQ2XSx6b29tX3N0YXJ0PTE2KQ0KDQoNCmltZ18wMDEgPSAicHl0aG9uX2xvZ28ucG5nIg0KDQp0ZXh0XzAwMT0iPGI+SWdsZXNpYSBOdWVzdHJhIFNlw7FvcmEgZGUgTGEgTWVyY2VkPC9iPiINCg0KdGV4dF8wMDI9IjxiPkNvbnZlbnRvIFJlZ2luYSBBbmdlbG9ydW08L2I+Ig0KDQp0ZXh0XzAwMz0iPGI+UHVlcnRhIGRlIExhIE1pc2VyaWNvcmRpYTwvYj4iDQoNCmZsLk1hcmtlcihsb2NhdGlvbj1bMTguNDc0MTY5MjE0ODYzNjUsIC02OS44ODgyNDc0NTAxNDI3OV0sDQogICAgICAgICAgaWNvbj1mbC5JY29uKGNvbG9yPSJkYXJrYmx1ZSIsaWNvbj0ib2stc2lnbiIpLHBvcHVwPWZsLlBvcHVwKHRleHRfMDAxLG1heF93aWR0aD0yNTApKS5hZGRfdG8ocGFycXVlX2luZGVwZW5kZW5jaWFfYWxyZWRlZG9yZXMpDQoNCmZsLk1hcmtlcihsb2NhdGlvbj1bMTguNDcxMTE2NDA0OTIzMTI2LCAtNjkuODg3MTUzMTA4OTM2Ml0sDQogICAgICAgICAgaWNvbj1mbC5JY29uKGNvbG9yPSJvcmFuZ2UiLGljb249Im9rLXNpZ24iKSxwb3B1cD1mbC5Qb3B1cCh0ZXh0XzAwMixtYXhfd2lkdGg9MjAwKSkuYWRkX3RvKHBhcnF1ZV9pbmRlcGVuZGVuY2lhX2FscmVkZWRvcmVzKQ0KDQpmbC5NYXJrZXIobG9jYXRpb249WzE4LjQ2ODc3NTg4MDQ4MTAwNCwgLTY5Ljg5MDExNDI2NzQ4Njc4XSwNCiAgICAgICAgICBpY29uPWZsLkljb24oY29sb3I9ImJsdWUiLGljb249Im9rLXNpZ24iKSxwb3B1cD1mbC5Qb3B1cCh0ZXh0XzAwMyxtYXhfd2lkdGg9MjAwKSkuYWRkX3RvKHBhcnF1ZV9pbmRlcGVuZGVuY2lhX2FscmVkZWRvcmVzKQ0KDQoNCkZsb2F0SW1hZ2UoaW1nXzAwMSxsZWZ0PTkwLGJvdHRvbT05MCkuYWRkX3RvKHBhcnF1ZV9pbmRlcGVuZGVuY2lhX2FscmVkZWRvcmVzKQ0KDQoNCnBhcnF1ZV9pbmRlcGVuZGVuY2lhX2FscmVkZWRvcmVzLnNhdmUoIm1hcGFfZm9saXVtXzAwNy5odG1sIikNCg0KcGFycXVlX2luZGVwZW5kZW5jaWFfYWxyZWRlZG9yZXMNCmBgYA0KDQoNCiMjIE3Dumx0aXBsZXMgTWFyY2Fkb3JlcyAtIENhc28gSUkNCg0KYGBge3B5dGhvbiBmb2xpdW1fMDkscmVzdWx0cz0naGlkZSd9DQoNCiMgTXVsdGlwbGVzIE1hcmNhZG9yZXMgLSBEYXRhIEZyYW1lIC0gQ2FzbyBJSQ0KDQpwYXJxdWVfaW5kZXBlbmRlbmNpYV9hbHJlZGVkb3JlcyA9IGZsLk1hcChsb2NhdGlvbj1bMTguNDcxMjc5MjIyODI1MDA3LCAtNjkuODkyMDY2OTE1NTMwNDZdLHpvb21fc3RhcnQ9MTYpDQoNCg0KaW1nXzAwMSA9ICJweXRob25fbG9nby5wbmciDQoNCmNlbnRyb19kYXRhZnJhbWUgPSBwZC5EYXRhRnJhbWUoeydsdWdhcic6WydJZ2xlc2lhIE51ZXN0cmEgU2XDsW9yYSBkZSBMYSBNZXJjZWQnLCdDb252ZW50byBSZWdpbmEgQW5nZWxvcnVtJywnUHVlcnRhIGRlIGxhIE1pc2VyaWNvcmRpYSddLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbGF0aXR1ZCc6WzE4LjQ3NDE2OTIxNDg2MzY1LDE4LjQ3MTExNjQwNDkyMzEyNiwxOC40Njg3NzU4ODA0ODEwMDRdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbG9uZ2l0dWQnOlstNjkuODg4MjQ3NDUwMTQyNzksLTY5Ljg4NzE1MzEwODkzNjIsLTY5Ljg5MDExNDI2NzQ4Njc4XSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NpbWJvbG8nOlsnb2stc2lnbicsJ29rLXNpZ24nLCdvay1zaWduJ10sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjb2xvcic6WydkYXJrLWJsdWUnLCdvcmFuZ2UnLCdibHVlJ119KQ0KDQpmb3IgaSBpbiBjZW50cm9fZGF0YWZyYW1lLml0ZXJ0dXBsZXMoKToNCiAgICBmbC5NYXJrZXIobG9jYXRpb249W2kubGF0aXR1ZCxpLmxvbmdpdHVkXSwNCiAgICAgICAgICAgICAgaWNvbj1mbC5JY29uKGNvbG9yPWkuY29sb3IsaWNvbj1pLnNpbWJvbG8pLHBvcHVwPWZsLlBvcHVwKGkubHVnYXIsbWF4X3dpZHRoPTIwMCkpLmFkZF90byhwYXJxdWVfaW5kZXBlbmRlbmNpYV9hbHJlZGVkb3JlcykNCg0KRmxvYXRJbWFnZShpbWdfMDAxLGxlZnQ9OTAsYm90dG9tPTkwKS5hZGRfdG8ocGFycXVlX2luZGVwZW5kZW5jaWFfYWxyZWRlZG9yZXMpDQoNCg0KcGFycXVlX2luZGVwZW5kZW5jaWFfYWxyZWRlZG9yZXMuc2F2ZSgibWFwYV9mb2xpdW1fMDA4Lmh0bWwiKQ0KDQpwYXJxdWVfaW5kZXBlbmRlbmNpYV9hbHJlZGVkb3Jlcw0KYGBgDQoNCg0KIyMgTcO6dGxpcGxlcyBNYXJjYWRvcmVzIC0gQ2FzbyBJSUkNCg0KYGBge3B5dGhvbiBmb2xpdW1fMTAscmVzdWx0cz0naGlkZSd9DQoNCiMgTXVsdGlwbGVzIE1hcmNhZG9yZXMgLSBQYW5kYXMgKGFyY2hpdm8udHh0KSAtIENhc28gSUlJDQoNCnBhcnF1ZV9pbmRlcGVuZGVuY2lhX2FscmVkZWRvcmVzID0gZmwuTWFwKGxvY2F0aW9uPVsxOC40NzEyNzkyMjI4MjUwMDcsIC02OS44OTIwNjY5MTU1MzA0Nl0sem9vbV9zdGFydD0xNikNCg0KDQppbWdfMDAxID0gInB5dGhvbl9sb2dvLnBuZyINCg0KDQpGbG9hdEltYWdlKGltZ18wMDEsbGVmdD05MCxib3R0b209OTApLmFkZF90byhwYXJxdWVfaW5kZXBlbmRlbmNpYV9hbHJlZGVkb3JlcykNCg0KcHVudG9zID0gcGQucmVhZF9jc3YoInB1bnRvc19kb20udHh0IikNCg0KcHVudG9zDQoNCnB1bnRvc19mcmFtZSA9IHBkLkRhdGFGcmFtZShwdW50b3MpDQoNCmZvciBpIGluIHB1bnRvc19mcmFtZS5pdGVydHVwbGVzKCk6DQogICAgZmwuTWFya2VyKGxvY2F0aW9uPVtpLmxhdGl0dWQsaS5sb25naXR1ZF0sDQogICAgICAgICAgICAgIGljb249ZmwuSWNvbihjb2xvcj1pLmNvbG9yLGljb249aS5zaW1ib2xvKSxwb3B1cD1mbC5Qb3B1cChpLmx1Z2FyLG1heF93aWR0aD0yMDApKS5hZGRfdG8ocGFycXVlX2luZGVwZW5kZW5jaWFfYWxyZWRlZG9yZXMpDQogICAgDQpwYXJxdWVfaW5kZXBlbmRlbmNpYV9hbHJlZGVkb3JlcyAgICANCg0KYGBgDQoNCg0KIyMgVHV0b3JpYWwgRm9saXVtIC0gWW91VHViZQ0KDQpgYGB7ciB2ZW1iZWRyfQ0KDQojIEluY3J1c3RhbW9zIGFsIGRvY3VtZW50byB1biB0dXRvcmlhbCBkZSBZb3VUdWJlIGhhY2llbmRvIHVzbyBkZSBsYSBsaWJyZXLDrWEgdmVtYmVkcg0KDQpsaWJyYXJ5KHZlbWJlZHIpDQoNCmVtYmVkX3VybCgiaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj14bF9PRng3Qmd0QSIpICU+JSANCiAgIHVzZV9hbGlnbigiY2VudGVyIikgJT4lDQogICB1c2Vfcm91bmRlZCgxMCkNCg0KDQpgYGANCg0KPGRpdiBjbGFzcz0idG9jaWZ5LWV4dGVuZC1wYWdlIiBkYXRhLXVuaXF1ZT0idG9jaWZ5LWV4dGVuZC1wYWdlIiBzdHlsZT0iaGVpZ2h0OiAwOyI+PC9kaXY+