Skip to content

Instantly share code, notes, and snippets.

@ravy101
Last active March 15, 2019 09:55
Show Gist options
  • Save ravy101/1d50cb6156ed98f99273556733bd0258 to your computer and use it in GitHub Desktop.
Save ravy101/1d50cb6156ed98f99273556733bd0258 to your computer and use it in GitHub Desktop.
Created on Cognitive Class Labs
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data Science Capstone Project - Week 3\n",
"First import required libraries."
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"from geopy.geocoders import Nominatim # convert an address into latitude and longitude values\n",
"import requests # library to handle requests\n",
"from pandas.io.json import json_normalize # tranform JSON file into a pandas dataframe\n",
"#!conda install -c conda-forge geocoder --yes\n",
"import geocoder\n",
"from sklearn.cluster import KMeans\n",
"\n",
"#!conda install -c conda-forge folium=0.5.0 --yes # uncomment this line if you haven't completed the Foursquare API lab\n",
"import folium \n",
"import matplotlib.cm as cm\n",
"import matplotlib.colors as colors"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Part 1 - Parse and Clean the Postcode Data\n",
"Get the wikipedia page to be scraped."
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Data downloaded!\n"
]
}
],
"source": [
"!wget -q -O 'toronto_data.html' https://en.wikipedia.org/wiki/List_of_postal_codes_of_Canada:_M\n",
"print('Data downloaded!')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Open the HTML file and read the postcodes table using pandas. Pandas has a read_html function to parse tables from HTML content into a list of DataFrames."
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {},
"outputs": [],
"source": [
"with open('toronto_data.html', 'r') as myfile:\n",
" html_data = myfile.read()\n",
"dfs = pd.read_html(html_data)\n",
"df = dfs[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we will remove the not assigned boroughs and replace the not assigned neighbourhoods with the borough name. We will also join neighbourhoods with the same postcode."
]
},
{
"cell_type": "code",
"execution_count": 113,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/jupyterlab/conda/lib/python3.6/site-packages/pandas/core/indexing.py:190: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame\n",
"\n",
"See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n",
" self._setitem_with_indexer(indexer, value)\n",
"/home/jupyterlab/conda/lib/python3.6/site-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame\n",
"\n",
"See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n",
" \n"
]
}
],
"source": [
"df = df[df['Borough'] != 'Not assigned']\n",
"df.loc[df['Neighbourhood'] == 'Not assigned', 'Neighbourhood'] = df.Borough\n",
"df_grp = pd.DataFrame(df.groupby(['Postcode', 'Borough'])['Neighbourhood'].apply(lambda x: \"%s\" % ', '.join(x))).reset_index()"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>Scarborough</td>\n",
" <td>Rouge, Malvern</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>Scarborough</td>\n",
" <td>Highland Creek, Rouge Hill, Port Union</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>Scarborough</td>\n",
" <td>Guildwood, Morningside, West Hill</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>Scarborough</td>\n",
" <td>Woburn</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>Scarborough</td>\n",
" <td>Cedarbrae</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood\n",
"0 M1B Scarborough Rouge, Malvern\n",
"1 M1C Scarborough Highland Creek, Rouge Hill, Port Union\n",
"2 M1E Scarborough Guildwood, Morningside, West Hill\n",
"3 M1G Scarborough Woburn\n",
"4 M1H Scarborough Cedarbrae"
]
},
"execution_count": 114,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_grp.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Part 2 - Add Longitude and Latitude"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we will define a function that will take a post code and iterate until coordinates can be returned."
]
},
{
"cell_type": "code",
"execution_count": 115,
"metadata": {},
"outputs": [],
"source": [
"def get_toronto_coords(postal_code):\n",
" lat_lng_coords = None\n",
" while(lat_lng_coords is None):\n",
" g = geocoder.google('{}, Toronto, Ontario'.format(postal_code))\n",
" lat_lng_coords = g.latlng\n",
"\n",
" return lat_lng_coords"
]
},
{
"cell_type": "code",
"execution_count": 116,
"metadata": {},
"outputs": [],
"source": [
"#get_toronto_coords('M1B')\n",
"#get_toronto_coords('M1H')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Geocoder is not responding at all so we will use the CSV instead. Starting with downloading the file."
]
},
{
"cell_type": "code",
"execution_count": 117,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Coords downloaded!\n"
]
}
],
"source": [
"!wget -q -O 'toronto_coords.csv' https://cocl.us/Geospatial_data\n",
"print('Coords downloaded!')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we will join our grouped dataframe with the corresponding coordinates."
]
},
{
"cell_type": "code",
"execution_count": 118,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>Scarborough</td>\n",
" <td>Rouge, Malvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>Scarborough</td>\n",
" <td>Highland Creek, Rouge Hill, Port Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>Scarborough</td>\n",
" <td>Guildwood, Morningside, West Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>Scarborough</td>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>Scarborough</td>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood Latitude \\\n",
"0 M1B Scarborough Rouge, Malvern 43.806686 \n",
"1 M1C Scarborough Highland Creek, Rouge Hill, Port Union 43.784535 \n",
"2 M1E Scarborough Guildwood, Morningside, West Hill 43.763573 \n",
"3 M1G Scarborough Woburn 43.770992 \n",
"4 M1H Scarborough Cedarbrae 43.773136 \n",
"\n",
" Longitude \n",
"0 -79.194353 \n",
"1 -79.160497 \n",
"2 -79.188711 \n",
"3 -79.216917 \n",
"4 -79.239476 "
]
},
"execution_count": 118,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"coord_df = pd.read_csv('toronto_coords.csv')\n",
"df_full = df_grp.join(coord_df.set_index('Postal Code'), on='Postcode', how='left')\n",
"df_full.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Part 3 - Analysis\n",
"Now we will make FourSquare API calls to gather venue information for our neighbourhoods and apply cluster analysis. We will modify and use some code from the previous labs."
]
},
{
"cell_type": "code",
"execution_count": 119,
"metadata": {},
"outputs": [],
"source": [
"CLIENT_ID = '' # your Foursquare ID\n",
"CLIENT_SECRET = '' # your Foursquare Secret\n",
"VERSION = '20180605' # Foursquare API version\n",
"LIMIT = 500\n",
"radius = 500\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reuse the functions defined in the lab that process FourSquare API responses with some minor changes. This time our coordinates are for the postcode rather than the neighborhood."
]
},
{
"cell_type": "code",
"execution_count": 205,
"metadata": {},
"outputs": [],
"source": [
"def get_category_type(row):\n",
" try:\n",
" categories_list = row['categories']\n",
" except:\n",
" categories_list = row['venue.categories']\n",
" \n",
" if len(categories_list) == 0:\n",
" return None\n",
" else:\n",
" return categories_list[0]['name']\n",
"\n",
"def getNearbyVenues(names, latitudes, longitudes, LIMIT = 500, radius=750):\n",
" \n",
" venues_list=[]\n",
" for name, lat, lng in zip(names, latitudes, longitudes):\n",
" \n",
" # create the API request URL\n",
" url = 'https://api.foursquare.com/v2/venues/explore?&client_id={}&client_secret={}&v={}&ll={},{}&radius={}&limit={}'.format(\n",
" CLIENT_ID, \n",
" CLIENT_SECRET, \n",
" VERSION, \n",
" lat, \n",
" lng, \n",
" radius, \n",
" LIMIT)\n",
" \n",
" # make the GET request\n",
" results = requests.get(url).json()[\"response\"]['groups'][0]['items']\n",
" \n",
" # return only relevant information for each nearby venue\n",
" venues_list.append([(\n",
" name, \n",
" lat, \n",
" lng, \n",
" v['venue']['name'], \n",
" v['venue']['location']['lat'], \n",
" v['venue']['location']['lng'], \n",
" v['venue']['categories'][0]['name']) for v in results])\n",
"\n",
" nearby_venues = pd.DataFrame([item for venue_list in venues_list for item in venue_list])\n",
" nearby_venues.columns = ['Postcode', \n",
" 'Postcode Latitude', \n",
" 'Postcode Longitude', \n",
" 'Venue', \n",
" 'Venue Latitude', \n",
" 'Venue Longitude', \n",
" 'Venue Category']\n",
" \n",
" return(nearby_venues)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Invoke the FourSquare API with our Toronto postcodes and coordinates."
]
},
{
"cell_type": "code",
"execution_count": 121,
"metadata": {},
"outputs": [
{
"ename": "KeyError",
"evalue": "'groups'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-121-1e43f95cf479>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtoronto_venues\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetNearbyVenues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnames\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdf_full\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Postcode'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlatitudes\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdf_full\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Latitude'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlongitudes\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdf_full\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Longitude'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mtoronto_venues\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhead\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m<ipython-input-120-547eb41bd933>\u001b[0m in \u001b[0;36mgetNearbyVenues\u001b[0;34m(names, latitudes, longitudes, LIMIT, radius)\u001b[0m\n\u001b[1;32m 26\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0;31m# make the GET request\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 28\u001b[0;31m \u001b[0mresults\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"response\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'groups'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'items'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 29\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0;31m# return only relevant information for each nearby venue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mKeyError\u001b[0m: 'groups'"
]
}
],
"source": [
"toronto_venues = getNearbyVenues(names=df_full['Postcode'], latitudes=df_full['Latitude'], longitudes=df_full['Longitude'])\n",
"\n",
"toronto_venues.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will one-hot encode our venue data and re-add the postcode column for grouping."
]
},
{
"cell_type": "code",
"execution_count": 122,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Accessories Store</th>\n",
" <th>Adult Boutique</th>\n",
" <th>Afghan Restaurant</th>\n",
" <th>Airport</th>\n",
" <th>Airport Food Court</th>\n",
" <th>Airport Gate</th>\n",
" <th>Airport Lounge</th>\n",
" <th>Airport Service</th>\n",
" <th>Airport Terminal</th>\n",
" <th>American Restaurant</th>\n",
" <th>...</th>\n",
" <th>Video Game Store</th>\n",
" <th>Video Store</th>\n",
" <th>Vietnamese Restaurant</th>\n",
" <th>Warehouse Store</th>\n",
" <th>Wine Bar</th>\n",
" <th>Wine Shop</th>\n",
" <th>Wings Joint</th>\n",
" <th>Women's Store</th>\n",
" <th>Yoga Studio</th>\n",
" <th>Postcode</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>M1B</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>M1C</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>M1E</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>M1E</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>M1E</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 273 columns</p>\n",
"</div>"
],
"text/plain": [
" Accessories Store Adult Boutique Afghan Restaurant Airport \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Airport Food Court Airport Gate Airport Lounge Airport Service \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Airport Terminal American Restaurant ... Video Game Store Video Store \\\n",
"0 0 0 ... 0 0 \n",
"1 0 0 ... 0 0 \n",
"2 0 0 ... 0 0 \n",
"3 0 0 ... 0 0 \n",
"4 0 0 ... 0 0 \n",
"\n",
" Vietnamese Restaurant Warehouse Store Wine Bar Wine Shop Wings Joint \\\n",
"0 0 0 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Women's Store Yoga Studio Postcode \n",
"0 0 0 M1B \n",
"1 0 0 M1C \n",
"2 0 0 M1E \n",
"3 0 0 M1E \n",
"4 0 0 M1E \n",
"\n",
"[5 rows x 273 columns]"
]
},
"execution_count": 122,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"toronto_onehot = pd.get_dummies(toronto_venues[['Venue Category']], prefix=\"\", prefix_sep=\"\")\n",
"toronto_onehot['Postcode'] = toronto_venues['Postcode'] \n",
"\n",
"toronto_onehot.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will group our venue information in 2 ways for cluster analysis:\n",
"* **sum** - Venue type columns will record the total number of venues in the neighborhood of this type. This will give us an idea of what is available nearby and consider the number of venues of each type.\n",
"* **mean** - Venue type columns will record the proportion of venues in the neighborhood that are of this type. This will de-prioritize the total number of venues in order to prevent our clustering from simply representing the overall development/density of the area.\n"
]
},
{
"cell_type": "code",
"execution_count": 123,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Postcode</th>\n",
" <th>Accessories Store</th>\n",
" <th>Adult Boutique</th>\n",
" <th>Afghan Restaurant</th>\n",
" <th>Airport</th>\n",
" <th>Airport Food Court</th>\n",
" <th>Airport Gate</th>\n",
" <th>Airport Lounge</th>\n",
" <th>Airport Service</th>\n",
" <th>Airport Terminal</th>\n",
" <th>...</th>\n",
" <th>Vegetarian / Vegan Restaurant</th>\n",
" <th>Video Game Store</th>\n",
" <th>Video Store</th>\n",
" <th>Vietnamese Restaurant</th>\n",
" <th>Warehouse Store</th>\n",
" <th>Wine Bar</th>\n",
" <th>Wine Shop</th>\n",
" <th>Wings Joint</th>\n",
" <th>Women's Store</th>\n",
" <th>Yoga Studio</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>...</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 273 columns</p>\n",
"</div>"
],
"text/plain": [
" Postcode Accessories Store Adult Boutique Afghan Restaurant Airport \\\n",
"0 M1B 0 0 0 0 \n",
"1 M1C 0 0 0 0 \n",
"2 M1E 0 0 0 0 \n",
"3 M1G 0 0 0 0 \n",
"4 M1H 0 0 0 0 \n",
"\n",
" Airport Food Court Airport Gate Airport Lounge Airport Service \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Airport Terminal ... Vegetarian / Vegan Restaurant Video Game Store \\\n",
"0 0 ... 0 0 \n",
"1 0 ... 0 0 \n",
"2 0 ... 0 0 \n",
"3 0 ... 0 0 \n",
"4 0 ... 0 0 \n",
"\n",
" Video Store Vietnamese Restaurant Warehouse Store Wine Bar Wine Shop \\\n",
"0 0 0 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Wings Joint Women's Store Yoga Studio \n",
"0 0 0 0 \n",
"1 0 0 0 \n",
"2 0 0 0 \n",
"3 0 0 0 \n",
"4 0 0 0 \n",
"\n",
"[5 rows x 273 columns]"
]
},
"execution_count": 123,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"toronto_grouped_sum = toronto_onehot.groupby('Postcode').sum().reset_index()\n",
"toronto_grouped_mean = toronto_onehot.groupby('Postcode').mean().reset_index()\n",
"toronto_grouped_sum.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we will apply our clustering to both sets of grouped data."
]
},
{
"cell_type": "code",
"execution_count": 124,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4,\n",
" 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 4, 4,\n",
" 4, 0, 4, 4, 4, 0, 0, 0, 1, 1, 1, 3, 2, 3, 2, 2, 4, 4, 4, 0, 0, 0,\n",
" 4, 1, 2, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4,\n",
" 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], dtype=int32)"
]
},
"execution_count": 124,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"kclusters = 5\n",
"post_temp = toronto_grouped_sum['Postcode']\n",
"toronto_grouped_clustering_sum = toronto_grouped_sum.drop('Postcode', 1)\n",
"toronto_grouped_clustering_mean = toronto_grouped_mean.drop('Postcode', 1)\n",
"# run k-means clustering\n",
"kmeans_sum = KMeans(n_clusters=kclusters, random_state=10).fit(toronto_grouped_clustering_sum)\n",
"kmeans_mean = KMeans(n_clusters=kclusters, random_state=10).fit(toronto_grouped_clustering_mean)\n",
"# check cluster labels generated for each row in the dataframe\n",
"kmeans_sum.labels_[0:100] "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will record the clustering labels and store in a new data frame with the postcode data."
]
},
{
"cell_type": "code",
"execution_count": 125,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Cluster Sum</th>\n",
" <th>Cluster Mean</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Postcode</th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>M1B</th>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>M1C</th>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>M1E</th>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>M1G</th>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>M1H</th>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Cluster Sum Cluster Mean\n",
"Postcode \n",
"M1B 4 1\n",
"M1C 4 1\n",
"M1E 4 1\n",
"M1G 4 1\n",
"M1H 4 1"
]
},
"execution_count": 125,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_clust = pd.DataFrame({'Cluster Sum': kmeans_sum.labels_, 'Cluster Mean': kmeans_mean.labels_})\n",
"df_clust.index = post_temp\n",
"df_clust.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now the cluster results are joined back to the consolidated full data frame."
]
},
{
"cell_type": "code",
"execution_count": 126,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>Cluster Sum</th>\n",
" <th>Cluster Mean</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>Scarborough</td>\n",
" <td>Rouge, Malvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>Scarborough</td>\n",
" <td>Highland Creek, Rouge Hill, Port Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>Scarborough</td>\n",
" <td>Guildwood, Morningside, West Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>Scarborough</td>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>Scarborough</td>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood Latitude \\\n",
"0 M1B Scarborough Rouge, Malvern 43.806686 \n",
"1 M1C Scarborough Highland Creek, Rouge Hill, Port Union 43.784535 \n",
"2 M1E Scarborough Guildwood, Morningside, West Hill 43.763573 \n",
"3 M1G Scarborough Woburn 43.770992 \n",
"4 M1H Scarborough Cedarbrae 43.773136 \n",
"\n",
" Longitude Cluster Sum Cluster Mean \n",
"0 -79.194353 4 1 \n",
"1 -79.160497 4 1 \n",
"2 -79.188711 4 1 \n",
"3 -79.216917 4 1 \n",
"4 -79.239476 4 1 "
]
},
"execution_count": 126,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_full_clust = df_full.join(df_clust, on='Postcode', how='inner')\n",
"df_full_clust.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will first use the sum based clustering to colour our postcodes on a folium map."
]
},
{
"cell_type": "code",
"execution_count": 198,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExIiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDMuNywtNzkuNF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6b29tOiAxMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Qm91bmRzOiBib3VuZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXllcnM6IFtdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ybGRDb3B5SnVtcDogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcnM6IEwuQ1JTLkVQU0czODU3CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgdGlsZV9sYXllcl9jZDIyYzkyMjFlMzg0OTJiYjhkYTZiZjkzZTRmMGVjOSA9IEwudGlsZUxheWVyKAogICAgICAgICAgICAgICAgJ2h0dHBzOi8ve3N9LnRpbGUub3BlbnN0cmVldG1hcC5vcmcve3p9L3t4fS97eX0ucG5nJywKICAgICAgICAgICAgICAgIHsKICAiYXR0cmlidXRpb24iOiBudWxsLAogICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwKICAibWF4Wm9vbSI6IDE4LAogICJtaW5ab29tIjogMSwKICAibm9XcmFwIjogZmFsc2UsCiAgInN1YmRvbWFpbnMiOiAiYWJjIgp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOWY5MzhlNDliNTA0NDJjNmE5OTM1Yjg4MmZiZjMyZjQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My44MDY2ODYyOTk5OTk5OTYsLTc5LjE5NDM1MzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjRmNWYxMDExY2E5NDhiZGE1ZjNjM2E1ZTU2NzdiNTYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTdkNTQ3YjZhNzU4NDk1MzgyZTJjYmVmNTNkNzZkZTggPSAkKCc8ZGl2IGlkPSJodG1sX2U3ZDU0N2I2YTc1ODQ5NTM4MmUyY2JlZjUzZDc2ZGU4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3VnZSwgTWFsdmVybiBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzI0ZjVmMTAxMWNhOTQ4YmRhNWYzYzNhNWU1Njc3YjU2LnNldENvbnRlbnQoaHRtbF9lN2Q1NDdiNmE3NTg0OTUzODJlMmNiZWY1M2Q3NmRlOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85ZjkzOGU0OWI1MDQ0MmM2YTk5MzViODgyZmJmMzJmNC5iaW5kUG9wdXAocG9wdXBfMjRmNWYxMDExY2E5NDhiZGE1ZjNjM2E1ZTU2NzdiNTYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZjVhZjgwNDkxNmIxNDU2ZWJlNGE5NjhmNmExZTkxZGIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43ODQ1MzUxLC03OS4xNjA0OTcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzI4MTY1MDdlNTA3MjQzNDNiYzg3ZDY1ZjZjZTYyZmM2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc2NTg1ODcxNTFhNjQyZmI5MWJlZjU3OWQwMTQ3NjkyID0gJCgnPGRpdiBpZD0iaHRtbF83NjU4NTg3MTUxYTY0MmZiOTFiZWY1NzlkMDE0NzY5MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGlnaGxhbmQgQ3JlZWssIFJvdWdlIEhpbGwsIFBvcnQgVW5pb24gQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yODE2NTA3ZTUwNzI0MzQzYmM4N2Q2NWY2Y2U2MmZjNi5zZXRDb250ZW50KGh0bWxfNzY1ODU4NzE1MWE2NDJmYjkxYmVmNTc5ZDAxNDc2OTIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZjVhZjgwNDkxNmIxNDU2ZWJlNGE5NjhmNmExZTkxZGIuYmluZFBvcHVwKHBvcHVwXzI4MTY1MDdlNTA3MjQzNDNiYzg3ZDY1ZjZjZTYyZmM2KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2MyYTIwMWRkOWRiNjQ3NGE4ODdiMzAzODEwNTlhZDkwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzYzNTcyNiwtNzkuMTg4NzExNV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzAyNjcyYTNiZmVlNDRhZTA5ZWIwZjJmNTU2YzI0NDI1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc0NjkwYzJhOTk1OTQxZjFiMzdjNWYyNmJlYmFmODkzID0gJCgnPGRpdiBpZD0iaHRtbF83NDY5MGMyYTk5NTk0MWYxYjM3YzVmMjZiZWJhZjg5MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R3VpbGR3b29kLCBNb3JuaW5nc2lkZSwgV2VzdCBIaWxsIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDI2NzJhM2JmZWU0NGFlMDllYjBmMmY1NTZjMjQ0MjUuc2V0Q29udGVudChodG1sXzc0NjkwYzJhOTk1OTQxZjFiMzdjNWYyNmJlYmFmODkzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2MyYTIwMWRkOWRiNjQ3NGE4ODdiMzAzODEwNTlhZDkwLmJpbmRQb3B1cChwb3B1cF8wMjY3MmEzYmZlZTQ0YWUwOWViMGYyZjU1NmMyNDQyNSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hYTVlMzk2MTY0NTg0Mzg0YWUxMGZkMjVlYTc5ZWU5ZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MDk5MjEsLTc5LjIxNjkxNzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjRiYTI5M2FkMjNmNDg3Mjg3ZWJmZTlhMzg3MTNlODAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODBjYTYxMjgwNTBmNDI5Y2JlYTBiYjNiNjNmYmI0MWIgPSAkKCc8ZGl2IGlkPSJodG1sXzgwY2E2MTI4MDUwZjQyOWNiZWEwYmIzYjYzZmJiNDFiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb2J1cm4gQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82NGJhMjkzYWQyM2Y0ODcyODdlYmZlOWEzODcxM2U4MC5zZXRDb250ZW50KGh0bWxfODBjYTYxMjgwNTBmNDI5Y2JlYTBiYjNiNjNmYmI0MWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYWE1ZTM5NjE2NDU4NDM4NGFlMTBmZDI1ZWE3OWVlOWQuYmluZFBvcHVwKHBvcHVwXzY0YmEyOTNhZDIzZjQ4NzI4N2ViZmU5YTM4NzEzZTgwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2FkODhhMDhiMWNjMTRjMDk5YTNiYzdkZDFkNjY0MjEyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzczMTM2LC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzdlYjUyMjUyYmZjZDRjMjQ4Mjc2ZmYxZDE1YWY4NTljID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzYzYTIxZGJjYzcxZTQyZWNiYjA1ODIxODljMzVlMmJhID0gJCgnPGRpdiBpZD0iaHRtbF82M2EyMWRiY2M3MWU0MmVjYmIwNTgyMTg5YzM1ZTJiYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2VkYXJicmFlIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2ViNTIyNTJiZmNkNGMyNDgyNzZmZjFkMTVhZjg1OWMuc2V0Q29udGVudChodG1sXzYzYTIxZGJjYzcxZTQyZWNiYjA1ODIxODljMzVlMmJhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2FkODhhMDhiMWNjMTRjMDk5YTNiYzdkZDFkNjY0MjEyLmJpbmRQb3B1cChwb3B1cF83ZWI1MjI1MmJmY2Q0YzI0ODI3NmZmMWQxNWFmODU5Yyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zMmIxMjc2ODhlMmE0YmNlOTI1MWE0MmI5YTU1NjFhZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc0NDczNDIsLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMGNjODE4OGE3MDcxNDNiNGJjNDk5MzdiNWM3MWU4OWMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjlmMjJiNGJiZTY2NDU0Nzg4NGM4OGMwNjBjZDc0NDEgPSAkKCc8ZGl2IGlkPSJodG1sX2I5ZjIyYjRiYmU2NjQ1NDc4ODRjODhjMDYwY2Q3NDQxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TY2FyYm9yb3VnaCBWaWxsYWdlIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMGNjODE4OGE3MDcxNDNiNGJjNDk5MzdiNWM3MWU4OWMuc2V0Q29udGVudChodG1sX2I5ZjIyYjRiYmU2NjQ1NDc4ODRjODhjMDYwY2Q3NDQxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzMyYjEyNzY4OGUyYTRiY2U5MjUxYTQyYjlhNTU2MWFkLmJpbmRQb3B1cChwb3B1cF8wY2M4MTg4YTcwNzE0M2I0YmM0OTkzN2I1YzcxZTg5Yyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMjUzNzg4MDRkODI0ZTdmYjA0Y2IwN2U3NGVjYTgxOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcyNzkyOTIsLTc5LjI2MjAyOTQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfN2NmNzJkZmFlODBlNDIwNDg2ZjI4YzI3ZGVkYTBiNWUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2VkYzQ0NjhmZTA2NDY0ZGI4NjVlYjZkZjQ2NjJlOGUgPSAkKCc8ZGl2IGlkPSJodG1sX2NlZGM0NDY4ZmUwNjQ2NGRiODY1ZWI2ZGY0NjYyZThlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5FYXN0IEJpcmNobW91bnQgUGFyaywgSW9udmlldywgS2VubmVkeSBQYXJrIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2NmNzJkZmFlODBlNDIwNDg2ZjI4YzI3ZGVkYTBiNWUuc2V0Q29udGVudChodG1sX2NlZGM0NDY4ZmUwNjQ2NGRiODY1ZWI2ZGY0NjYyZThlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2IyNTM3ODgwNGQ4MjRlN2ZiMDRjYjA3ZTc0ZWNhODE4LmJpbmRQb3B1cChwb3B1cF83Y2Y3MmRmYWU4MGU0MjA0ODZmMjhjMjdkZWRhMGI1ZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81OWNiOGNjZTJiYmE0MjQ2YTQxYTRkYTAwN2M0OTI3YSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMTExMTcwMDAwMDAwNCwtNzkuMjg0NTc3Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzYzYjJmNDNiYWEwMjQ1M2U5Y2NhMWUxNWQ4NDgyMmQ1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2JlMGE4OTE3NzkzMjRmZTY4OTdlZTU5OGViMzZkMWZmID0gJCgnPGRpdiBpZD0iaHRtbF9iZTBhODkxNzc5MzI0ZmU2ODk3ZWU1OThlYjM2ZDFmZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2xhaXJsZWEsIEdvbGRlbiBNaWxlLCBPYWtyaWRnZSBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzYzYjJmNDNiYWEwMjQ1M2U5Y2NhMWUxNWQ4NDgyMmQ1LnNldENvbnRlbnQoaHRtbF9iZTBhODkxNzc5MzI0ZmU2ODk3ZWU1OThlYjM2ZDFmZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81OWNiOGNjZTJiYmE0MjQ2YTQxYTRkYTAwN2M0OTI3YS5iaW5kUG9wdXAocG9wdXBfNjNiMmY0M2JhYTAyNDUzZTljY2ExZTE1ZDg0ODIyZDUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfN2RjNzllOGE5NTI3NDcyMmJlYzAxYTE2YmQ3YjI1YzcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTYzMTYsLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTYxZGQ1OGI5NWQzNDQ3ZTg1OGIxMjA1NDM5OTk3ODMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNzZlZTZlN2VhZTdjNDYyNjkzZTVlYmEyNzBjYjk1MjAgPSAkKCc8ZGl2IGlkPSJodG1sXzc2ZWU2ZTdlYWU3YzQ2MjY5M2U1ZWJhMjcwY2I5NTIwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DbGlmZmNyZXN0LCBDbGlmZnNpZGUsIFNjYXJib3JvdWdoIFZpbGxhZ2UgV2VzdCBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E2MWRkNThiOTVkMzQ0N2U4NThiMTIwNTQzOTk5NzgzLnNldENvbnRlbnQoaHRtbF83NmVlNmU3ZWFlN2M0NjI2OTNlNWViYTI3MGNiOTUyMCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl83ZGM3OWU4YTk1Mjc0NzIyYmVjMDFhMTZiZDdiMjVjNy5iaW5kUG9wdXAocG9wdXBfYTYxZGQ1OGI5NWQzNDQ3ZTg1OGIxMjA1NDM5OTk3ODMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjEwNTIwZGU5M2EyNDhiYmFmNTdkOWVlODVmOTNhZTggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTI2NTcwMDAwMDAwMDQsLTc5LjI2NDg0ODFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83ZWM4MGNjMGI3MDY0NDI1YTMzNzY5NGVjY2NkNjhkMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hODY3M2JjMzA5ZGQ0MDQ4YTIxYmJhMzQ0ODJiMGRlZiA9ICQoJzxkaXYgaWQ9Imh0bWxfYTg2NzNiYzMwOWRkNDA0OGEyMWJiYTM0NDgyYjBkZWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJpcmNoIENsaWZmLCBDbGlmZnNpZGUgV2VzdCBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzdlYzgwY2MwYjcwNjQ0MjVhMzM3Njk0ZWNjY2Q2OGQwLnNldENvbnRlbnQoaHRtbF9hODY3M2JjMzA5ZGQ0MDQ4YTIxYmJhMzQ0ODJiMGRlZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yMTA1MjBkZTkzYTI0OGJiYWY1N2Q5ZWU4NWY5M2FlOC5iaW5kUG9wdXAocG9wdXBfN2VjODBjYzBiNzA2NDQyNWEzMzc2OTRlY2NjZDY4ZDApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTU4MjIxZTI2NzljNDFmN2E3YTA4NmRkZjY1NjQzOWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTc0MDk2LC03OS4yNzMzMDQwMDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzUzMmY2NTdiYTMxYjRkM2Q4YjFkZTlkMmRiODBiNGZhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhmMTlmYWViMGFjZTRjMWFhNTRiYjUyZTNiZmNkZTAwID0gJCgnPGRpdiBpZD0iaHRtbF84ZjE5ZmFlYjBhY2U0YzFhYTU0YmI1MmUzYmZjZGUwMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG9yc2V0IFBhcmssIFNjYXJib3JvdWdoIFRvd24gQ2VudHJlLCBXZXhmb3JkIEhlaWdodHMgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81MzJmNjU3YmEzMWI0ZDNkOGIxZGU5ZDJkYjgwYjRmYS5zZXRDb250ZW50KGh0bWxfOGYxOWZhZWIwYWNlNGMxYWE1NGJiNTJlM2JmY2RlMDApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNTU4MjIxZTI2NzljNDFmN2E3YTA4NmRkZjY1NjQzOWIuYmluZFBvcHVwKHBvcHVwXzUzMmY2NTdiYTMxYjRkM2Q4YjFkZTlkMmRiODBiNGZhKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzhmOTZhNDkzNzZiYjQwZDNhZDQyZDBlYzljYjNkN2ZjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzUwMDcxNTAwMDAwMDA0LC03OS4yOTU4NDkxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTdhOTMxMWFhNjQxNDYzMWJjNGE2MmM3NzFiZTgzMjEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmVlMGRlNjliZGQ0NDlkODhhN2ZlZjNjYjU2NzRmZmYgPSAkKCc8ZGl2IGlkPSJodG1sXzJlZTBkZTY5YmRkNDQ5ZDg4YTdmZWYzY2I1Njc0ZmZmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5NYXJ5dmFsZSwgV2V4Zm9yZCBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzE3YTkzMTFhYTY0MTQ2MzFiYzRhNjJjNzcxYmU4MzIxLnNldENvbnRlbnQoaHRtbF8yZWUwZGU2OWJkZDQ0OWQ4OGE3ZmVmM2NiNTY3NGZmZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84Zjk2YTQ5Mzc2YmI0MGQzYWQ0MmQwZWM5Y2IzZDdmYy5iaW5kUG9wdXAocG9wdXBfMTdhOTMxMWFhNjQxNDYzMWJjNGE2MmM3NzFiZTgzMjEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNzMwMDFhMjM1MThhNDc2ZWI0MDNhNDIwZWZjYTEyMTYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43OTQyMDAzLC03OS4yNjIwMjk0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Y5YmI1NzI4NzEzNzQzNWE5YzExZDY4YjFlM2U3MjZkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzgyYmZkMjgwYTMyOTQ2YjZhZWU1ZjYwODY4NjJjYzg2ID0gJCgnPGRpdiBpZD0iaHRtbF84MmJmZDI4MGEzMjk0NmI2YWVlNWY2MDg2ODYyY2M4NiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWdpbmNvdXJ0IENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZjliYjU3Mjg3MTM3NDM1YTljMTFkNjhiMWUzZTcyNmQuc2V0Q29udGVudChodG1sXzgyYmZkMjgwYTMyOTQ2YjZhZWU1ZjYwODY4NjJjYzg2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzczMDAxYTIzNTE4YTQ3NmViNDAzYTQyMGVmY2ExMjE2LmJpbmRQb3B1cChwb3B1cF9mOWJiNTcyODcxMzc0MzVhOWMxMWQ2OGIxZTNlNzI2ZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81ODFlOGQ2YTJmNzA0YTlmYTU0NWI2NjExZWM2YTRkMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4MTYzNzUsLTc5LjMwNDMwMjFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xNTllNjUwMThkODM0MWQwOWUxOWEyN2QyMWQwNjNlZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wZmZkNjlhYTI5Nzk0MDdhYmI1MDY2MjhkOTc0Zjg2MSA9ICQoJzxkaXYgaWQ9Imh0bWxfMGZmZDY5YWEyOTc5NDA3YWJiNTA2NjI4ZDk3NGY4NjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsYXJrcyBDb3JuZXJzLCBTdWxsaXZhbiwgVGFtIE8mIzM5O1NoYW50ZXIgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xNTllNjUwMThkODM0MWQwOWUxOWEyN2QyMWQwNjNlZC5zZXRDb250ZW50KGh0bWxfMGZmZDY5YWEyOTc5NDA3YWJiNTA2NjI4ZDk3NGY4NjEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNTgxZThkNmEyZjcwNGE5ZmE1NDViNjYxMWVjNmE0ZDAuYmluZFBvcHVwKHBvcHVwXzE1OWU2NTAxOGQ4MzQxZDA5ZTE5YTI3ZDIxZDA2M2VkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzViYjFmMGE1ODlkYTQxZGNhNGEyYWYxYWE1MGVjZWRjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuODE1MjUyMiwtNzkuMjg0NTc3Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzgxOGRmZGExZWRiODRhMTI5ZTBmMjQxMjAyNzdmMWQ5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzljYjBlYTlmY2VhMzRlN2Q5MDk5MDI4NTQzMzlhMDEyID0gJCgnPGRpdiBpZD0iaHRtbF85Y2IwZWE5ZmNlYTM0ZTdkOTA5OTAyODU0MzM5YTAxMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWdpbmNvdXJ0IE5vcnRoLCBMJiMzOTtBbW9yZWF1eCBFYXN0LCBNaWxsaWtlbiwgU3RlZWxlcyBFYXN0IENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODE4ZGZkYTFlZGI4NGExMjllMGYyNDEyMDI3N2YxZDkuc2V0Q29udGVudChodG1sXzljYjBlYTlmY2VhMzRlN2Q5MDk5MDI4NTQzMzlhMDEyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzViYjFmMGE1ODlkYTQxZGNhNGEyYWYxYWE1MGVjZWRjLmJpbmRQb3B1cChwb3B1cF84MThkZmRhMWVkYjg0YTEyOWUwZjI0MTIwMjc3ZjFkOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82Yjc5ZjIxZDQ1YzM0OTYwODA4MWRjMWJiNWZlOTZlMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5OTUyNTIwMDAwMDAwNSwtNzkuMzE4Mzg4N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzhkNGU1YTA5Y2M1MjQxYjQ4Y2JhMzZhZDY1ODE3Yzg4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2VjZjUzYzRjYjQ5MzQ2NmY4ZDU5Nzc4MzJjMjBjOTc0ID0gJCgnPGRpdiBpZD0iaHRtbF9lY2Y1M2M0Y2I0OTM0NjZmOGQ1OTc3ODMyYzIwYzk3NCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TCYjMzk7QW1vcmVhdXggV2VzdCwgU3RlZWxlcyBXZXN0IENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOGQ0ZTVhMDljYzUyNDFiNDhjYmEzNmFkNjU4MTdjODguc2V0Q29udGVudChodG1sX2VjZjUzYzRjYjQ5MzQ2NmY4ZDU5Nzc4MzJjMjBjOTc0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzZiNzlmMjFkNDVjMzQ5NjA4MDgxZGMxYmI1ZmU5NmUxLmJpbmRQb3B1cChwb3B1cF84ZDRlNWEwOWNjNTI0MWI0OGNiYTM2YWQ2NTgxN2M4OCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yN2NmY2EyODVlMGI0OTY4YTBlZWZjNmRhNjVjZGE3NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwMzc2MjIsLTc5LjM2MzQ1MTddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xNzczYmJiNTQwNjI0NzVjYmY0ZWJmODJkZDA4NjRiYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mZTIwNjc3ZmQxMWU0YTkxYmNjNzAyMTczNjY4NzE1OSA9ICQoJzxkaXYgaWQ9Imh0bWxfZmUyMDY3N2ZkMTFlNGE5MWJjYzcwMjE3MzY2ODcxNTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhpbGxjcmVzdCBWaWxsYWdlIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMTc3M2JiYjU0MDYyNDc1Y2JmNGViZjgyZGQwODY0YmEuc2V0Q29udGVudChodG1sX2ZlMjA2NzdmZDExZTRhOTFiY2M3MDIxNzM2Njg3MTU5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzI3Y2ZjYTI4NWUwYjQ5NjhhMGVlZmM2ZGE2NWNkYTc2LmJpbmRQb3B1cChwb3B1cF8xNzczYmJiNTQwNjI0NzVjYmY0ZWJmODJkZDA4NjRiYSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xZTM4ZGZlMDViMDI0YWY1YjYzNDc5MTE4OGYyNTM5MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3ODUxNzUsLTc5LjM0NjU1NTddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAib3JhbmdlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAib3JhbmdlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2M1N2ExZmI5MWI1MTRkZTViZTNkYTg3YWEyMWMyODk3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhmNTliM2EwZDMzNzQ2ZGRiNjYwYjY3YjExMDY1ZDBjID0gJCgnPGRpdiBpZD0iaHRtbF84ZjU5YjNhMGQzMzc0NmRkYjY2MGI2N2IxMTA2NWQwYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RmFpcnZpZXcsIEhlbnJ5IEZhcm0sIE9yaW9sZSBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M1N2ExZmI5MWI1MTRkZTViZTNkYTg3YWEyMWMyODk3LnNldENvbnRlbnQoaHRtbF84ZjU5YjNhMGQzMzc0NmRkYjY2MGI2N2IxMTA2NWQwYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xZTM4ZGZlMDViMDI0YWY1YjYzNDc5MTE4OGYyNTM5Mi5iaW5kUG9wdXAocG9wdXBfYzU3YTFmYjkxYjUxNGRlNWJlM2RhODdhYTIxYzI4OTcpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYTNmMTQzYjZlYTc1NDA3MmI2ZmI2MjNlYTk5MjFiODMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43ODY5NDczLC03OS4zODU5NzVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lOTkzYmFhOWFlYTI0YTVhOWQyN2M3OTA5YWRmYzgxMyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lZjE2N2FlODZmMGU0ZjQzYTk3YmY4NzNkYmE2YWJhNCA9ICQoJzxkaXYgaWQ9Imh0bWxfZWYxNjdhZTg2ZjBlNGY0M2E5N2JmODczZGJhNmFiYTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJheXZpZXcgVmlsbGFnZSBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2U5OTNiYWE5YWVhMjRhNWE5ZDI3Yzc5MDlhZGZjODEzLnNldENvbnRlbnQoaHRtbF9lZjE2N2FlODZmMGU0ZjQzYTk3YmY4NzNkYmE2YWJhNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hM2YxNDNiNmVhNzU0MDcyYjZmYjYyM2VhOTkyMWI4My5iaW5kUG9wdXAocG9wdXBfZTk5M2JhYTlhZWEyNGE1YTlkMjdjNzkwOWFkZmM4MTMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTcwYjY3NThjM2FhNDZiNzk3NmRjY2ZkZmNkZjE5NTkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTc0OTAyLC03OS4zNzQ3MTQwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzBhNWNkYWEzNjhkNTQ4MjM5MmU2ZGQ2NDVhZDc5Y2E3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzZmYzNmZGUxODJlZjRkMWRiYjcwZmFjMDQzNDY2NzgxID0gJCgnPGRpdiBpZD0iaHRtbF82ZmMzZmRlMTgyZWY0ZDFkYmI3MGZhYzA0MzQ2Njc4MSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U2lsdmVyIEhpbGxzLCBZb3JrIE1pbGxzIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMGE1Y2RhYTM2OGQ1NDgyMzkyZTZkZDY0NWFkNzljYTcuc2V0Q29udGVudChodG1sXzZmYzNmZGUxODJlZjRkMWRiYjcwZmFjMDQzNDY2NzgxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzE3MGI2NzU4YzNhYTQ2Yjc5NzZkY2NmZGZjZGYxOTU5LmJpbmRQb3B1cChwb3B1cF8wYTVjZGFhMzY4ZDU0ODIzOTJlNmRkNjQ1YWQ3OWNhNyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMGU0MGNmM2E1YjE0MGUwYjQ4N2I0NmUwZDU0MTFhYyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MDExOTksLTc5LjQwODQ5Mjc5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTMyOWUxYmNiNTRkNDY1Y2E0YTNmODQ2ODQ3YjkzOGUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDNkMDAxNmEyZGMwNDg1YjhhOGIwMGY0YzJhMjRkNzEgPSAkKCc8ZGl2IGlkPSJodG1sX2QzZDAwMTZhMmRjMDQ4NWI4YThiMDBmNGMyYTI0ZDcxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaWxsb3dkYWxlIFNvdXRoIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTMyOWUxYmNiNTRkNDY1Y2E0YTNmODQ2ODQ3YjkzOGUuc2V0Q29udGVudChodG1sX2QzZDAwMTZhMmRjMDQ4NWI4YThiMDBmNGMyYTI0ZDcxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2IwZTQwY2YzYTViMTQwZTBiNDg3YjQ2ZTBkNTQxMWFjLmJpbmRQb3B1cChwb3B1cF9hMzI5ZTFiY2I1NGQ0NjVjYTRhM2Y4NDY4NDdiOTM4ZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83ZWJkNWRkNmUyZGU0NDU0ODkzMTM0MTNhNDE4MzdhMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1Mjc1ODI5OTk5OTk5NiwtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2I3YThmZDQ5MDdjNTRlYTNhNjBlN2QzZDdiMDA5MjhhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzY4ODZiMGI4MDRkMjQ2ZjQ4NzJhYjE0ZmZkNjQyNTc3ID0gJCgnPGRpdiBpZD0iaHRtbF82ODg2YjBiODA0ZDI0NmY0ODcyYWIxNGZmZDY0MjU3NyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+WW9yayBNaWxscyBXZXN0IENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjdhOGZkNDkwN2M1NGVhM2E2MGU3ZDNkN2IwMDkyOGEuc2V0Q29udGVudChodG1sXzY4ODZiMGI4MDRkMjQ2ZjQ4NzJhYjE0ZmZkNjQyNTc3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzdlYmQ1ZGQ2ZTJkZTQ0NTQ4OTMxMzQxM2E0MTgzN2ExLmJpbmRQb3B1cChwb3B1cF9iN2E4ZmQ0OTA3YzU0ZWEzYTYwZTdkM2Q3YjAwOTI4YSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMzhiYTMwMDRlNmE0MTUzYjhhMjU0YTIxYWQzM2QxZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4MjczNjQsLTc5LjQ0MjI1OTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8zMDY0MzQ0NGViZTY0MDA0OWYwM2Q0NjQwYWQ0NTU2NiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kMTEyNDlhNzMyMjE0ZThmOTFjY2QwZjMyOTU4ZjkwNCA9ICQoJzxkaXYgaWQ9Imh0bWxfZDExMjQ5YTczMjIxNGU4ZjkxY2NkMGYzMjk1OGY5MDQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldpbGxvd2RhbGUgV2VzdCBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzMwNjQzNDQ0ZWJlNjQwMDQ5ZjAzZDQ2NDBhZDQ1NTY2LnNldENvbnRlbnQoaHRtbF9kMTEyNDlhNzMyMjE0ZThmOTFjY2QwZjMyOTU4ZjkwNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hMzhiYTMwMDRlNmE0MTUzYjhhMjU0YTIxYWQzM2QxZS5iaW5kUG9wdXAocG9wdXBfMzA2NDM0NDRlYmU2NDAwNDlmMDNkNDY0MGFkNDU1NjYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTg5MmZlNGU3YjMxNGU0NjgzMjRkYWU2OTMzMTI2NzUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTMyNTg2LC03OS4zMjk2NTY1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjc4ZjhlZTA3YmMxNGNmNWI0Zjg2OTJhZTY2NWVkYmMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTIzMzdiYjdmM2YxNGYyNmJlOGY1MTNlNTFiNDIxYjcgPSAkKCc8ZGl2IGlkPSJodG1sX2UyMzM3YmI3ZjNmMTRmMjZiZThmNTEzZTUxYjQyMWI3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrd29vZHMgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iNzhmOGVlMDdiYzE0Y2Y1YjRmODY5MmFlNjY1ZWRiYy5zZXRDb250ZW50KGh0bWxfZTIzMzdiYjdmM2YxNGYyNmJlOGY1MTNlNTFiNDIxYjcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZTg5MmZlNGU3YjMxNGU0NjgzMjRkYWU2OTMzMTI2NzUuYmluZFBvcHVwKHBvcHVwX2I3OGY4ZWUwN2JjMTRjZjViNGY4NjkyYWU2NjVlZGJjKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzZlZjAxMzU0NmVhNzRiNjU5MWI0MTRiZGJmNWMyNjVlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzQ1OTA1Nzk5OTk5OTk2LC03OS4zNTIxODhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xMjMzMmEwNDI2NWY0OGE0OTA2MzI2YmU2MGNkYjlkOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83ZjkzOWFhNjdhMjg0ZmQ3ODA1OTYyNjc3NGRlMWUwYiA9ICQoJzxkaXYgaWQ9Imh0bWxfN2Y5MzlhYTY3YTI4NGZkNzgwNTk2MjY3NzRkZTFlMGIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvbiBNaWxscyBOb3J0aCBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzEyMzMyYTA0MjY1ZjQ4YTQ5MDYzMjZiZTYwY2RiOWQ5LnNldENvbnRlbnQoaHRtbF83ZjkzOWFhNjdhMjg0ZmQ3ODA1OTYyNjc3NGRlMWUwYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl82ZWYwMTM1NDZlYTc0YjY1OTFiNDE0YmRiZjVjMjY1ZS5iaW5kUG9wdXAocG9wdXBfMTIzMzJhMDQyNjVmNDhhNDkwNjMyNmJlNjBjZGI5ZDkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDgwNGI0NDhkOTcxNDY3ZmI1MjZhY2JhYzllNTExYWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjU4OTk3MDAwMDAwMSwtNzkuMzQwOTIzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmZhODc5MjFhYjFkNGM3ZThkOTk5YjRlNjdmNDcyNjcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODMwOTY3M2RkYWY1NGIyMGEwNGUwMTA3MjZjNWRjNGMgPSAkKCc8ZGl2IGlkPSJodG1sXzgzMDk2NzNkZGFmNTRiMjBhMDRlMDEwNzI2YzVkYzRjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5GbGVtaW5nZG9uIFBhcmssIERvbiBNaWxscyBTb3V0aCBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2JmYTg3OTIxYWIxZDRjN2U4ZDk5OWI0ZTY3ZjQ3MjY3LnNldENvbnRlbnQoaHRtbF84MzA5NjczZGRhZjU0YjIwYTA0ZTAxMDcyNmM1ZGM0Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8wODA0YjQ0OGQ5NzE0NjdmYjUyNmFjYmFjOWU1MTFhYi5iaW5kUG9wdXAocG9wdXBfYmZhODc5MjFhYjFkNGM3ZThkOTk5YjRlNjdmNDcyNjcpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNzBmYTBkNzE0M2Q4NDBhZjk4NTA1OWJmN2FkZmE0MmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTQzMjgzLC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMWU2MjcwYjkzNTQ2NDY2OWJkM2M3M2RkZWEzNmRkNjggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2RlYjVkOGVhZjc1NDRmODlkNzZkNjI0OTUxNDVkMDEgPSAkKCc8ZGl2IGlkPSJodG1sX2NkZWI1ZDhlYWY3NTQ0Zjg5ZDc2ZDYyNDk1MTQ1ZDAxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CYXRodXJzdCBNYW5vciwgRG93bnN2aWV3IE5vcnRoLCBXaWxzb24gSGVpZ2h0cyBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzFlNjI3MGI5MzU0NjQ2NjliZDNjNzNkZGVhMzZkZDY4LnNldENvbnRlbnQoaHRtbF9jZGViNWQ4ZWFmNzU0NGY4OWQ3NmQ2MjQ5NTE0NWQwMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl83MGZhMGQ3MTQzZDg0MGFmOTg1MDU5YmY3YWRmYTQyZC5iaW5kUG9wdXAocG9wdXBfMWU2MjcwYjkzNTQ2NDY2OWJkM2M3M2RkZWEzNmRkNjgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjJhY2Y3NjA4OGIyNGRhYWI5ZWNkZWZjNWIzNzIzOTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Njc5ODAzLC03OS40ODcyNjE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzMxYjI0MjU4MmE4NTQ2MjQ4NTRiNzhjY2Y5NDdmZWIwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2RhYTE0NDEyYzRiNzQ4N2M5ODVlYzliMWM2YjVlMTA2ID0gJCgnPGRpdiBpZD0iaHRtbF9kYWExNDQxMmM0Yjc0ODdjOTg1ZWM5YjFjNmI1ZTEwNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGh3b29kIFBhcmssIFlvcmsgVW5pdmVyc2l0eSBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzMxYjI0MjU4MmE4NTQ2MjQ4NTRiNzhjY2Y5NDdmZWIwLnNldENvbnRlbnQoaHRtbF9kYWExNDQxMmM0Yjc0ODdjOTg1ZWM5YjFjNmI1ZTEwNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iMmFjZjc2MDg4YjI0ZGFhYjllY2RlZmM1YjM3MjM5NS5iaW5kUG9wdXAocG9wdXBfMzFiMjQyNTgyYTg1NDYyNDg1NGI3OGNjZjk0N2ZlYjApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfM2MyNDgxYzI1ZWZlNGViOTlhMzE3ZWMxNDIxYjc4MDggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mzc0NzMyMDAwMDAwMDQsLTc5LjQ2NDc2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2U2MzkwNDNjZDFjNDJlZThmODFhZGMzOTBjNzhkODIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYWI3ZDVlN2JjZTI0NDNiMTk2ZmQ4NmZjMGI0YzYyODkgPSAkKCc8ZGl2IGlkPSJodG1sX2FiN2Q1ZTdiY2UyNDQzYjE5NmZkODZmYzBiNGM2Mjg5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DRkIgVG9yb250bywgRG93bnN2aWV3IEVhc3QgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zZTYzOTA0M2NkMWM0MmVlOGY4MWFkYzM5MGM3OGQ4Mi5zZXRDb250ZW50KGh0bWxfYWI3ZDVlN2JjZTI0NDNiMTk2ZmQ4NmZjMGI0YzYyODkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfM2MyNDgxYzI1ZWZlNGViOTlhMzE3ZWMxNDIxYjc4MDguYmluZFBvcHVwKHBvcHVwXzNlNjM5MDQzY2QxYzQyZWU4ZjgxYWRjMzkwYzc4ZDgyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2JmYWM0OTI4NDE2NjQxYTNiMzA5MmU3MjRjNGE1Yzc1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM5MDE0NiwtNzkuNTA2OTQzNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzMxNjc0ZDY3OWVmYTRjNzE5Nzk2NmRiMjhiNTEzMDQ3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2YzNWZiNTU0ZmVjMzQ1YzQ4Y2FjYmFjMDg2NGI5YWRjID0gJCgnPGRpdiBpZD0iaHRtbF9mMzVmYjU1NGZlYzM0NWM0OGNhY2JhYzA4NjRiOWFkYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG93bnN2aWV3IFdlc3QgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zMTY3NGQ2NzllZmE0YzcxOTc5NjZkYjI4YjUxMzA0Ny5zZXRDb250ZW50KGh0bWxfZjM1ZmI1NTRmZWMzNDVjNDhjYWNiYWMwODY0YjlhZGMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYmZhYzQ5Mjg0MTY2NDFhM2IzMDkyZTcyNGM0YTVjNzUuYmluZFBvcHVwKHBvcHVwXzMxNjc0ZDY3OWVmYTRjNzE5Nzk2NmRiMjhiNTEzMDQ3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RlNTdhM2ZkNjk5MTQ3YWU4ZThkZTZhZDViMjU1YjIyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI4NDk2NCwtNzkuNDk1Njk3NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mZjlkMzVmMGZjZGE0OTE3OTIyY2Y1MTUwNjM3ZDFiYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kYjBiMGFiZDdiMDU0OGM5ODRiYmUzNmNhNmM2NmVlYiA9ICQoJzxkaXYgaWQ9Imh0bWxfZGIwYjBhYmQ3YjA1NDhjOTg0YmJlMzZjYTZjNjZlZWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldyBDZW50cmFsIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmY5ZDM1ZjBmY2RhNDkxNzkyMmNmNTE1MDYzN2QxYmEuc2V0Q29udGVudChodG1sX2RiMGIwYWJkN2IwNTQ4Yzk4NGJiZTM2Y2E2YzY2ZWViKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2RlNTdhM2ZkNjk5MTQ3YWU4ZThkZTZhZDViMjU1YjIyLmJpbmRQb3B1cChwb3B1cF9mZjlkMzVmMGZjZGE0OTE3OTIyY2Y1MTUwNjM3ZDFiYSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMzY3ZWQ0YjlmYWU0ZDVlYWFkNDIzYmI4ZjBkOTMzMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2MTYzMTMsLTc5LjUyMDk5OTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOWI2YzkzNzA3YThmNGQ2NzgyYWE3ZDUwOWRkM2U4ZWMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMzM1NWE5YjhkMzEzNGEyYmE4NmZhYWUyYmM5NDUzNjMgPSAkKCc8ZGl2IGlkPSJodG1sXzMzNTVhOWI4ZDMxMzRhMmJhODZmYWFlMmJjOTQ1MzYzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3duc3ZpZXcgTm9ydGh3ZXN0IENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOWI2YzkzNzA3YThmNGQ2NzgyYWE3ZDUwOWRkM2U4ZWMuc2V0Q29udGVudChodG1sXzMzNTVhOWI4ZDMxMzRhMmJhODZmYWFlMmJjOTQ1MzYzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2IzNjdlZDRiOWZhZTRkNWVhYWQ0MjNiYjhmMGQ5MzMzLmJpbmRQb3B1cChwb3B1cF85YjZjOTM3MDdhOGY0ZDY3ODJhYTdkNTA5ZGQzZThlYyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yYzZlMjdhYTcxYTA0OGUzOGU0MGE5MmRkNTUyMjA2NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcyNTg4MjI5OTk5OTk5NSwtNzkuMzE1NTcxNTk5OTk5OThdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85Zjk0YmRjZmI4MTM0MjUwYjJmY2Q0ZWNiNDJkMGMxNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jZmQyYWMzMDBmMTY0NzM1YWRkNGRiN2U4MTE4MTZhOSA9ICQoJzxkaXYgaWQ9Imh0bWxfY2ZkMmFjMzAwZjE2NDczNWFkZDRkYjdlODExODE2YTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlZpY3RvcmlhIFZpbGxhZ2UgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85Zjk0YmRjZmI4MTM0MjUwYjJmY2Q0ZWNiNDJkMGMxNC5zZXRDb250ZW50KGh0bWxfY2ZkMmFjMzAwZjE2NDczNWFkZDRkYjdlODExODE2YTkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMmM2ZTI3YWE3MWEwNDhlMzhlNDBhOTJkZDU1MjIwNjcuYmluZFBvcHVwKHBvcHVwXzlmOTRiZGNmYjgxMzQyNTBiMmZjZDRlY2I0MmQwYzE0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzgyYzdmYzQxMmE5ZTRmZjJhY2I5MmUzYjMwNjcxZjgwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA2Mzk3MiwtNzkuMzA5OTM3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMzA4ODM5NzVkZGIxNGM3NDhmZDJlZmVkYmE4Y2Q3N2UgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTc3MmZmODM0OGFmNGQ2ZTg3NDg5MDk4MmFlMWRkMDkgPSAkKCc8ZGl2IGlkPSJodG1sX2E3NzJmZjgzNDhhZjRkNmU4NzQ4OTA5ODJhZTFkZDA5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb29kYmluZSBHYXJkZW5zLCBQYXJrdmlldyBIaWxsIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzA4ODM5NzVkZGIxNGM3NDhmZDJlZmVkYmE4Y2Q3N2Uuc2V0Q29udGVudChodG1sX2E3NzJmZjgzNDhhZjRkNmU4NzQ4OTA5ODJhZTFkZDA5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzgyYzdmYzQxMmE5ZTRmZjJhY2I5MmUzYjMwNjcxZjgwLmJpbmRQb3B1cChwb3B1cF8zMDg4Mzk3NWRkYjE0Yzc0OGZkMmVmZWRiYThjZDc3ZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80YTJjNmM5YWVjZDU0MTMzYmRiOGI1ZTYxNGVlMzM1MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5NTM0MzkwMDAwMDAwNSwtNzkuMzE4Mzg4N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQxMjE4OWUwNjMwMDQyN2RiYmVlNWJmMjI5NjgwNDg5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzVmZDE0NzY5NzQ2ZjQ1YTJiYzhmOGY5OGY1NDdjOWJkID0gJCgnPGRpdiBpZD0iaHRtbF81ZmQxNDc2OTc0NmY0NWEyYmM4ZjhmOThmNTQ3YzliZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V29vZGJpbmUgSGVpZ2h0cyBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQxMjE4OWUwNjMwMDQyN2RiYmVlNWJmMjI5NjgwNDg5LnNldENvbnRlbnQoaHRtbF81ZmQxNDc2OTc0NmY0NWEyYmM4ZjhmOThmNTQ3YzliZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80YTJjNmM5YWVjZDU0MTMzYmRiOGI1ZTYxNGVlMzM1Mi5iaW5kUG9wdXAocG9wdXBfNDEyMTg5ZTA2MzAwNDI3ZGJiZWU1YmYyMjk2ODA0ODkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDllM2I4OGFkYTI4NDMwNjk5ZjZkNWVjZWNiODliODggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NzYzNTczOTk5OTk5OSwtNzkuMjkzMDMxMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzdlMzFjMDRiZGY4NTRlYzhiZWY3NWI3OTYyNDU4ZmQ0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc3YTQzMGVkOTZmMzRmOWE4YzcwMTE2MTMzODM2YTA2ID0gJCgnPGRpdiBpZD0iaHRtbF83N2E0MzBlZDk2ZjM0ZjlhOGM3MDExNjEzMzgzNmEwNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEJlYWNoZXMgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83ZTMxYzA0YmRmODU0ZWM4YmVmNzViNzk2MjQ1OGZkNC5zZXRDb250ZW50KGh0bWxfNzdhNDMwZWQ5NmYzNGY5YThjNzAxMTYxMzM4MzZhMDYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMDllM2I4OGFkYTI4NDMwNjk5ZjZkNWVjZWNiODliODguYmluZFBvcHVwKHBvcHVwXzdlMzFjMDRiZGY4NTRlYzhiZWY3NWI3OTYyNDU4ZmQ0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NlOTJkMjU3N2QzNzRlZTk5ZjBhNzIyM2FjOTg0OGI5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA5MDYwNCwtNzkuMzYzNDUxN10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ZkYWMxMDNkMDk0NTRkNGM5NDM0NGUyMmI0NTllOTU4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzAyNTA2MmIyZTJiZTQxZTJhZWFhNzM0OTY3YjdlZTIwID0gJCgnPGRpdiBpZD0iaHRtbF8wMjUwNjJiMmUyYmU0MWUyYWVhYTczNDk2N2I3ZWUyMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TGVhc2lkZSBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2ZkYWMxMDNkMDk0NTRkNGM5NDM0NGUyMmI0NTllOTU4LnNldENvbnRlbnQoaHRtbF8wMjUwNjJiMmUyYmU0MWUyYWVhYTczNDk2N2I3ZWUyMCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jZTkyZDI1NzdkMzc0ZWU5OWYwYTcyMjNhYzk4NDhiOS5iaW5kUG9wdXAocG9wdXBfZmRhYzEwM2QwOTQ1NGQ0Yzk0MzQ0ZTIyYjQ1OWU5NTgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNWFmNDI3ZDRkZTVmNGZlZTkxMWI3ZTkyOTZiNTcyZDQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDUzNjg5LC03OS4zNDkzNzE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Q0NmU5YTU0YWQ4ZDQ4NjM5NjFkODQ0NWU5YjAzZmEwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzRhYmQxYWQ2NGZiZjQ2ODE4MTIzZGU3MDVhMjU5YTZkID0gJCgnPGRpdiBpZD0iaHRtbF80YWJkMWFkNjRmYmY0NjgxODEyM2RlNzA1YTI1OWE2ZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhvcm5jbGlmZmUgUGFyayBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2Q0NmU5YTU0YWQ4ZDQ4NjM5NjFkODQ0NWU5YjAzZmEwLnNldENvbnRlbnQoaHRtbF80YWJkMWFkNjRmYmY0NjgxODEyM2RlNzA1YTI1OWE2ZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81YWY0MjdkNGRlNWY0ZmVlOTExYjdlOTI5NmI1NzJkNC5iaW5kUG9wdXAocG9wdXBfZDQ2ZTlhNTRhZDhkNDg2Mzk2MWQ4NDQ1ZTliMDNmYTApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMmU2YTM1ODY3MmVkNDhkY2EyNmYxMzhkZTgwMWI5MmMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODUzNDcsLTc5LjMzODEwNjVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wM2NjN2Q0YmE5OGU0N2QxOTkzNTZiZGE1YzFmOTVmZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jNjFhNzFlMTBmNjc0ZTc2YmJhNWU2MjQ1Nzk4M2NlZCA9ICQoJzxkaXYgaWQ9Imh0bWxfYzYxYTcxZTEwZjY3NGU3NmJiYTVlNjI0NTc5ODNjZWQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVhc3QgVG9yb250byBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzAzY2M3ZDRiYTk4ZTQ3ZDE5OTM1NmJkYTVjMWY5NWZkLnNldENvbnRlbnQoaHRtbF9jNjFhNzFlMTBmNjc0ZTc2YmJhNWU2MjQ1Nzk4M2NlZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yZTZhMzU4NjcyZWQ0OGRjYTI2ZjEzOGRlODAxYjkyYy5iaW5kUG9wdXAocG9wdXBfMDNjYzdkNGJhOThlNDdkMTk5MzU2YmRhNWMxZjk1ZmQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjE5MjQxYmY2NjU1NDA4NDgxOWEwMGMyNDEyMzNiZTIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Nzk1NTcxLC03OS4zNTIxODhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAib3JhbmdlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAib3JhbmdlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ViNWQwOGQ1MzRjMDQ0MWM5MjYwMzUxN2YwMWE5NTI4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2E3YjJmNjA3N2YyMTQzZjM4YTZiZTBjZDk0NThkZTJkID0gJCgnPGRpdiBpZD0iaHRtbF9hN2IyZjYwNzdmMjE0M2YzOGE2YmUwY2Q5NDU4ZGUyZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIERhbmZvcnRoIFdlc3QsIFJpdmVyZGFsZSBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2ViNWQwOGQ1MzRjMDQ0MWM5MjYwMzUxN2YwMWE5NTI4LnNldENvbnRlbnQoaHRtbF9hN2IyZjYwNzdmMjE0M2YzOGE2YmUwY2Q5NDU4ZGUyZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iMTkyNDFiZjY2NTU0MDg0ODE5YTAwYzI0MTIzM2JlMi5iaW5kUG9wdXAocG9wdXBfZWI1ZDA4ZDUzNGMwNDQxYzkyNjAzNTE3ZjAxYTk1MjgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjc5MjkyNTY0MTljNGEzMGFjYzc5MGY2NTJjMjJmYjYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Njg5OTg1LC03OS4zMTU1NzE1OTk5OTk5OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzE1ODYzZDUxZTM1MjQ1YTNhZmY1YWQ2ZjdmOGU0ZjRhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2NiMGIxZGM4ZTMyMzRjMDM5ZjE4ZDM0YzZlZTg3ZmRlID0gJCgnPGRpdiBpZD0iaHRtbF9jYjBiMWRjOGUzMjM0YzAzOWYxOGQzNGM2ZWU4N2ZkZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEJlYWNoZXMgV2VzdCwgSW5kaWEgQmF6YWFyIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMTU4NjNkNTFlMzUyNDVhM2FmZjVhZDZmN2Y4ZTRmNGEuc2V0Q29udGVudChodG1sX2NiMGIxZGM4ZTMyMzRjMDM5ZjE4ZDM0YzZlZTg3ZmRlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2I3OTI5MjU2NDE5YzRhMzBhY2M3OTBmNjUyYzIyZmI2LmJpbmRQb3B1cChwb3B1cF8xNTg2M2Q1MWUzNTI0NWEzYWZmNWFkNmY3ZjhlNGY0YSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84YTk3MWM1NDUyZjQ0YzViOTcxYTg1NWM1ZWI4ZGU5NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1OTUyNTUsLTc5LjM0MDkyM10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2ZjYjJjMTU5YzVhNDBhYWFiMjA3ZGM5MzFiYjkzODAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZWE5MzNlMmVhNWNmNDA2Yzg2YmVhYTA5NDE1Yjc3YjEgPSAkKCc8ZGl2IGlkPSJodG1sX2VhOTMzZTJlYTVjZjQwNmM4NmJlYWEwOTQxNWI3N2IxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdHVkaW8gRGlzdHJpY3QgQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zZmNiMmMxNTljNWE0MGFhYWIyMDdkYzkzMWJiOTM4MC5zZXRDb250ZW50KGh0bWxfZWE5MzNlMmVhNWNmNDA2Yzg2YmVhYTA5NDE1Yjc3YjEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOGE5NzFjNTQ1MmY0NGM1Yjk3MWE4NTVjNWViOGRlOTYuYmluZFBvcHVwKHBvcHVwXzNmY2IyYzE1OWM1YTQwYWFhYjIwN2RjOTMxYmI5MzgwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2QzMTFlZTQ4ZjgwZDRhNjViYTA3MDBhMjA4MTUxZDVmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI4MDIwNSwtNzkuMzg4NzkwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2UzZmNkZjU4ZjA2ODRkNDg4OTM3OTc3ZjllNDE0NzA0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzI4MTRiN2JlZGU2ZTQwNDk4Yzc5OTFjNzcyM2ZmZWUxID0gJCgnPGRpdiBpZD0iaHRtbF8yODE0YjdiZWRlNmU0MDQ5OGM3OTkxYzc3MjNmZmVlMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TGF3cmVuY2UgUGFyayBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2UzZmNkZjU4ZjA2ODRkNDg4OTM3OTc3ZjllNDE0NzA0LnNldENvbnRlbnQoaHRtbF8yODE0YjdiZWRlNmU0MDQ5OGM3OTkxYzc3MjNmZmVlMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kMzExZWU0OGY4MGQ0YTY1YmEwNzAwYTIwODE1MWQ1Zi5iaW5kUG9wdXAocG9wdXBfZTNmY2RmNThmMDY4NGQ0ODg5Mzc5NzdmOWU0MTQ3MDQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNWRlNTM2YTM3ZjIwNDQ5OTlmNTRiNGFjYmMyMjUwZjkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTI3NTExLC03OS4zOTAxOTc1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMWRlMGY3YTA2MjYxNDMwNzljYWJkMTQ5ZWE3NTk2NTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmMzNDNhOTQ3NmRiNDhiYzhmMzJiMTQ1Nzk2MmE0ZDcgPSAkKCc8ZGl2IGlkPSJodG1sXzJjMzQzYTk0NzZkYjQ4YmM4ZjMyYjE0NTc5NjJhNGQ3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EYXZpc3ZpbGxlIE5vcnRoIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMWRlMGY3YTA2MjYxNDMwNzljYWJkMTQ5ZWE3NTk2NTIuc2V0Q29udGVudChodG1sXzJjMzQzYTk0NzZkYjQ4YmM4ZjMyYjE0NTc5NjJhNGQ3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzVkZTUzNmEzN2YyMDQ0OTk5ZjU0YjRhY2JjMjI1MGY5LmJpbmRQb3B1cChwb3B1cF8xZGUwZjdhMDYyNjE0MzA3OWNhYmQxNDllYTc1OTY1Mik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zZTU0NjRkMjU3MTg0Mjk1ODUwOTIxOGRkNWE1ODdmZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxNTM4MzQsLTc5LjQwNTY3ODQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjAzOWYzM2Q1ZmE4NDRhNjkwOWYzYmM5NmUwNmE5MDYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTAyNDQ5MGQ5YjVhNGRmMmI0NjQ5N2M2OWJhZjYyNGQgPSAkKCc8ZGl2IGlkPSJodG1sX2EwMjQ0OTBkOWI1YTRkZjJiNDY0OTdjNjliYWY2MjRkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aCBUb3JvbnRvIFdlc3QgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yMDM5ZjMzZDVmYTg0NGE2OTA5ZjNiYzk2ZTA2YTkwNi5zZXRDb250ZW50KGh0bWxfYTAyNDQ5MGQ5YjVhNGRmMmI0NjQ5N2M2OWJhZjYyNGQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfM2U1NDY0ZDI1NzE4NDI5NTg1MDkyMThkZDVhNTg3ZmUuYmluZFBvcHVwKHBvcHVwXzIwMzlmMzNkNWZhODQ0YTY5MDlmM2JjOTZlMDZhOTA2KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzE2YTNmOTE5ZThkMTQzOWY4ZWFmZGJmZDE5ZjY3NjExID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA0MzI0NCwtNzkuMzg4NzkwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfN2M4ODY3MjRhZjNlNGYxMTg5ZTY0NDliMzZlYTdiZGIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNzNlZWEzMWIwMzEwNGZkMzk3MjI2ZTVjMjEyOTdlMDYgPSAkKCc8ZGl2IGlkPSJodG1sXzczZWVhMzFiMDMxMDRmZDM5NzIyNmU1YzIxMjk3ZTA2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EYXZpc3ZpbGxlIENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2M4ODY3MjRhZjNlNGYxMTg5ZTY0NDliMzZlYTdiZGIuc2V0Q29udGVudChodG1sXzczZWVhMzFiMDMxMDRmZDM5NzIyNmU1YzIxMjk3ZTA2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzE2YTNmOTE5ZThkMTQzOWY4ZWFmZGJmZDE5ZjY3NjExLmJpbmRQb3B1cChwb3B1cF83Yzg4NjcyNGFmM2U0ZjExODllNjQ0OWIzNmVhN2JkYik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zZWJkMDU2ODdjYzU0MzRkYWZhMThjMmM1ODhlMDZmNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4OTU3NDMsLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODc1ZTgxOTE4YmJhNGFmYWFlNjRmZDQ1MzBmODYzOGEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZWE3ZDU5Y2E3NmM2NGM3Y2FkMjcxZTFhMTkwYTY1YjkgPSAkKCc8ZGl2IGlkPSJodG1sX2VhN2Q1OWNhNzZjNjRjN2NhZDI3MWUxYTE5MGE2NWI5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Nb29yZSBQYXJrLCBTdW1tZXJoaWxsIEVhc3QgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84NzVlODE5MThiYmE0YWZhYWU2NGZkNDUzMGY4NjM4YS5zZXRDb250ZW50KGh0bWxfZWE3ZDU5Y2E3NmM2NGM3Y2FkMjcxZTFhMTkwYTY1YjkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfM2ViZDA1Njg3Y2M1NDM0ZGFmYTE4YzJjNTg4ZTA2ZjcuYmluZFBvcHVwKHBvcHVwXzg3NWU4MTkxOGJiYTRhZmFhZTY0ZmQ0NTMwZjg2MzhhKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q5ZDNlNjMyN2FiMDQ3OGE4ZmNjNWY4Y2VmZDU0YzgzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg2NDEyMjk5OTk5OTksLTc5LjQwMDA0OTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81MDg5YWUxZGZmYzE0ZTM0OGJjY2NkNDE2ZGI0NGE3ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jNjU4MDk4YTNhNzQ0ZjI2YWNkZjY0OWNiYzk1OTI5YSA9ICQoJzxkaXYgaWQ9Imh0bWxfYzY1ODA5OGEzYTc0NGYyNmFjZGY2NDljYmM5NTkyOWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRlZXIgUGFyaywgRm9yZXN0IEhpbGwgU0UsIFJhdGhuZWxseSwgU291dGggSGlsbCwgU3VtbWVyaGlsbCBXZXN0IENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTA4OWFlMWRmZmMxNGUzNDhiY2NjZDQxNmRiNDRhN2Yuc2V0Q29udGVudChodG1sX2M2NTgwOThhM2E3NDRmMjZhY2RmNjQ5Y2JjOTU5MjlhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2Q5ZDNlNjMyN2FiMDQ3OGE4ZmNjNWY4Y2VmZDU0YzgzLmJpbmRQb3B1cChwb3B1cF81MDg5YWUxZGZmYzE0ZTM0OGJjY2NkNDE2ZGI0NGE3Zik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zOWNlMGMxYThiYTQ0YWEwYTg5ZmJmNWE4OTY2NzA5ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3OTU2MjYsLTc5LjM3NzUyOTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjQwOTVjYjNkOThkNDc1NmEwNjE1NTc5NWM2YTI3NzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDM4ZThkNWMxNWRkNDc4MmFiMzEwZmEzNGU4N2EwM2MgPSAkKCc8ZGl2IGlkPSJodG1sXzQzOGU4ZDVjMTVkZDQ3ODJhYjMxMGZhMzRlODdhMDNjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3NlZGFsZSBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzY0MDk1Y2IzZDk4ZDQ3NTZhMDYxNTU3OTVjNmEyNzcyLnNldENvbnRlbnQoaHRtbF80MzhlOGQ1YzE1ZGQ0NzgyYWIzMTBmYTM0ZTg3YTAzYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8zOWNlMGMxYThiYTQ0YWEwYTg5ZmJmNWE4OTY2NzA5ZS5iaW5kUG9wdXAocG9wdXBfNjQwOTVjYjNkOThkNDc1NmEwNjE1NTc5NWM2YTI3NzIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMGFjMjE3Njk3ODZlNGQ2ODhhMDk4MDcwYWVhOGI1OGMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Njc5NjcsLTc5LjM2NzY3NTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAib3JhbmdlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAib3JhbmdlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc4NGFiOGYwOTU2MDRjNjY4ZDBmYjY3ODEwYzEyMTRmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2E1MjI4MDRkMmU0NjRhNGFhZDNmN2Q0N2RlNWEzMzA2ID0gJCgnPGRpdiBpZD0iaHRtbF9hNTIyODA0ZDJlNDY0YTRhYWQzZjdkNDdkZTVhMzMwNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2FiYmFnZXRvd24sIFN0LiBKYW1lcyBUb3duIENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzg0YWI4ZjA5NTYwNGM2NjhkMGZiNjc4MTBjMTIxNGYuc2V0Q29udGVudChodG1sX2E1MjI4MDRkMmU0NjRhNGFhZDNmN2Q0N2RlNWEzMzA2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzBhYzIxNzY5Nzg2ZTRkNjg4YTA5ODA3MGFlYThiNThjLmJpbmRQb3B1cChwb3B1cF83ODRhYjhmMDk1NjA0YzY2OGQwZmI2NzgxMGMxMjE0Zik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zYjljNjg2YTJlNzE0MzRlYTlmMjQ4ZWJlNzE4ZGE2ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2NTg1OTksLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIm9yYW5nZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIm9yYW5nZSIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yMzMyY2I0Y2NiMmI0ODBiYTQzYjBlM2FlYTBiNmJmZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iOWM4NzRkMzUyMDc0OGZiYWNlYjg1MmRiODFmN2U2NSA9ICQoJzxkaXYgaWQ9Imh0bWxfYjljODc0ZDM1MjA3NDhmYmFjZWI4NTJkYjgxZjdlNjUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNodXJjaCBhbmQgV2VsbGVzbGV5IENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMjMzMmNiNGNjYjJiNDgwYmE0M2IwZTNhZWEwYjZiZmYuc2V0Q29udGVudChodG1sX2I5Yzg3NGQzNTIwNzQ4ZmJhY2ViODUyZGI4MWY3ZTY1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzNiOWM2ODZhMmU3MTQzNGVhOWYyNDhlYmU3MThkYTZlLmJpbmRQb3B1cChwb3B1cF8yMzMyY2I0Y2NiMmI0ODBiYTQzYjBlM2FlYTBiNmJmZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hZWNhM2QyNDA1NTQ0Y2Y0YjA4Yjg3MjdiMGNkM2Q5YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1NDI1OTksLTc5LjM2MDYzNTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAib3JhbmdlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAib3JhbmdlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2M0NjI4MDIwMzhhMTQ0YjNiZTAwYTAxMDZlMmZkMGU5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2RmNzlmNzdlM2M1YjQ5MzBhNjIwZDM0NDVhZjAyNzZlID0gJCgnPGRpdiBpZD0iaHRtbF9kZjc5Zjc3ZTNjNWI0OTMwYTYyMGQzNDQ1YWYwMjc2ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGFyYm91cmZyb250LCBSZWdlbnQgUGFyayBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M0NjI4MDIwMzhhMTQ0YjNiZTAwYTAxMDZlMmZkMGU5LnNldENvbnRlbnQoaHRtbF9kZjc5Zjc3ZTNjNWI0OTMwYTYyMGQzNDQ1YWYwMjc2ZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hZWNhM2QyNDA1NTQ0Y2Y0YjA4Yjg3MjdiMGNkM2Q5Yi5iaW5kUG9wdXAocG9wdXBfYzQ2MjgwMjAzOGExNDRiM2JlMDBhMDEwNmUyZmQwZTkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNGRjZThkMDc4ZGZmNDgwYWI0Y2NlNGRlZmU5NWE0MGEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTcxNjE4LC03OS4zNzg5MzcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMzFmZDNiNGY3NmFmNDQ5ODhmNGMwZDg4OGFhZDBkZDkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOWM4MzY4NzRhZWUzNGNmN2EwOWZjNGI3MDFkNmQ2ZjkgPSAkKCc8ZGl2IGlkPSJodG1sXzljODM2ODc0YWVlMzRjZjdhMDlmYzRiNzAxZDZkNmY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SeWVyc29uLCBHYXJkZW4gRGlzdHJpY3QgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zMWZkM2I0Zjc2YWY0NDk4OGY0YzBkODg4YWFkMGRkOS5zZXRDb250ZW50KGh0bWxfOWM4MzY4NzRhZWUzNGNmN2EwOWZjNGI3MDFkNmQ2ZjkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNGRjZThkMDc4ZGZmNDgwYWI0Y2NlNGRlZmU5NWE0MGEuYmluZFBvcHVwKHBvcHVwXzMxZmQzYjRmNzZhZjQ0OTg4ZjRjMGQ4ODhhYWQwZGQ5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I3YjFiYWRmMjVjMDRiN2VhZTJmNGJkMDVkNWE4YzdjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUxNDkzOSwtNzkuMzc1NDE3OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNWQxNjlmYjY4YjdjNDA0NGEwODUyZDI3MWVmZTI2YTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGMyZDk5NjcwZDZjNDIwOTg1MzZlMzdiZmQ5ZTcyNzggPSAkKCc8ZGl2IGlkPSJodG1sXzRjMmQ5OTY3MGQ2YzQyMDk4NTM2ZTM3YmZkOWU3Mjc4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdC4gSmFtZXMgVG93biBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzVkMTY5ZmI2OGI3YzQwNDRhMDg1MmQyNzFlZmUyNmExLnNldENvbnRlbnQoaHRtbF80YzJkOTk2NzBkNmM0MjA5ODUzNmUzN2JmZDllNzI3OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iN2IxYmFkZjI1YzA0YjdlYWUyZjRiZDA1ZDVhOGM3Yy5iaW5kUG9wdXAocG9wdXBfNWQxNjlmYjY4YjdjNDA0NGEwODUyZDI3MWVmZTI2YTEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfODA4OTA1MTAzYmUzNDMyZGE0ODgyZjFlZjU1MmMyYjkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDQ3NzA3OTk5OTk5OTYsLTc5LjM3MzMwNjRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzMwZDQyYjQxNGJmZTQ1MTRhYmM2ZWU5YjMxNDkwNWYwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQ3NGYyN2IxMGY5NDQwZThhOTAzOTFkNDY3YWY1ZWJkID0gJCgnPGRpdiBpZD0iaHRtbF80NzRmMjdiMTBmOTQ0MGU4YTkwMzkxZDQ2N2FmNWViZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmVyY3p5IFBhcmsgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zMGQ0MmI0MTRiZmU0NTE0YWJjNmVlOWIzMTQ5MDVmMC5zZXRDb250ZW50KGh0bWxfNDc0ZjI3YjEwZjk0NDBlOGE5MDM5MWQ0NjdhZjVlYmQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfODA4OTA1MTAzYmUzNDMyZGE0ODgyZjFlZjU1MmMyYjkuYmluZFBvcHVwKHBvcHVwXzMwZDQyYjQxNGJmZTQ1MTRhYmM2ZWU5YjMxNDkwNWYwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzMzNmY0NGIyNTVjOTQwNmRhYjgyODgwOGY5ZGJkMTQ3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjU3OTUyNCwtNzkuMzg3MzgyNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJ5ZWxsb3ciLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJ5ZWxsb3ciLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZWQ4MzRmYjc1MGY0NGM3ZDkxMmNjMGU1NDQxM2Q0Y2YgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNzEyYTNiNmQxNmFmNDhjMDg2MjNmMjgzNTUyNDQxNTIgPSAkKCc8ZGl2IGlkPSJodG1sXzcxMmEzYjZkMTZhZjQ4YzA4NjIzZjI4MzU1MjQ0MTUyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DZW50cmFsIEJheSBTdHJlZXQgQ2x1c3RlciAzPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lZDgzNGZiNzUwZjQ0YzdkOTEyY2MwZTU0NDEzZDRjZi5zZXRDb250ZW50KGh0bWxfNzEyYTNiNmQxNmFmNDhjMDg2MjNmMjgzNTUyNDQxNTIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMzM2ZjQ0YjI1NWM5NDA2ZGFiODI4ODA4ZjlkYmQxNDcuYmluZFBvcHVwKHBvcHVwX2VkODM0ZmI3NTBmNDRjN2Q5MTJjYzBlNTQ0MTNkNGNmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2IyZGEzZmVjZmZjMDRkODJhODE0OWYzYzAzMGQ2Y2I1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUwNTcxMjAwMDAwMDEsLTc5LjM4NDU2NzVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTJiZjNmM2IzNzdiNDJjNDhlNmM3NWNiYTk3NDk5YmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTg3Njc5MzRjNTc4NGNmZGJhMzg5ZjhlOThkMTI1NGQgPSAkKCc8ZGl2IGlkPSJodG1sXzE4NzY3OTM0YzU3ODRjZmRiYTM4OWY4ZTk4ZDEyNTRkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BZGVsYWlkZSwgS2luZywgUmljaG1vbmQgQ2x1c3RlciAyPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hMmJmM2YzYjM3N2I0MmM0OGU2Yzc1Y2JhOTc0OTliZS5zZXRDb250ZW50KGh0bWxfMTg3Njc5MzRjNTc4NGNmZGJhMzg5ZjhlOThkMTI1NGQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjJkYTNmZWNmZmMwNGQ4MmE4MTQ5ZjNjMDMwZDZjYjUuYmluZFBvcHVwKHBvcHVwX2EyYmYzZjNiMzc3YjQyYzQ4ZTZjNzVjYmE5NzQ5OWJlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q1NjU4NTk5NzQ4MzQxZDdhMzE1ZTY0Y2U0YzI0Y2JlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQwODE1NywtNzkuMzgxNzUyMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAieWVsbG93IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAieWVsbG93IiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc5YzEwNmQzZjMzNDQwMGZiNGE2MmQwNzM1YmRkZWE0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQxYmJlYjY1NmY4ZDRjZDRhMTZiNzJmM2NkZGEwYjMzID0gJCgnPGRpdiBpZD0iaHRtbF80MWJiZWI2NTZmOGQ0Y2Q0YTE2YjcyZjNjZGRhMGIzMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGFyYm91cmZyb250IEVhc3QsIFRvcm9udG8gSXNsYW5kcywgVW5pb24gU3RhdGlvbiBDbHVzdGVyIDM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc5YzEwNmQzZjMzNDQwMGZiNGE2MmQwNzM1YmRkZWE0LnNldENvbnRlbnQoaHRtbF80MWJiZWI2NTZmOGQ0Y2Q0YTE2YjcyZjNjZGRhMGIzMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kNTY1ODU5OTc0ODM0MWQ3YTMxNWU2NGNlNGMyNGNiZS5iaW5kUG9wdXAocG9wdXBfNzljMTA2ZDNmMzM0NDAwZmI0YTYyZDA3MzViZGRlYTQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMzk2YmU4YjY1MmYyNGZiMjgzYzVlYTJjNjUxMzVmZmUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDcxNzY4LC03OS4zODE1NzY0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jNmM5ZGIzZWE5ZTI0NWZiOGQxOTM5MGQzNWRhYmNkNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81MTcyZWNmMzMxYjI0YzM1YTY5NTllNjk4MGQwNTFkMSA9ICQoJzxkaXYgaWQ9Imh0bWxfNTE3MmVjZjMzMWIyNGMzNWE2OTU5ZTY5ODBkMDUxZDEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRlc2lnbiBFeGNoYW5nZSwgVG9yb250byBEb21pbmlvbiBDZW50cmUgQ2x1c3RlciAyPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jNmM5ZGIzZWE5ZTI0NWZiOGQxOTM5MGQzNWRhYmNkNS5zZXRDb250ZW50KGh0bWxfNTE3MmVjZjMzMWIyNGMzNWE2OTU5ZTY5ODBkMDUxZDEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMzk2YmU4YjY1MmYyNGZiMjgzYzVlYTJjNjUxMzVmZmUuYmluZFBvcHVwKHBvcHVwX2M2YzlkYjNlYTllMjQ1ZmI4ZDE5MzkwZDM1ZGFiY2Q1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzE4MDY5ZDFlYzFjZTQxNzI4MDJhZjMyYTViOThjMzljID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4MTk4NSwtNzkuMzc5ODE2OTAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImJsdWUiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2Q5Y2QwMGMxMWM4NGQ5MmE2ZTU3ZmFiMThiYjc3YTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2I3YzcyY2FhMmRmNDQ4NWEyNmZjNDNjMjJiYzQ3MjUgPSAkKCc8ZGl2IGlkPSJodG1sX2NiN2M3MmNhYTJkZjQ0ODVhMjZmYzQzYzIyYmM0NzI1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db21tZXJjZSBDb3VydCwgVmljdG9yaWEgSG90ZWwgQ2x1c3RlciAyPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zZDljZDAwYzExYzg0ZDkyYTZlNTdmYWIxOGJiNzdhMC5zZXRDb250ZW50KGh0bWxfY2I3YzcyY2FhMmRmNDQ4NWEyNmZjNDNjMjJiYzQ3MjUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMTgwNjlkMWVjMWNlNDE3MjgwMmFmMzJhNWI5OGMzOWMuYmluZFBvcHVwKHBvcHVwXzNkOWNkMDBjMTFjODRkOTJhNmU1N2ZhYjE4YmI3N2EwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2YwNTM5ZDdkZjJiNTQ4ZjQ5ODJmZWU2N2JmZjk1NzQ5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzMzMjgyNSwtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2JlMTNhMTIzZGY4ODQ0YmZhMDcyMzk5NDA5OGI2ZGZjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzZhZDFiZjE2MWVkNjQ0MTJhNTJiNjcxNTE0Zjc2MzM0ID0gJCgnPGRpdiBpZD0iaHRtbF82YWQxYmYxNjFlZDY0NDEyYTUyYjY3MTUxNGY3NjMzNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmVkZm9yZCBQYXJrLCBMYXdyZW5jZSBNYW5vciBFYXN0IENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYmUxM2ExMjNkZjg4NDRiZmEwNzIzOTk0MDk4YjZkZmMuc2V0Q29udGVudChodG1sXzZhZDFiZjE2MWVkNjQ0MTJhNTJiNjcxNTE0Zjc2MzM0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2YwNTM5ZDdkZjJiNTQ4ZjQ5ODJmZWU2N2JmZjk1NzQ5LmJpbmRQb3B1cChwb3B1cF9iZTEzYTEyM2RmODg0NGJmYTA3MjM5OTQwOThiNmRmYyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83YzlmZDdhYmQwZTY0ZDQ3YWQ4MTk4MmRlNzk5NTdlYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMTY5NDgsLTc5LjQxNjkzNTU5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWU0MWY1MmU5NDExNDNhNmJhYTcwYTIxY2M4NzU1OTYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOGVhODUwNWE4NDZjNDlmNWI4MDA2NWJiN2Y3NjRmMjYgPSAkKCc8ZGl2IGlkPSJodG1sXzhlYTg1MDVhODQ2YzQ5ZjViODAwNjViYjdmNzY0ZjI2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3NlbGF3biBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FlNDFmNTJlOTQxMTQzYTZiYWE3MGEyMWNjODc1NTk2LnNldENvbnRlbnQoaHRtbF84ZWE4NTA1YTg0NmM0OWY1YjgwMDY1YmI3Zjc2NGYyNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl83YzlmZDdhYmQwZTY0ZDQ3YWQ4MTk4MmRlNzk5NTdlYi5iaW5kUG9wdXAocG9wdXBfYWU0MWY1MmU5NDExNDNhNmJhYTcwYTIxY2M4NzU1OTYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTZlMTk3Yzc4MmVkNGRiZmI5Y2IzN2ZlMWNiMTNhOWYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTY5NDc2LC03OS40MTEzMDcyMDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzFjNzExMGNiZDQ3OTQ0MjJiYTJlZWQ1MzVkMTA5MTRmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2UwYjNiMGVmZmUwZjRjZGM5N2VjNWRhNWFmODIwNDk4ID0gJCgnPGRpdiBpZD0iaHRtbF9lMGIzYjBlZmZlMGY0Y2RjOTdlYzVkYTVhZjgyMDQ5OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Rm9yZXN0IEhpbGwgTm9ydGgsIEZvcmVzdCBIaWxsIFdlc3QgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xYzcxMTBjYmQ0Nzk0NDIyYmEyZWVkNTM1ZDEwOTE0Zi5zZXRDb250ZW50KGh0bWxfZTBiM2IwZWZmZTBmNGNkYzk3ZWM1ZGE1YWY4MjA0OTgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZTZlMTk3Yzc4MmVkNGRiZmI5Y2IzN2ZlMWNiMTNhOWYuYmluZFBvcHVwKHBvcHVwXzFjNzExMGNiZDQ3OTQ0MjJiYTJlZWQ1MzVkMTA5MTRmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NjMjg3ZmFlYjM2ODQ0Mzg4YmY4MTY5NjRmM2RhMzBiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjcyNzA5NywtNzkuNDA1Njc4NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAib3JhbmdlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAib3JhbmdlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2U1Yzg1OGNhMzJlMjQ1YzZhNTdlNmQxODNlYjY1MGM1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzllNDRiYWY1NjBlYzRmODQ4MTg3NTRiN2ViZmM2NDE4ID0gJCgnPGRpdiBpZD0iaHRtbF85ZTQ0YmFmNTYwZWM0Zjg0ODE4NzU0YjdlYmZjNjQxOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEFubmV4LCBOb3J0aCBNaWR0b3duLCBZb3JrdmlsbGUgQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lNWM4NThjYTMyZTI0NWM2YTU3ZTZkMTgzZWI2NTBjNS5zZXRDb250ZW50KGh0bWxfOWU0NGJhZjU2MGVjNGY4NDgxODc1NGI3ZWJmYzY0MTgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfY2MyODdmYWViMzY4NDQzODhiZjgxNjk2NGYzZGEzMGIuYmluZFBvcHVwKHBvcHVwX2U1Yzg1OGNhMzJlMjQ1YzZhNTdlNmQxODNlYjY1MGM1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzcyNWIxMTdmNjRhYTQ1YzViOGVlMjJmYTIwZjcwYmVhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYyNjk1NiwtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzA1NDg3OTc0ZDcxNDA2MDgzNjQ2YWQ4YjE1Zjc1N2UgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTI3N2ExMTczMmQxNGY0NGI5MzA3Y2RjMzQ5NjQwZTMgPSAkKCc8ZGl2IGlkPSJodG1sX2UyNzdhMTE3MzJkMTRmNDRiOTMwN2NkYzM0OTY0MGUzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IYXJib3JkLCBVbml2ZXJzaXR5IG9mIFRvcm9udG8gQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83MDU0ODc5NzRkNzE0MDYwODM2NDZhZDhiMTVmNzU3ZS5zZXRDb250ZW50KGh0bWxfZTI3N2ExMTczMmQxNGY0NGI5MzA3Y2RjMzQ5NjQwZTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzI1YjExN2Y2NGFhNDVjNWI4ZWUyMmZhMjBmNzBiZWEuYmluZFBvcHVwKHBvcHVwXzcwNTQ4Nzk3NGQ3MTQwNjA4MzY0NmFkOGIxNWY3NTdlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I2ODhlMDM1MmY5ZTQ1OGY5NzRmZGJhYzhiODdkNjJlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUzMjA1NywtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNmQxM2FiYzg0MGEyNGZhYmJlZDI0YWI0NDJkOGFlM2MgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmZhYmNhZDYzZWJhNGU3M2E4OWQxMzVkNDQ4YTQwMDQgPSAkKCc8ZGl2IGlkPSJodG1sXzJmYWJjYWQ2M2ViYTRlNzNhODlkMTM1ZDQ0OGE0MDA0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DaGluYXRvd24sIEdyYW5nZSBQYXJrLCBLZW5zaW5ndG9uIE1hcmtldCBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzZkMTNhYmM4NDBhMjRmYWJiZWQyNGFiNDQyZDhhZTNjLnNldENvbnRlbnQoaHRtbF8yZmFiY2FkNjNlYmE0ZTczYTg5ZDEzNWQ0NDhhNDAwNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iNjg4ZTAzNTJmOWU0NThmOTc0ZmRiYWM4Yjg3ZDYyZS5iaW5kUG9wdXAocG9wdXBfNmQxM2FiYzg0MGEyNGZhYmJlZDI0YWI0NDJkOGFlM2MpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGM4MGY1ZTQ4ZGM2NGE1MmIzOWE1MjkyN2ZlZjg2MGEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Mjg5NDY3LC03OS4zOTQ0MTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODMyNTZhY2FkZjBjNDVmZmEwZGZkNjI2N2YwZmYxMmYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZGY4MjE0YzExODdhNDZhNGIwN2I2ZThlMGUzODBmMzYgPSAkKCc8ZGl2IGlkPSJodG1sX2RmODIxNGMxMTg3YTQ2YTRiMDdiNmU4ZTBlMzgwZjM2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DTiBUb3dlciwgQmF0aHVyc3QgUXVheSwgSXNsYW5kIGFpcnBvcnQsIEhhcmJvdXJmcm9udCBXZXN0LCBLaW5nIGFuZCBTcGFkaW5hLCBSYWlsd2F5IExhbmRzLCBTb3V0aCBOaWFnYXJhIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODMyNTZhY2FkZjBjNDVmZmEwZGZkNjI2N2YwZmYxMmYuc2V0Q29udGVudChodG1sX2RmODIxNGMxMTg3YTQ2YTRiMDdiNmU4ZTBlMzgwZjM2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2RjODBmNWU0OGRjNjRhNTJiMzlhNTI5MjdmZWY4NjBhLmJpbmRQb3B1cChwb3B1cF84MzI1NmFjYWRmMGM0NWZmYTBkZmQ2MjY3ZjBmZjEyZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zMGJmYWQ5YmM2NWY0Yzg5YTdlNDJlNTM5NDI3YzY1ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NjQzNTIsLTc5LjM3NDg0NTk5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kNGViZjA1NTU5Njc0NDNjYTE1ZjJjMTViMWY5MjYwMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jNTMyZmMwMTYzNWY0OTI5YTM5MmQ1YzFlMjgxNWI4YyA9ICQoJzxkaXYgaWQ9Imh0bWxfYzUzMmZjMDE2MzVmNDkyOWEzOTJkNWMxZTI4MTViOGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0biBBIFBPIEJveGVzIDI1IFRoZSBFc3BsYW5hZGUgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kNGViZjA1NTU5Njc0NDNjYTE1ZjJjMTViMWY5MjYwMi5zZXRDb250ZW50KGh0bWxfYzUzMmZjMDE2MzVmNDkyOWEzOTJkNWMxZTI4MTViOGMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMzBiZmFkOWJjNjVmNGM4OWE3ZTQyZTUzOTQyN2M2NWUuYmluZFBvcHVwKHBvcHVwX2Q0ZWJmMDU1NTk2NzQ0M2NhMTVmMmMxNWIxZjkyNjAyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzU2MDQ5NmZlMTkyNjQxMTBhMzE1ZjE1YjAwYjZmMTk2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4NDI5MiwtNzkuMzgyMjgwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiYmx1ZSIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83MGY4ZTM5ZTMwZGE0NDQ5YWE3NTEyZDFjMDViODE0MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hZmFhYTkyYWU4MzQ0MzJkODdlMjkxNzEyOTA4YWUzMSA9ICQoJzxkaXYgaWQ9Imh0bWxfYWZhYWE5MmFlODM0NDMyZDg3ZTI5MTcxMjkwOGFlMzEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZpcnN0IENhbmFkaWFuIFBsYWNlLCBVbmRlcmdyb3VuZCBjaXR5IENsdXN0ZXIgMjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzBmOGUzOWUzMGRhNDQ0OWFhNzUxMmQxYzA1YjgxNDMuc2V0Q29udGVudChodG1sX2FmYWFhOTJhZTgzNDQzMmQ4N2UyOTE3MTI5MDhhZTMxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU2MDQ5NmZlMTkyNjQxMTBhMzE1ZjE1YjAwYjZmMTk2LmJpbmRQb3B1cChwb3B1cF83MGY4ZTM5ZTMwZGE0NDQ5YWE3NTEyZDFjMDViODE0Myk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hNGU2YWQ1NDA2OTQ0YzVhOGYzNTFiODk4NWFlMGViYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxODUxNzk5OTk5OTk5NiwtNzkuNDY0NzYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hZTU1OWYwMzc4YjE0YWQ5OWMzZWJlOWI0ZWU0OTQ5MCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80MmRlYjgzZmU0NDk0YTMzYmMxN2Y2ZGNjZDYzNGU0YiA9ICQoJzxkaXYgaWQ9Imh0bWxfNDJkZWI4M2ZlNDQ5NGEzM2JjMTdmNmRjY2Q2MzRlNGIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxhd3JlbmNlIEhlaWdodHMsIExhd3JlbmNlIE1hbm9yIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYWU1NTlmMDM3OGIxNGFkOTljM2ViZTliNGVlNDk0OTAuc2V0Q29udGVudChodG1sXzQyZGViODNmZTQ0OTRhMzNiYzE3ZjZkY2NkNjM0ZTRiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2E0ZTZhZDU0MDY5NDRjNWE4ZjM1MWI4OTg1YWUwZWJiLmJpbmRQb3B1cChwb3B1cF9hZTU1OWYwMzc4YjE0YWQ5OWMzZWJlOWI0ZWU0OTQ5MCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMWZkOGFiODBlOGM0MmIzOTI0MmNhYjZiMzQwMzlhNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTU3NywtNzkuNDQ1MDcyNTk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mODBjNjlkMGYyMGI0ZTIwOTlhNjIxMmM2YjIzYTI4YSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kZGE0NTJkZWExMGM0YzBlYjRjMDVjNjJjNTUyNDkxOCA9ICQoJzxkaXYgaWQ9Imh0bWxfZGRhNDUyZGVhMTBjNGMwZWI0YzA1YzYyYzU1MjQ5MTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkdsZW5jYWlybiBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2Y4MGM2OWQwZjIwYjRlMjA5OWE2MjEyYzZiMjNhMjhhLnNldENvbnRlbnQoaHRtbF9kZGE0NTJkZWExMGM0YzBlYjRjMDVjNjJjNTUyNDkxOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hMWZkOGFiODBlOGM0MmIzOTI0MmNhYjZiMzQwMzlhNi5iaW5kUG9wdXAocG9wdXBfZjgwYzY5ZDBmMjBiNGUyMDk5YTYyMTJjNmIyM2EyOGEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjM0MTM0Nzk5OTY0NDhiYTk3YjI2N2M4OTUxM2UzMTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTM3ODEzLC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ZjNWU4ZTllZGI5NDRlNDRiMzI2NzU2MTJkMTgxZTY4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzFjMWZiMWYxNGMyMDQ3MThhODhkN2YwNmY5MWJjOWU3ID0gJCgnPGRpdiBpZD0iaHRtbF8xYzFmYjFmMTRjMjA0NzE4YTg4ZDdmMDZmOTFiYzllNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtZXdvb2QtQ2VkYXJ2YWxlIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmM1ZThlOWVkYjk0NGU0NGIzMjY3NTYxMmQxODFlNjguc2V0Q29udGVudChodG1sXzFjMWZiMWYxNGMyMDQ3MThhODhkN2YwNmY5MWJjOWU3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzIzNDEzNDc5OTk2NDQ4YmE5N2IyNjdjODk1MTNlMzE1LmJpbmRQb3B1cChwb3B1cF9mYzVlOGU5ZWRiOTQ0ZTQ0YjMyNjc1NjEyZDE4MWU2OCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lYjQ3NjQyMzE1ODU0OWU5YjM1Y2YyMjI5NWU0M2JmMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4OTAyNTYsLTc5LjQ1MzUxMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzZiNjI0MTdiZDViYTRjYmRiN2I3MTUxNDJkNTNmNmI3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzM5ZWQ4ODczNzU0NDQ3NmU5NDgxNGFmNGFlN2E4OTFiID0gJCgnPGRpdiBpZD0iaHRtbF8zOWVkODg3Mzc1NDQ0NzZlOTQ4MTRhZjRhZTdhODkxYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2FsZWRvbmlhLUZhaXJiYW5rcyBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzZiNjI0MTdiZDViYTRjYmRiN2I3MTUxNDJkNTNmNmI3LnNldENvbnRlbnQoaHRtbF8zOWVkODg3Mzc1NDQ0NzZlOTQ4MTRhZjRhZTdhODkxYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lYjQ3NjQyMzE1ODU0OWU5YjM1Y2YyMjI5NWU0M2JmMi5iaW5kUG9wdXAocG9wdXBfNmI2MjQxN2JkNWJhNGNiZGI3YjcxNTE0MmQ1M2Y2YjcpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjM3MGY2NTE4ZDU0NDRkMDhkMWY4YmU1ZjI2MjBhOWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Njk1NDIsLTc5LjQyMjU2MzddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8zMmZjZjk5ZGYwOTg0YzYxOWM2NzBiMzFmMjI0MGU2NiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82MmQ0ZTcxZDk3Mjk0NDI5YTBmMDAzYmViN2QwNzM3MyA9ICQoJzxkaXYgaWQ9Imh0bWxfNjJkNGU3MWQ5NzI5NDQyOWEwZjAwM2JlYjdkMDczNzMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNocmlzdGllIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzJmY2Y5OWRmMDk4NGM2MTljNjcwYjMxZjIyNDBlNjYuc2V0Q29udGVudChodG1sXzYyZDRlNzFkOTcyOTQ0MjlhMGYwMDNiZWI3ZDA3MzczKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2IzNzBmNjUxOGQ1NDQ0ZDA4ZDFmOGJlNWYyNjIwYTliLmJpbmRQb3B1cChwb3B1cF8zMmZjZjk5ZGYwOTg0YzYxOWM2NzBiMzFmMjI0MGU2Nik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83ZjAzMmJkZjQwMWM0N2FlYjc2YTUxNTU1NmU1MTdjMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2OTAwNTEwMDAwMDAxLC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZGUzMzU5MTVlNjY3NDgwNGIwOGZhMDUzMmRhOWY0ZGQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfN2Y3ZjQzNTk3YzZjNGY1YTlmZTFkZjUyMGM4ZTBjNDggPSAkKCc8ZGl2IGlkPSJodG1sXzdmN2Y0MzU5N2M2YzRmNWE5ZmUxZGY1MjBjOGUwYzQ4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3ZlcmNvdXJ0IFZpbGxhZ2UsIER1ZmZlcmluIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZGUzMzU5MTVlNjY3NDgwNGIwOGZhMDUzMmRhOWY0ZGQuc2V0Q29udGVudChodG1sXzdmN2Y0MzU5N2M2YzRmNWE5ZmUxZGY1MjBjOGUwYzQ4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzdmMDMyYmRmNDAxYzQ3YWViNzZhNTE1NTU2ZTUxN2MyLmJpbmRQb3B1cChwb3B1cF9kZTMzNTkxNWU2Njc0ODA0YjA4ZmEwNTMyZGE5ZjRkZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85ZDIyZGYxNzZjNjk0NmY0YTBiNDc0YzY2YmI3YTllOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NzkyNjcwMDAwMDAwNiwtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODZiNGEzMjI4NDE0NGM5ZmEzZmZhOTVmZWY5ZWI4MGYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGJkNDMzNzM0ZmFjNDE2ODgwNDlkMGY0ODY4NzVmODYgPSAkKCc8ZGl2IGlkPSJodG1sXzBiZDQzMzczNGZhYzQxNjg4MDQ5ZDBmNDg2ODc1Zjg2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MaXR0bGUgUG9ydHVnYWwsIFRyaW5pdHkgQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84NmI0YTMyMjg0MTQ0YzlmYTNmZmE5NWZlZjllYjgwZi5zZXRDb250ZW50KGh0bWxfMGJkNDMzNzM0ZmFjNDE2ODgwNDlkMGY0ODY4NzVmODYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOWQyMmRmMTc2YzY5NDZmNGEwYjQ3NGM2NmJiN2E5ZTguYmluZFBvcHVwKHBvcHVwXzg2YjRhMzIyODQxNDRjOWZhM2ZmYTk1ZmVmOWViODBmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzUzNzNlYWM2MGM1MTRhN2E4MjBlN2JmN2VmY2M3YTg4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjM2ODQ3MiwtNzkuNDI4MTkxNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hNmJlYzc0MzBmNDI0MTk3YjE0ZjU5ZTUxMzYzNGRjYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wNDY0Yjg0MDRiMmU0ZDVmOTJjMzUzODEzYzA0OGEwZCA9ICQoJzxkaXYgaWQ9Imh0bWxfMDQ2NGI4NDA0YjJlNGQ1ZjkyYzM1MzgxM2MwNDhhMGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJyb2NrdG9uLCBFeGhpYml0aW9uIFBsYWNlLCBQYXJrZGFsZSBWaWxsYWdlIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTZiZWM3NDMwZjQyNDE5N2IxNGY1OWU1MTM2MzRkY2Muc2V0Q29udGVudChodG1sXzA0NjRiODQwNGIyZTRkNWY5MmMzNTM4MTNjMDQ4YTBkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzUzNzNlYWM2MGM1MTRhN2E4MjBlN2JmN2VmY2M3YTg4LmJpbmRQb3B1cChwb3B1cF9hNmJlYzc0MzBmNDI0MTk3YjE0ZjU5ZTUxMzYzNGRjYyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xOWFlYzlkM2E4NDg0YjZkOTllMTFkYWJiM2Q1MTc4OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMzc1NjIwMDAwMDAwNiwtNzkuNDkwMDczOF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzIyNjA4OTlmZmVlNjQ3ZTFiYjQ5MDMxZmZmZGI5OTM4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzU3ODdiMmZhOTkyODQzZmQ4ZGIyOWQ2NmI2YTdkMWU0ID0gJCgnPGRpdiBpZD0iaHRtbF81Nzg3YjJmYTk5Mjg0M2ZkOGRiMjlkNjZiNmE3ZDFlNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TWFwbGUgTGVhZiBQYXJrLCBOb3J0aCBQYXJrLCBVcHdvb2QgUGFyayBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzIyNjA4OTlmZmVlNjQ3ZTFiYjQ5MDMxZmZmZGI5OTM4LnNldENvbnRlbnQoaHRtbF81Nzg3YjJmYTk5Mjg0M2ZkOGRiMjlkNjZiNmE3ZDFlNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xOWFlYzlkM2E4NDg0YjZkOTllMTFkYWJiM2Q1MTc4OC5iaW5kUG9wdXAocG9wdXBfMjI2MDg5OWZmZWU2NDdlMWJiNDkwMzFmZmZkYjk5MzgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZWI4N2VkYmEzNjg1NDA0OTg1Zjc5YWNlNGI5MmQ1OTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTExMTU4LC03OS40NzYwMTMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzUwYzZhNmRlM2YwMzQzNGNhNTA5YWRmNmFkNDY5N2UzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzRhY2UxZjllYWM5MjQ1ZjBiMTdmYjYwM2Q4NzdlYjQ2ID0gJCgnPGRpdiBpZD0iaHRtbF80YWNlMWY5ZWFjOTI0NWYwYjE3ZmI2MDNkODc3ZWI0NiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RGVsIFJheSwgS2VlbGVzZGFsZSwgTW91bnQgRGVubmlzLCBTaWx2ZXJ0aG9ybiBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzUwYzZhNmRlM2YwMzQzNGNhNTA5YWRmNmFkNDY5N2UzLnNldENvbnRlbnQoaHRtbF80YWNlMWY5ZWFjOTI0NWYwYjE3ZmI2MDNkODc3ZWI0Nik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lYjg3ZWRiYTM2ODU0MDQ5ODVmNzlhY2U0YjkyZDU5NC5iaW5kUG9wdXAocG9wdXBfNTBjNmE2ZGUzZjAzNDM0Y2E1MDlhZGY2YWQ0Njk3ZTMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTlhZTI4MjZkMjIxNGRiYWEzNmRmZDc1YzRiZDFhZWMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NzMxODUyOTk5OTk5OSwtNzkuNDg3MjYxOTAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wN2EyOTc3MmMwN2U0ZGZmOWE3MzFjZDllZmRkMTQ4OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84NzEwYTQwZTQyYWI0NThjYjFhNGM3NGU5ZTM1ZGQ0ZCA9ICQoJzxkaXYgaWQ9Imh0bWxfODcxMGE0MGU0MmFiNDU4Y2IxYTRjNzRlOWUzNWRkNGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRoZSBKdW5jdGlvbiBOb3J0aCwgUnVubnltZWRlIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDdhMjk3NzJjMDdlNGRmZjlhNzMxY2Q5ZWZkZDE0ODguc2V0Q29udGVudChodG1sXzg3MTBhNDBlNDJhYjQ1OGNiMWE0Yzc0ZTllMzVkZDRkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU5YWUyODI2ZDIyMTRkYmFhMzZkZmQ3NWM0YmQxYWVjLmJpbmRQb3B1cChwb3B1cF8wN2EyOTc3MmMwN2U0ZGZmOWE3MzFjZDllZmRkMTQ4OCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yYzgxY2FkMTVhNGM0MGE2OTIwMGQyN2RjMGU5OWIxZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MTYwODMsLTc5LjQ2NDc2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZmE1MWRiMDYzOWVmNDQwMzhjOTI5ZTk4ZWE4Y2RkZTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmU0NDBhYzgyMTJmNDY5OThiM2RjNDUzYmRjZDMyODIgPSAkKCc8ZGl2IGlkPSJodG1sX2ZlNDQwYWM4MjEyZjQ2OTk4YjNkYzQ1M2JkY2QzMjgyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IaWdoIFBhcmssIFRoZSBKdW5jdGlvbiBTb3V0aCBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2ZhNTFkYjA2MzllZjQ0MDM4YzkyOWU5OGVhOGNkZGUwLnNldENvbnRlbnQoaHRtbF9mZTQ0MGFjODIxMmY0Njk5OGIzZGM0NTNiZGNkMzI4Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yYzgxY2FkMTVhNGM0MGE2OTIwMGQyN2RjMGU5OWIxZi5iaW5kUG9wdXAocG9wdXBfZmE1MWRiMDYzOWVmNDQwMzhjOTI5ZTk4ZWE4Y2RkZTApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWJjNGJiNTZmZjA1NDcwZGExYTNlZTZmOTYxMWUxYTkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDg5NTk3LC03OS40NTYzMjVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wNzg2MGY1NTUyNzA0MjU0OWJhMzNmMTkwYTQxN2RmMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xNTZjYjViMDJhNzg0NzdlYTY5NWVhOGRlMTgxNmYzYSA9ICQoJzxkaXYgaWQ9Imh0bWxfMTU2Y2I1YjAyYTc4NDc3ZWE2OTVlYThkZTE4MTZmM2EiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlBhcmtkYWxlLCBSb25jZXN2YWxsZXMgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wNzg2MGY1NTUyNzA0MjU0OWJhMzNmMTkwYTQxN2RmMi5zZXRDb250ZW50KGh0bWxfMTU2Y2I1YjAyYTc4NDc3ZWE2OTVlYThkZTE4MTZmM2EpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMWJjNGJiNTZmZjA1NDcwZGExYTNlZTZmOTYxMWUxYTkuYmluZFBvcHVwKHBvcHVwXzA3ODYwZjU1NTI3MDQyNTQ5YmEzM2YxOTBhNDE3ZGYyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYwMjdiZWJhYTFiMzRiMDE4NjllN2E5NGRkYmYwM2MzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUxNTcwNiwtNzkuNDg0NDQ5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZGMzOGQ3OWRhZDBkNDdkYjhlNGVlODgzZmIzYzIzODEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYmM1OTU4N2VkYmU2NGI0YjhkYjUzOWM4YmE3ZGY3YzMgPSAkKCc8ZGl2IGlkPSJodG1sX2JjNTk1ODdlZGJlNjRiNGI4ZGI1MzljOGJhN2RmN2MzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SdW5ueW1lZGUsIFN3YW5zZWEgQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kYzM4ZDc5ZGFkMGQ0N2RiOGU0ZWU4ODNmYjNjMjM4MS5zZXRDb250ZW50KGh0bWxfYmM1OTU4N2VkYmU2NGI0YjhkYjUzOWM4YmE3ZGY3YzMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjAyN2JlYmFhMWIzNGIwMTg2OWU3YTk0ZGRiZjAzYzMuYmluZFBvcHVwKHBvcHVwX2RjMzhkNzlkYWQwZDQ3ZGI4ZTRlZTg4M2ZiM2MyMzgxKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzc4YzllMzc0NmU0MTQ4NDFiODgwMTAxYjA4YzE0ZjNkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYyMzAxNSwtNzkuMzg5NDkzOF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjNiNDJkZTAyZTA5NDA4YmI0Yjg5YmM2ZGEyODg1MjIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTUzNTgyMzI5ODE2NGVhODhhN2FlNDJlNGU2YjhhZGEgPSAkKCc8ZGl2IGlkPSJodG1sX2U1MzU4MjMyOTgxNjRlYTg4YTdhZTQyZTRlNmI4YWRhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5RdWVlbiYjMzk7cyBQYXJrIENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjNiNDJkZTAyZTA5NDA4YmI0Yjg5YmM2ZGEyODg1MjIuc2V0Q29udGVudChodG1sX2U1MzU4MjMyOTgxNjRlYTg4YTdhZTQyZTRlNmI4YWRhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzc4YzllMzc0NmU0MTQ4NDFiODgwMTAxYjA4YzE0ZjNkLmJpbmRQb3B1cChwb3B1cF9iM2I0MmRlMDJlMDk0MDhiYjRiODliYzZkYTI4ODUyMik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81YzE4MmE2YmZhNGE0ZTY4OTU2ODQzOGNmN2I0MGEyOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjk2NTYsLTc5LjYxNTgxODk5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjkzM2IyOGM1NGUyNDUzODgzYWU5OTU4NWFlYmU2MDMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGYxYzM3OTk1M2NiNDhiZDk3NTYwODEwNDRiNTRmZmYgPSAkKCc8ZGl2IGlkPSJodG1sXzBmMWMzNzk5NTNjYjQ4YmQ5NzU2MDgxMDQ0YjU0ZmZmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DYW5hZGEgUG9zdCBHYXRld2F5IFByb2Nlc3NpbmcgQ2VudHJlIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjkzM2IyOGM1NGUyNDUzODgzYWU5OTU4NWFlYmU2MDMuc2V0Q29udGVudChodG1sXzBmMWMzNzk5NTNjYjQ4YmQ5NzU2MDgxMDQ0YjU0ZmZmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzVjMTgyYTZiZmE0YTRlNjg5NTY4NDM4Y2Y3YjQwYTI5LmJpbmRQb3B1cChwb3B1cF9iOTMzYjI4YzU0ZTI0NTM4ODNhZTk5NTg1YWViZTYwMyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zMmZkYTJlNzVjZWQ0ODIzOGIzMDI1ZTRjYjlkZTExZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Mjc0MzksLTc5LjMyMTU1OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2IzZWM5NGYzM2I4YTQ5OWNiN2E3OTIxOGE1ODA5MzFkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzdmMjIwMTNiOTFhMTQ5YmFhYmM5MTZjY2M4M2VlNTEzID0gJCgnPGRpdiBpZD0iaHRtbF83ZjIyMDEzYjkxYTE0OWJhYWJjOTE2Y2NjODNlZTUxMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnVzaW5lc3MgUmVwbHkgTWFpbCBQcm9jZXNzaW5nIENlbnRyZSA5NjkgRWFzdGVybiBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2IzZWM5NGYzM2I4YTQ5OWNiN2E3OTIxOGE1ODA5MzFkLnNldENvbnRlbnQoaHRtbF83ZjIyMDEzYjkxYTE0OWJhYWJjOTE2Y2NjODNlZTUxMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8zMmZkYTJlNzVjZWQ0ODIzOGIzMDI1ZTRjYjlkZTExZi5iaW5kUG9wdXAocG9wdXBfYjNlYzk0ZjMzYjhhNDk5Y2I3YTc5MjE4YTU4MDkzMWQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOTI2YTcxZWQ2YTgwNDdhMTljMDI5Njk5MDk5Mzg4NTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MDU2NDY2LC03OS41MDEzMjA3MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzY4ODRkZGQ5ZTEwNzQ0MzA4OGI0ZDU4Yjk2NDE4NmM0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzY4ZDRmMGM0ZmI1YjQ4NzU4NzY0OWE2YWE1YjFmOTY4ID0gJCgnPGRpdiBpZD0iaHRtbF82OGQ0ZjBjNGZiNWI0ODc1ODc2NDlhNmFhNWIxZjk2OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtYmVyIEJheSBTaG9yZXMsIE1pbWljbyBTb3V0aCwgTmV3IFRvcm9udG8gQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82ODg0ZGRkOWUxMDc0NDMwODhiNGQ1OGI5NjQxODZjNC5zZXRDb250ZW50KGh0bWxfNjhkNGYwYzRmYjViNDg3NTg3NjQ5YTZhYTViMWY5NjgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOTI2YTcxZWQ2YTgwNDdhMTljMDI5Njk5MDk5Mzg4NTQuYmluZFBvcHVwKHBvcHVwXzY4ODRkZGQ5ZTEwNzQ0MzA4OGI0ZDU4Yjk2NDE4NmM0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzE2NDdjZTYyOTc1YzQ2NTJhZTBiNTY0NjA4NTdiNzYxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjAyNDEzNzAwMDAwMDEsLTc5LjU0MzQ4NDA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzRmNzg3Mzg2OWJlNGM3YmE5Zjg3MzczM2YyYmZjYTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDg2YzhkZmQ2Y2Q1NDY2OGEyNTIwMjJmN2M2ZGYyZmEgPSAkKCc8ZGl2IGlkPSJodG1sXzQ4NmM4ZGZkNmNkNTQ2NjhhMjUyMDIyZjdjNmRmMmZhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BbGRlcndvb2QsIExvbmcgQnJhbmNoIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzRmNzg3Mzg2OWJlNGM3YmE5Zjg3MzczM2YyYmZjYTkuc2V0Q29udGVudChodG1sXzQ4NmM4ZGZkNmNkNTQ2NjhhMjUyMDIyZjdjNmRmMmZhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzE2NDdjZTYyOTc1YzQ2NTJhZTBiNTY0NjA4NTdiNzYxLmJpbmRQb3B1cChwb3B1cF9jNGY3ODczODY5YmU0YzdiYTlmODczNzMzZjJiZmNhOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hNTJmYzYyZDA5YTU0ZDEzOWNiYTAzMmY4MzQxN2YxZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MzY1MzYwMDAwMDAwNSwtNzkuNTA2OTQzNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzA0NzFmYzYwNzk4ZjQyNDY4OTZhMTNkZjM1MTk3YmNmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzVjNmMwN2RkMGQzYTRkNzU5MmYxOTA1Y2Q4ZjE3ODJjID0gJCgnPGRpdiBpZD0iaHRtbF81YzZjMDdkZDBkM2E0ZDc1OTJmMTkwNWNkOGYxNzgyYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEtpbmdzd2F5LCBNb250Z29tZXJ5IFJvYWQsIE9sZCBNaWxsIE5vcnRoIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDQ3MWZjNjA3OThmNDI0Njg5NmExM2RmMzUxOTdiY2Yuc2V0Q29udGVudChodG1sXzVjNmMwN2RkMGQzYTRkNzU5MmYxOTA1Y2Q4ZjE3ODJjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2E1MmZjNjJkMDlhNTRkMTM5Y2JhMDMyZjgzNDE3ZjFlLmJpbmRQb3B1cChwb3B1cF8wNDcxZmM2MDc5OGY0MjQ2ODk2YTEzZGYzNTE5N2JjZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMGZiZmM4MTEzOTg0ZDA4ODhiOGFmMTk3ZjlmODE2ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjI1NzksLTc5LjQ5ODUwOTA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2Q1ZDY4Y2QwYWYwNDdjY2E5ZmRhODRkM2ExMjAxMzMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDY2YTJjZTdmMTM2NDNmY2JjNmI0NGJiYzdmMTViNTQgPSAkKCc8ZGl2IGlkPSJodG1sX2Q2NmEyY2U3ZjEzNjQzZmNiYzZiNDRiYmM3ZjE1YjU0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IdW1iZXIgQmF5LCBLaW5nJiMzOTtzIE1pbGwgUGFyaywgS2luZ3N3YXkgUGFyayBTb3V0aCBFYXN0LCBNaW1pY28gTkUsIE9sZCBNaWxsIFNvdXRoLCBUaGUgUXVlZW5zd2F5IEVhc3QsIFJveWFsIFlvcmsgU291dGggRWFzdCwgU3VubnlsZWEgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zZDVkNjhjZDBhZjA0N2NjYTlmZGE4NGQzYTEyMDEzMy5zZXRDb250ZW50KGh0bWxfZDY2YTJjZTdmMTM2NDNmY2JjNmI0NGJiYzdmMTViNTQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYTBmYmZjODExMzk4NGQwODg4YjhhZjE5N2Y5ZjgxNmUuYmluZFBvcHVwKHBvcHVwXzNkNWQ2OGNkMGFmMDQ3Y2NhOWZkYTg0ZDNhMTIwMTMzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I1YjA3YWQ2Mjg0NjRhYjM4NjRkY2VjYWI5NjgxMzVlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4ODQwOCwtNzkuNTIwOTk5NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iN2FiZGZjY2U1ZjU0YTkzODZjZjJiMWExZTlmZTNlZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83M2Y0Y2E2YjYwNTI0OWI3OTA2MTRhZGY4MmRmYjE5NCA9ICQoJzxkaXYgaWQ9Imh0bWxfNzNmNGNhNmI2MDUyNDliNzkwNjE0YWRmODJkZmIxOTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPktpbmdzd2F5IFBhcmsgU291dGggV2VzdCwgTWltaWNvIE5XLCBUaGUgUXVlZW5zd2F5IFdlc3QsIFJveWFsIFlvcmsgU291dGggV2VzdCwgU291dGggb2YgQmxvb3IgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iN2FiZGZjY2U1ZjU0YTkzODZjZjJiMWExZTlmZTNlZS5zZXRDb250ZW50KGh0bWxfNzNmNGNhNmI2MDUyNDliNzkwNjE0YWRmODJkZmIxOTQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjViMDdhZDYyODQ2NGFiMzg2NGRjZWNhYjk2ODEzNWUuYmluZFBvcHVwKHBvcHVwX2I3YWJkZmNjZTVmNTRhOTM4NmNmMmIxYTFlOWZlM2VlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2MzNWVjYzU3MWZjMTQ5YjE5MmM1ZDUwMWM0MWRkN2U4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUwOTQzMiwtNzkuNTU0NzI0NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wYzhlYjBiZmVjMDA0MTFkYjZkMzc4YTI4ODc3ZWRkMSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lYjdjNzc2MTdiNzM0YTExYTJkM2UxYWYwZWM5MDkzOCA9ICQoJzxkaXYgaWQ9Imh0bWxfZWI3Yzc3NjE3YjczNGExMWEyZDNlMWFmMGVjOTA5MzgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsb3ZlcmRhbGUsIElzbGluZ3RvbiwgTWFydGluIEdyb3ZlLCBQcmluY2VzcyBHYXJkZW5zLCBXZXN0IERlYW5lIFBhcmsgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wYzhlYjBiZmVjMDA0MTFkYjZkMzc4YTI4ODc3ZWRkMS5zZXRDb250ZW50KGh0bWxfZWI3Yzc3NjE3YjczNGExMWEyZDNlMWFmMGVjOTA5MzgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYzM1ZWNjNTcxZmMxNDliMTkyYzVkNTAxYzQxZGQ3ZTguYmluZFBvcHVwKHBvcHVwXzBjOGViMGJmZWMwMDQxMWRiNmQzNzhhMjg4NzdlZGQxKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2FjMGFlODEyOWY0YTRkZGNiOTYwOWY4MWI2ZmJhYWFmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQzNTE1MiwtNzkuNTc3MjAwNzk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84NTFlZTE2MmJhMjY0YTE4OWUzZmVkM2E5ZDUwYjE0OSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83MGY0NzFkNDJmNmQ0OWZiYjg5MWRiYjY1YzAyNmZmOCA9ICQoJzxkaXYgaWQ9Imh0bWxfNzBmNDcxZDQyZjZkNDlmYmI4OTFkYmI2NWMwMjZmZjgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJsb29yZGFsZSBHYXJkZW5zLCBFcmluZ2F0ZSwgTWFya2xhbmQgV29vZCwgT2xkIEJ1cm5oYW10aG9ycGUgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84NTFlZTE2MmJhMjY0YTE4OWUzZmVkM2E5ZDUwYjE0OS5zZXRDb250ZW50KGh0bWxfNzBmNDcxZDQyZjZkNDlmYmI4OTFkYmI2NWMwMjZmZjgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYWMwYWU4MTI5ZjRhNGRkY2I5NjA5ZjgxYjZmYmFhYWYuYmluZFBvcHVwKHBvcHVwXzg1MWVlMTYyYmEyNjRhMTg5ZTNmZWQzYTlkNTBiMTQ5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzFhMDk4YzQ1NTU3ZjQ5NmFiYmI5MWVkMWJiYTJjM2I2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU2MzAzMywtNzkuNTY1OTYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8zZmVlMzEzZGQzZGY0YTc0ODc5ZjkwNGE5MDU4YTI4MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xYTFlZDY5MGFlNDM0YmRjODJmMDc3MmE1ZGZlMjc4MyA9ICQoJzxkaXYgaWQ9Imh0bWxfMWExZWQ2OTBhZTQzNGJkYzgyZjA3NzJhNWRmZTI3ODMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkh1bWJlciBTdW1taXQgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zZmVlMzEzZGQzZGY0YTc0ODc5ZjkwNGE5MDU4YTI4My5zZXRDb250ZW50KGh0bWxfMWExZWQ2OTBhZTQzNGJkYzgyZjA3NzJhNWRmZTI3ODMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMWEwOThjNDU1NTdmNDk2YWJiYjkxZWQxYmJhMmMzYjYuYmluZFBvcHVwKHBvcHVwXzNmZWUzMTNkZDNkZjRhNzQ4NzlmOTA0YTkwNThhMjgzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2U5NjZmZGNjOTc3NTQ0NDU4ZjRkMWY2ZjFkMjc2ZTNlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI0NzY1OSwtNzkuNTMyMjQyNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81YmYxZWViN2QwNDU0NDcwYTAyZmU4OTQ4ODRmZDA4MiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iYmIyYzRlMTRjNDE0ZTZhODZhNGQ5ZjcyNmI4NTQ5ZCA9ICQoJzxkaXYgaWQ9Imh0bWxfYmJiMmM0ZTE0YzQxNGU2YTg2YTRkOWY3MjZiODU0OWQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVtZXJ5LCBIdW1iZXJsZWEgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81YmYxZWViN2QwNDU0NDcwYTAyZmU4OTQ4ODRmZDA4Mi5zZXRDb250ZW50KGh0bWxfYmJiMmM0ZTE0YzQxNGU2YTg2YTRkOWY3MjZiODU0OWQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZTk2NmZkY2M5Nzc1NDQ0NThmNGQxZjZmMWQyNzZlM2UuYmluZFBvcHVwKHBvcHVwXzViZjFlZWI3ZDA0NTQ0NzBhMDJmZTg5NDg4NGZkMDgyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ExMjc3YjdjOTYwODRkZGZiY2E5NjBkNTg0NDhiNzQxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA2ODc2LC03OS41MTgxODg0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzkwNTI0NTUxN2U3MjQwNTlhOTdhZDI0ODYxZDhlYWUwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2E4NjQ2MWZmM2I5MDRkYmY4YTcwZDIxZGZiYjYxYTU0ID0gJCgnPGRpdiBpZD0iaHRtbF9hODY0NjFmZjNiOTA0ZGJmOGE3MGQyMWRmYmI2MWE1NCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2VzdG9uIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTA1MjQ1NTE3ZTcyNDA1OWE5N2FkMjQ4NjFkOGVhZTAuc2V0Q29udGVudChodG1sX2E4NjQ2MWZmM2I5MDRkYmY4YTcwZDIxZGZiYjYxYTU0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2ExMjc3YjdjOTYwODRkZGZiY2E5NjBkNTg0NDhiNzQxLmJpbmRQb3B1cChwb3B1cF85MDUyNDU1MTdlNzI0MDU5YTk3YWQyNDg2MWQ4ZWFlMCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80OTJkYzQxYzM0OGE0ZWRmODJjNzkyMzNhZGM5MDllZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5NjMxOSwtNzkuNTMyMjQyNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiZ3JlZW4iLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJncmVlbiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85YTkxNzRiYjg1OTg0MGUyYTUwM2I3MDQxN2FkZjMxMSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85YWQ3MTBlYWMzYTI0MGQwOWI5ZTBmODA1NDE4YjI1MCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lNzIwYmY3MzNhYWM0MWQwYTQ0YjI1NDA5YTkwNWVmZCA9ICQoJzxkaXYgaWQ9Imh0bWxfZTcyMGJmNzMzYWFjNDFkMGE0NGIyNTQwOWE5MDVlZmQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldlc3Rtb3VudCBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzlhZDcxMGVhYzNhMjQwZDA5YjllMGY4MDU0MThiMjUwLnNldENvbnRlbnQoaHRtbF9lNzIwYmY3MzNhYWM0MWQwYTQ0YjI1NDA5YTkwNWVmZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80OTJkYzQxYzM0OGE0ZWRmODJjNzkyMzNhZGM5MDllZS5iaW5kUG9wdXAocG9wdXBfOWFkNzEwZWFjM2EyNDBkMDliOWUwZjgwNTQxOGIyNTApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjA3NjU5MGYyMWRjNGI1MGE5NzZjNmEyNDdmZjNkM2MgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODg5MDU0LC03OS41NTQ3MjQ0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzU0Y2YzYzY3MGM2NjRmYThiOGZiNGQwYmYyZDBhOWZmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2UwYmI1YjE5YzVmMjRiYmI5ZGJlODBmNTkwYjNlOWNjID0gJCgnPGRpdiBpZD0iaHRtbF9lMGJiNWIxOWM1ZjI0YmJiOWRiZTgwZjU5MGIzZTljYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+S2luZ3N2aWV3IFZpbGxhZ2UsIE1hcnRpbiBHcm92ZSBHYXJkZW5zLCBSaWNodmlldyBHYXJkZW5zLCBTdC4gUGhpbGxpcHMgQ2x1c3RlciA0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81NGNmM2M2NzBjNjY0ZmE4YjhmYjRkMGJmMmQwYTlmZi5zZXRDb250ZW50KGh0bWxfZTBiYjViMTljNWYyNGJiYjlkYmU4MGY1OTBiM2U5Y2MpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjA3NjU5MGYyMWRjNGI1MGE5NzZjNmEyNDdmZjNkM2MuYmluZFBvcHVwKHBvcHVwXzU0Y2YzYzY3MGM2NjRmYThiOGZiNGQwYmYyZDBhOWZmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzc2ZTkzNzdhYWUzMDQ1ZGRhYmYzODVkYjZjMjA5ODY2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM5NDE2Mzk5OTk5OTk2LC03OS41ODg0MzY5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImdyZWVuIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiZ3JlZW4iLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOWE5MTc0YmI4NTk4NDBlMmE1MDNiNzA0MTdhZGYzMTEpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTI5OTQzZDc3NTY3NGFlZGFmMTE4ZTU3YjA2MTIyMTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNmViODRkYzA4NTEzNDcwY2E5YWU3NGQ3MWI5MjExNjYgPSAkKCc8ZGl2IGlkPSJodG1sXzZlYjg0ZGMwODUxMzQ3MGNhOWFlNzRkNzFiOTIxMTY2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BbGJpb24gR2FyZGVucywgQmVhdW1vbmQgSGVpZ2h0cywgSHVtYmVyZ2F0ZSwgSmFtZXN0b3duLCBNb3VudCBPbGl2ZSwgU2lsdmVyc3RvbmUsIFNvdXRoIFN0ZWVsZXMsIFRoaXN0bGV0b3duIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTI5OTQzZDc3NTY3NGFlZGFmMTE4ZTU3YjA2MTIyMTkuc2V0Q29udGVudChodG1sXzZlYjg0ZGMwODUxMzQ3MGNhOWFlNzRkNzFiOTIxMTY2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzc2ZTkzNzdhYWUzMDQ1ZGRhYmYzODVkYjZjMjA5ODY2LmJpbmRQb3B1cChwb3B1cF81Mjk5NDNkNzc1Njc0YWVkYWYxMThlNTdiMDYxMjIxOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83YzlhNzgxMzZlMDc0NjE5ODc2MTE5NDY3OGYzNDljMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNjc0ODI5OTk5OTk5NCwtNzkuNTk0MDU0NF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzlhOTE3NGJiODU5ODQwZTJhNTAzYjcwNDE3YWRmMzExKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzE4YTM5ODJiNWNiMDRiZTU5ZDdhMzNjMjRkNWQ1ODc1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzZjYjAxYTY4ZDJkYzRiNTdiNGRlODg1NjgxZWQ0NjEwID0gJCgnPGRpdiBpZD0iaHRtbF82Y2IwMWE2OGQyZGM0YjU3YjRkZTg4NTY4MWVkNDYxMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGh3ZXN0IENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMThhMzk4MmI1Y2IwNGJlNTlkN2EzM2MyNGQ1ZDU4NzUuc2V0Q29udGVudChodG1sXzZjYjAxYTY4ZDJkYzRiNTdiNGRlODg1NjgxZWQ0NjEwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzdjOWE3ODEzNmUwNzQ2MTk4NzYxMTk0Njc4ZjM0OWMyLmJpbmRQb3B1cChwb3B1cF8xOGEzOTgyYjVjYjA0YmU1OWQ3YTMzYzI0ZDVkNTg3NSk7CgogICAgICAgICAgICAKICAgICAgICAKPC9zY3JpcHQ+\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7f48cb15ed30>"
]
},
"execution_count": 198,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# set color scheme for the clusters\n",
"x = np.arange(kclusters)\n",
"#ys = [i + x + (i*x)**2 for i in range(kclusters)]\n",
"#colors_array = cm.rainbow(np.linspace(0, 1, len(ys)))\n",
"#rainbow = [colors.rgb2hex(i) for i in colors_array]\n",
"\n",
"rainbow = ['red','blue','yellow','green','orange']\n",
"# create map\n",
"map_clusters = folium.Map(location=[43.7,-79.4], zoom_start=10.5)\n",
"\n",
"# add markers to the map\n",
"markers_colors = []\n",
"for lat, lon, poi, cluster in zip(df_full_clust['Latitude'], df_full_clust['Longitude'], df_full_clust['Neighbourhood'], df_full_clust['Cluster Sum']):\n",
" label = folium.Popup(str(poi) + ' Cluster ' + str(cluster), parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat, lon],\n",
" radius=5,\n",
" popup=label,\n",
" color=rainbow[cluster-1],\n",
" fill=True,\n",
" fill_color=rainbow[cluster-1],\n",
" fill_opacity=0.7).add_to(map_clusters)\n",
" \n",
"map_clusters"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The sum based clustering seems to be significantly influenced by proximity to the city center but does provide some information. Lets examine the areas of different clusters to see what we might find in each cluster. We start by grouping our postcodes by cluster membership and taking the average number of each venue type."
]
},
{
"cell_type": "code",
"execution_count": 204,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"---- Average Area in red Cluster Contains ----\n",
"Coffee Shop: 4.230769230769231\n",
"Café: 2.5384615384615383\n",
"Bar: 1.4615384615384615\n",
"Bakery: 1.3846153846153846\n",
"Restaurant: 1.3076923076923077\n",
"---- Average Area in blue Cluster Contains ----\n",
"Coffee Shop: 7.0\n",
"Café: 3.75\n",
"Restaurant: 3.5\n",
"Clothing Store: 3.0\n",
"Italian Restaurant: 2.75\n",
"---- Average Area in yellow Cluster Contains ----\n",
"Coffee Shop: 9.75\n",
"Café: 6.75\n",
"Hotel: 6.0\n",
"Restaurant: 4.0\n",
"American Restaurant: 3.5\n",
"---- Average Area in green Cluster Contains ----\n",
"Coffee Shop: 13.5\n",
"Café: 4.0\n",
"Italian Restaurant: 4.0\n",
"Aquarium: 2.5\n",
"Bar: 2.5\n",
"---- Average Area in orange Cluster Contains ----\n",
"Coffee Shop: 0.4805194805194805\n",
"Park: 0.37662337662337664\n",
"Pizza Place: 0.3246753246753247\n",
"Fast Food Restaurant: 0.2857142857142857\n",
"Sandwich Place: 0.2597402597402597\n"
]
}
],
"source": [
"toronto_grouped_clustering_sum['Cluster'] = kmeans_sum.labels_\n",
"sum_cluster_means = toronto_grouped_clustering_sum.groupby('Cluster').mean()\n",
"sum_cluster_means.index = rainbow \n",
"num_top_venues = 5\n",
"\n",
"for c in sum_cluster_means.index:\n",
" print(\"---- Average Area in \"+c+\" Cluster Contains ----\")\n",
" temp = sum_cluster_means[sum_cluster_means.index==c]\n",
" for _ in range(num_top_venues):\n",
" ven_type = temp.idxmax(axis=1)[0]\n",
" print('{}: {}'.format(ven_type, temp.loc[c, ven_type]))\n",
" temp = temp.drop(temp.idxmax(axis=1), axis=1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now lets visualise the mean based clustering."
]
},
{
"cell_type": "code",
"execution_count": 139,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiIiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2YiA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2YicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDMuNywtNzkuNF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6b29tOiAxMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Qm91bmRzOiBib3VuZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXllcnM6IFtdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ybGRDb3B5SnVtcDogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcnM6IEwuQ1JTLkVQU0czODU3CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgdGlsZV9sYXllcl9mNzY4ODBmYjk5ZWE0YjI5YjI3NzBhNjJiM2ZmMmMzMiA9IEwudGlsZUxheWVyKAogICAgICAgICAgICAgICAgJ2h0dHBzOi8ve3N9LnRpbGUub3BlbnN0cmVldG1hcC5vcmcve3p9L3t4fS97eX0ucG5nJywKICAgICAgICAgICAgICAgIHsKICAiYXR0cmlidXRpb24iOiBudWxsLAogICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwKICAibWF4Wm9vbSI6IDE4LAogICJtaW5ab29tIjogMSwKICAibm9XcmFwIjogZmFsc2UsCiAgInN1YmRvbWFpbnMiOiAiYWJjIgp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMGIzZjNlMTU4MmUxNGMyODk5ZDU2MGFhYjgwZWNjMmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My44MDY2ODYyOTk5OTk5OTYsLTc5LjE5NDM1MzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84ZDk2OTdjYWMxZjc0MjBlYjcwZDhiZTRiODMxYjNjZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wOGZmNTlhOGY2MzE0OGM2YTNlODc0MGYzYjljNGVmZSA9ICQoJzxkaXYgaWQ9Imh0bWxfMDhmZjU5YThmNjMxNDhjNmEzZTg3NDBmM2I5YzRlZmUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJvdWdlLCBNYWx2ZXJuIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOGQ5Njk3Y2FjMWY3NDIwZWI3MGQ4YmU0YjgzMWIzY2Uuc2V0Q29udGVudChodG1sXzA4ZmY1OWE4ZjYzMTQ4YzZhM2U4NzQwZjNiOWM0ZWZlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzBiM2YzZTE1ODJlMTRjMjg5OWQ1NjBhYWI4MGVjYzJkLmJpbmRQb3B1cChwb3B1cF84ZDk2OTdjYWMxZjc0MjBlYjcwZDhiZTRiODMxYjNjZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YjkxNGU5ZTMyMTk0YWJiOGQ2NTI5YTY1OTc1MmFkMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4NDUzNTEsLTc5LjE2MDQ5NzA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83YjM1OGJiMmQ0OGY0OTczYWY2MDI5OWNhZTA1Njc3NCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83NmE1OWE4YTQ5Mzk0MjVmODMzZmY3NzgyNGM2ZTBiZCA9ICQoJzxkaXYgaWQ9Imh0bWxfNzZhNTlhOGE0OTM5NDI1ZjgzM2ZmNzc4MjRjNmUwYmQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhpZ2hsYW5kIENyZWVrLCBSb3VnZSBIaWxsLCBQb3J0IFVuaW9uIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2IzNThiYjJkNDhmNDk3M2FmNjAyOTljYWUwNTY3NzQuc2V0Q29udGVudChodG1sXzc2YTU5YThhNDkzOTQyNWY4MzNmZjc3ODI0YzZlMGJkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzliOTE0ZTllMzIxOTRhYmI4ZDY1MjlhNjU5NzUyYWQyLmJpbmRQb3B1cChwb3B1cF83YjM1OGJiMmQ0OGY0OTczYWY2MDI5OWNhZTA1Njc3NCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zY2MzOTc3Y2YyMWE0YmFjOGRlMTU5OGFjYjc1MzlhZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2MzU3MjYsLTc5LjE4ODcxMTVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ZjYWYyY2EwMTY1OTQ5MTA5ODI3YTNmYzQ1YWY5OThhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk2YzM4Mzk0YzY2MDQwMTliYTI4ZTU2M2ExNTVmOTI4ID0gJCgnPGRpdiBpZD0iaHRtbF85NmMzODM5NGM2NjA0MDE5YmEyOGU1NjNhMTU1ZjkyOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R3VpbGR3b29kLCBNb3JuaW5nc2lkZSwgV2VzdCBIaWxsIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmNhZjJjYTAxNjU5NDkxMDk4MjdhM2ZjNDVhZjk5OGEuc2V0Q29udGVudChodG1sXzk2YzM4Mzk0YzY2MDQwMTliYTI4ZTU2M2ExNTVmOTI4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzNjYzM5NzdjZjIxYTRiYWM4ZGUxNTk4YWNiNzUzOWFmLmJpbmRQb3B1cChwb3B1cF9mY2FmMmNhMDE2NTk0OTEwOTgyN2EzZmM0NWFmOTk4YSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81ODg0MjA1NzIwMWU0MjRjYTdlZjIxOTQ5Y2NmNDE4ZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MDk5MjEsLTc5LjIxNjkxNzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wZWQ3ZWZkYWQ4Mjk0MWNiYjJiZjUzODYyMWNlYWQ3OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xZmJkMDlhYzBiMjA0YTc4OGMyMDhiZGUzN2YzMzBhNyA9ICQoJzxkaXYgaWQ9Imh0bWxfMWZiZDA5YWMwYjIwNGE3ODhjMjA4YmRlMzdmMzMwYTciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldvYnVybiBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzBlZDdlZmRhZDgyOTQxY2JiMmJmNTM4NjIxY2VhZDc4LnNldENvbnRlbnQoaHRtbF8xZmJkMDlhYzBiMjA0YTc4OGMyMDhiZGUzN2YzMzBhNyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81ODg0MjA1NzIwMWU0MjRjYTdlZjIxOTQ5Y2NmNDE4Zi5iaW5kUG9wdXAocG9wdXBfMGVkN2VmZGFkODI5NDFjYmIyYmY1Mzg2MjFjZWFkNzgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjliZTYyNTBjMWZjNDIwNzllMGY3ZmQ2ZjY4NTYzNDYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzMxMzYsLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81OWZlOTkwOWRmOTA0YzNlOTBkZDQzMjk1MTFlNmIxNiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81YWRhZmFiNjY3ODY0ZGY0YTBmZWUxZjcyZTY2ZDVlYiA9ICQoJzxkaXYgaWQ9Imh0bWxfNWFkYWZhYjY2Nzg2NGRmNGEwZmVlMWY3MmU2NmQ1ZWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNlZGFyYnJhZSBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU5ZmU5OTA5ZGY5MDRjM2U5MGRkNDMyOTUxMWU2YjE2LnNldENvbnRlbnQoaHRtbF81YWRhZmFiNjY3ODY0ZGY0YTBmZWUxZjcyZTY2ZDVlYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl82OWJlNjI1MGMxZmM0MjA3OWUwZjdmZDZmNjg1NjM0Ni5iaW5kUG9wdXAocG9wdXBfNTlmZTk5MDlkZjkwNGMzZTkwZGQ0MzI5NTExZTZiMTYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZjcxZWQwMDdkYzc2NDE4ZTkyYWQ0MjYzODc5MDFhZWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NDQ3MzQyLC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMWFmMTVjMjlmMWZlNDNiNmFkMDU3Yzk0MDdjNTk5OTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNTgzNzlhM2E2MDUwNGI3ZmIyNWM3NDE0YzMyZmM5YjYgPSAkKCc8ZGl2IGlkPSJodG1sXzU4Mzc5YTNhNjA1MDRiN2ZiMjVjNzQxNGMzMmZjOWI2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TY2FyYm9yb3VnaCBWaWxsYWdlIENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMWFmMTVjMjlmMWZlNDNiNmFkMDU3Yzk0MDdjNTk5OTEuc2V0Q29udGVudChodG1sXzU4Mzc5YTNhNjA1MDRiN2ZiMjVjNzQxNGMzMmZjOWI2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2Y3MWVkMDA3ZGM3NjQxOGU5MmFkNDI2Mzg3OTAxYWViLmJpbmRQb3B1cChwb3B1cF8xYWYxNWMyOWYxZmU0M2I2YWQwNTdjOTQwN2M1OTk5MSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84N2NkMTAxNDU3Nzc0ZGQwODc2NjU0NDhiM2U0MjI0MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcyNzkyOTIsLTc5LjI2MjAyOTQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kNjM3NGY3YjJhZDk0ZjgyOTViNDg3MzdhZmIzMzk3ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zZjJjMTJkOTBlYTY0Njg4YWU2ZDU1ZjI2NzhjMDQ0MCA9ICQoJzxkaXYgaWQ9Imh0bWxfM2YyYzEyZDkwZWE2NDY4OGFlNmQ1NWYyNjc4YzA0NDAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVhc3QgQmlyY2htb3VudCBQYXJrLCBJb252aWV3LCBLZW5uZWR5IFBhcmsgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kNjM3NGY3YjJhZDk0ZjgyOTViNDg3MzdhZmIzMzk3Zi5zZXRDb250ZW50KGh0bWxfM2YyYzEyZDkwZWE2NDY4OGFlNmQ1NWYyNjc4YzA0NDApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfODdjZDEwMTQ1Nzc3NGRkMDg3NjY1NDQ4YjNlNDIyNDEuYmluZFBvcHVwKHBvcHVwX2Q2Mzc0ZjdiMmFkOTRmODI5NWI0ODczN2FmYjMzOTdmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzEzNjZiM2E0OTUwNTRmZDc5MGI3ZWY4N2Q5ODY3M2EzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzExMTExNzAwMDAwMDA0LC03OS4yODQ1NzcyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80NjQzMjFhNmQxZjA0ZDczOTM1OGU0YTg4YmMwNDBlOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jMmU1NDcyNzA1M2Y0ZWVkOGE0MWJjNzNkZWFlMTcxYSA9ICQoJzxkaXYgaWQ9Imh0bWxfYzJlNTQ3MjcwNTNmNGVlZDhhNDFiYzczZGVhZTE3MWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsYWlybGVhLCBHb2xkZW4gTWlsZSwgT2FrcmlkZ2UgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80NjQzMjFhNmQxZjA0ZDczOTM1OGU0YTg4YmMwNDBlOS5zZXRDb250ZW50KGh0bWxfYzJlNTQ3MjcwNTNmNGVlZDhhNDFiYzczZGVhZTE3MWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMTM2NmIzYTQ5NTA1NGZkNzkwYjdlZjg3ZDk4NjczYTMuYmluZFBvcHVwKHBvcHVwXzQ2NDMyMWE2ZDFmMDRkNzM5MzU4ZTRhODhiYzA0MGU5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NhYWZiYWJiZjliMDQ0MzNiZjU5ZWQ0NjI0ZWRiMzlhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzE2MzE2LC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTIxMTJkYjI5ZDczNDRiNGEyY2M0NjhlMzczNmZlOTQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2Q3NDI2ODMyYWFhNDNhOGFhODY3ZDM2NDNkOWY3YjMgPSAkKCc8ZGl2IGlkPSJodG1sX2NkNzQyNjgzMmFhYTQzYThhYTg2N2QzNjQzZDlmN2IzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DbGlmZmNyZXN0LCBDbGlmZnNpZGUsIFNjYXJib3JvdWdoIFZpbGxhZ2UgV2VzdCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2UyMTEyZGIyOWQ3MzQ0YjRhMmNjNDY4ZTM3MzZmZTk0LnNldENvbnRlbnQoaHRtbF9jZDc0MjY4MzJhYWE0M2E4YWE4NjdkMzY0M2Q5ZjdiMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jYWFmYmFiYmY5YjA0NDMzYmY1OWVkNDYyNGVkYjM5YS5iaW5kUG9wdXAocG9wdXBfZTIxMTJkYjI5ZDczNDRiNGEyY2M0NjhlMzczNmZlOTQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTcxZGFkZDE0MDdjNGFjYzgwMmI2NDNmZTNhM2ZjNGQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTI2NTcwMDAwMDAwMDQsLTc5LjI2NDg0ODFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2IwYmJkYWFkYmU3ZjRlM2M5NzU5MDBhYmQzMzZiNzI2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2Y5YTdkMWU1MGNjYjRlZjg5ODhmN2ExYWY5Y2NlZjA0ID0gJCgnPGRpdiBpZD0iaHRtbF9mOWE3ZDFlNTBjY2I0ZWY4OTg4ZjdhMWFmOWNjZWYwNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmlyY2ggQ2xpZmYsIENsaWZmc2lkZSBXZXN0IENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjBiYmRhYWRiZTdmNGUzYzk3NTkwMGFiZDMzNmI3MjYuc2V0Q29udGVudChodG1sX2Y5YTdkMWU1MGNjYjRlZjg5ODhmN2ExYWY5Y2NlZjA0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU3MWRhZGQxNDA3YzRhY2M4MDJiNjQzZmUzYTNmYzRkLmJpbmRQb3B1cChwb3B1cF9iMGJiZGFhZGJlN2Y0ZTNjOTc1OTAwYWJkMzM2YjcyNik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82OWYxMTUyZWUyZTc0YWY3YjEyZjAxNzc0OGY0OGU2MCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NzQwOTYsLTc5LjI3MzMwNDAwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kNzQ5ZGYyNWM1N2Y0MDQzODY5NDMzNWNmYmYzODQwNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jMGE3ZDA5ZmNhMmM0MjFkYWM2YjNjZjMxOGVmMzZmNiA9ICQoJzxkaXYgaWQ9Imh0bWxfYzBhN2QwOWZjYTJjNDIxZGFjNmIzY2YzMThlZjM2ZjYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvcnNldCBQYXJrLCBTY2FyYm9yb3VnaCBUb3duIENlbnRyZSwgV2V4Zm9yZCBIZWlnaHRzIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDc0OWRmMjVjNTdmNDA0Mzg2OTQzMzVjZmJmMzg0MDQuc2V0Q29udGVudChodG1sX2MwYTdkMDlmY2EyYzQyMWRhYzZiM2NmMzE4ZWYzNmY2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzY5ZjExNTJlZTJlNzRhZjdiMTJmMDE3NzQ4ZjQ4ZTYwLmJpbmRQb3B1cChwb3B1cF9kNzQ5ZGYyNWM1N2Y0MDQzODY5NDMzNWNmYmYzODQwNCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lOTA4OTUzOGMxNmI0ZTI0OGUwZTVhYjhjMWY0ZTU2NCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1MDA3MTUwMDAwMDAwNCwtNzkuMjk1ODQ5MV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjUxZGZkYjRmYzAxNDg5NWFiZjIzMzE4NWIwZjlmOGYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTE0OTExNTZlMmJlNDVlMmFhYmE0MTU4ODQ3MmZiMDggPSAkKCc8ZGl2IGlkPSJodG1sXzExNDkxMTU2ZTJiZTQ1ZTJhYWJhNDE1ODg0NzJmYjA4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5NYXJ5dmFsZSwgV2V4Zm9yZCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzI1MWRmZGI0ZmMwMTQ4OTVhYmYyMzMxODViMGY5ZjhmLnNldENvbnRlbnQoaHRtbF8xMTQ5MTE1NmUyYmU0NWUyYWFiYTQxNTg4NDcyZmIwOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lOTA4OTUzOGMxNmI0ZTI0OGUwZTVhYjhjMWY0ZTU2NC5iaW5kUG9wdXAocG9wdXBfMjUxZGZkYjRmYzAxNDg5NWFiZjIzMzE4NWIwZjlmOGYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDY0NzIzYWVlZTkzNGI0YjhjZjNjNGYwOTk4ZTFiZTIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43OTQyMDAzLC03OS4yNjIwMjk0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjU0OWM2ZGJiMGQyNDcxYmI2ZmEwMmE2ZTIwMWJjMWUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMzJjMzFiNzk5ZmQxNGQ3YmJmMTc5MWU5NWIzMzQ1ZDAgPSAkKCc8ZGl2IGlkPSJodG1sXzMyYzMxYjc5OWZkMTRkN2JiZjE3OTFlOTViMzM0NWQwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BZ2luY291cnQgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82NTQ5YzZkYmIwZDI0NzFiYjZmYTAyYTZlMjAxYmMxZS5zZXRDb250ZW50KGh0bWxfMzJjMzFiNzk5ZmQxNGQ3YmJmMTc5MWU5NWIzMzQ1ZDApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMDY0NzIzYWVlZTkzNGI0YjhjZjNjNGYwOTk4ZTFiZTIuYmluZFBvcHVwKHBvcHVwXzY1NDljNmRiYjBkMjQ3MWJiNmZhMDJhNmUyMDFiYzFlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzVjY2FjZDY4ZjE1MzRlODc5MWI2ODk0ZmZkMWY2YzViID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzgxNjM3NSwtNzkuMzA0MzAyMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNWJmMmI1ODAyMGU5NGFlNjlkZTJiYTQyZDM5YzQ1YjUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmQ5ODY2YjBiMWMwNGU5YjljYzgwNDRhZTNiNmExZTUgPSAkKCc8ZGl2IGlkPSJodG1sXzJkOTg2NmIwYjFjMDRlOWI5Y2M4MDQ0YWUzYjZhMWU1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DbGFya3MgQ29ybmVycywgU3VsbGl2YW4sIFRhbSBPJiMzOTtTaGFudGVyIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNWJmMmI1ODAyMGU5NGFlNjlkZTJiYTQyZDM5YzQ1YjUuc2V0Q29udGVudChodG1sXzJkOTg2NmIwYjFjMDRlOWI5Y2M4MDQ0YWUzYjZhMWU1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzVjY2FjZDY4ZjE1MzRlODc5MWI2ODk0ZmZkMWY2YzViLmJpbmRQb3B1cChwb3B1cF81YmYyYjU4MDIwZTk0YWU2OWRlMmJhNDJkMzljNDViNSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xZDE1M2NhNGY1OWY0N2Q1OWM2ZDFhYmZhM2M5Nzc3OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgxNTI1MjIsLTc5LjI4NDU3NzJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAib3JhbmdlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAib3JhbmdlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzNjYmI4ZjUzYTQ2MzQ0YzM5YmRmNjNjZDlkYjM0NmFkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2FmYzVjNmU3ZWZlYTRhMWJiMzIzMjYxNDMzMjk3NjNmID0gJCgnPGRpdiBpZD0iaHRtbF9hZmM1YzZlN2VmZWE0YTFiYjMyMzI2MTQzMzI5NzYzZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWdpbmNvdXJ0IE5vcnRoLCBMJiMzOTtBbW9yZWF1eCBFYXN0LCBNaWxsaWtlbiwgU3RlZWxlcyBFYXN0IENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfM2NiYjhmNTNhNDYzNDRjMzliZGY2M2NkOWRiMzQ2YWQuc2V0Q29udGVudChodG1sX2FmYzVjNmU3ZWZlYTRhMWJiMzIzMjYxNDMzMjk3NjNmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzFkMTUzY2E0ZjU5ZjQ3ZDU5YzZkMWFiZmEzYzk3Nzc4LmJpbmRQb3B1cChwb3B1cF8zY2JiOGY1M2E0NjM0NGMzOWJkZjYzY2Q5ZGIzNDZhZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wZDM5OWI0ZTMwNDg0ZDg4ODcwYjZkYmJhNjk2NGZhMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5OTUyNTIwMDAwMDAwNSwtNzkuMzE4Mzg4N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNGMzY2NhZjhiMDUzNGVkNmJhYmZkYTdkNGJhZjg5N2QgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGEwZTEyMzZmY2VkNGEyY2JiY2Y5NzY3ZmU4MGZjZDQgPSAkKCc8ZGl2IGlkPSJodG1sXzBhMGUxMjM2ZmNlZDRhMmNiYmNmOTc2N2ZlODBmY2Q0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MJiMzOTtBbW9yZWF1eCBXZXN0LCBTdGVlbGVzIFdlc3QgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80YzNjY2FmOGIwNTM0ZWQ2YmFiZmRhN2Q0YmFmODk3ZC5zZXRDb250ZW50KGh0bWxfMGEwZTEyMzZmY2VkNGEyY2JiY2Y5NzY3ZmU4MGZjZDQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMGQzOTliNGUzMDQ4NGQ4ODg3MGI2ZGJiYTY5NjRmYTAuYmluZFBvcHVwKHBvcHVwXzRjM2NjYWY4YjA1MzRlZDZiYWJmZGE3ZDRiYWY4OTdkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzJjODI2ZGFmMTlmMTRkYzY5NzU1OTY0MTc3Mzg4ZTQwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuODAzNzYyMiwtNzkuMzYzNDUxN10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzAzMjQ5ZGEzOTVhNGU1Zjg5YjViNTNjYzM4MGVlYWQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOGJmYmI0MmMwMWJiNDc5N2EwN2Y4YTNkOTM5ZDRkNzIgPSAkKCc8ZGl2IGlkPSJodG1sXzhiZmJiNDJjMDFiYjQ3OTdhMDdmOGEzZDkzOWQ0ZDcyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IaWxsY3Jlc3QgVmlsbGFnZSBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2MwMzI0OWRhMzk1YTRlNWY4OWI1YjUzY2MzODBlZWFkLnNldENvbnRlbnQoaHRtbF84YmZiYjQyYzAxYmI0Nzk3YTA3ZjhhM2Q5MzlkNGQ3Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yYzgyNmRhZjE5ZjE0ZGM2OTc1NTk2NDE3NzM4OGU0MC5iaW5kUG9wdXAocG9wdXBfYzAzMjQ5ZGEzOTVhNGU1Zjg5YjViNTNjYzM4MGVlYWQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZWJjY2E5NDkwMmM5NGMwZWEwNGI1NmU2MjgxNmI3MTcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Nzg1MTc1LC03OS4zNDY1NTU3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jNjk0ZWU2YWE2Yjc0MzY4YjMwZTIwODcyZGYyYjExNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kMWYyNWU3OTEyNDk0MDQ1YTA1NjNlOTE0ZWUxMWQyYyA9ICQoJzxkaXYgaWQ9Imh0bWxfZDFmMjVlNzkxMjQ5NDA0NWEwNTYzZTkxNGVlMTFkMmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZhaXJ2aWV3LCBIZW5yeSBGYXJtLCBPcmlvbGUgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jNjk0ZWU2YWE2Yjc0MzY4YjMwZTIwODcyZGYyYjExNC5zZXRDb250ZW50KGh0bWxfZDFmMjVlNzkxMjQ5NDA0NWEwNTYzZTkxNGVlMTFkMmMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZWJjY2E5NDkwMmM5NGMwZWEwNGI1NmU2MjgxNmI3MTcuYmluZFBvcHVwKHBvcHVwX2M2OTRlZTZhYTZiNzQzNjhiMzBlMjA4NzJkZjJiMTE0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ1ZGU5NGY1NmJiZDQzMGY5NDUzZTAyMmUwYWE0YmI2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg2OTQ3MywtNzkuMzg1OTc1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hYzI2ZDBjZmIzODk0MjZkYjY3NGE5MjI5ZGM0Njk2YiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mMGIwM2U3YjQ5ZWY0M2MyYWJhMzI3MzFhNzA3MjkxNCA9ICQoJzxkaXYgaWQ9Imh0bWxfZjBiMDNlN2I0OWVmNDNjMmFiYTMyNzMxYTcwNzI5MTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJheXZpZXcgVmlsbGFnZSBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FjMjZkMGNmYjM4OTQyNmRiNjc0YTkyMjlkYzQ2OTZiLnNldENvbnRlbnQoaHRtbF9mMGIwM2U3YjQ5ZWY0M2MyYWJhMzI3MzFhNzA3MjkxNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80NWRlOTRmNTZiYmQ0MzBmOTQ1M2UwMjJlMGFhNGJiNi5iaW5kUG9wdXAocG9wdXBfYWMyNmQwY2ZiMzg5NDI2ZGI2NzRhOTIyOWRjNDY5NmIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzBmZGI3MzJhZDZiNDdmMmE4MmUzYzQ4NjU0ODFhZWEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTc0OTAyLC03OS4zNzQ3MTQwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTAxNDY4NGQ5MTRiNGVlYjk0ODBjMzljMmVjNzE3MDIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTA0NzE2MjA1M2U1NDI5NmIyOTA1Zjg0ODVhODA5NjkgPSAkKCc8ZGl2IGlkPSJodG1sX2UwNDcxNjIwNTNlNTQyOTZiMjkwNWY4NDg1YTgwOTY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TaWx2ZXIgSGlsbHMsIFlvcmsgTWlsbHMgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85MDE0Njg0ZDkxNGI0ZWViOTQ4MGMzOWMyZWM3MTcwMi5zZXRDb250ZW50KGh0bWxfZTA0NzE2MjA1M2U1NDI5NmIyOTA1Zjg0ODVhODA5NjkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYzBmZGI3MzJhZDZiNDdmMmE4MmUzYzQ4NjU0ODFhZWEuYmluZFBvcHVwKHBvcHVwXzkwMTQ2ODRkOTE0YjRlZWI5NDgwYzM5YzJlYzcxNzAyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2U1YmIwNjBlYzIyMTQwOTViZjE2ZTI0YThjZWVjMjA5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzcwMTE5OSwtNzkuNDA4NDkyNzk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQzZjQyOWZjNGZmOTQ1YmViNzYzMmQ3MDk2YTNjMGVmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2JkZDg5MGZmNDFmZDRmNmI5MTVmNGQ4ODI2Y2ZhZmJkID0gJCgnPGRpdiBpZD0iaHRtbF9iZGQ4OTBmZjQxZmQ0ZjZiOTE1ZjRkODgyNmNmYWZiZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSBTb3V0aCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQzZjQyOWZjNGZmOTQ1YmViNzYzMmQ3MDk2YTNjMGVmLnNldENvbnRlbnQoaHRtbF9iZGQ4OTBmZjQxZmQ0ZjZiOTE1ZjRkODgyNmNmYWZiZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lNWJiMDYwZWMyMjE0MDk1YmYxNmUyNGE4Y2VlYzIwOS5iaW5kUG9wdXAocG9wdXBfNDNmNDI5ZmM0ZmY5NDViZWI3NjMyZDcwOTZhM2MwZWYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfY2EyNzJlMjJmZjc5NGNlYzkzMTg2ZmQ2NDM1ZDM2YmMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTI3NTgyOTk5OTk5OTYsLTc5LjQwMDA0OTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAieWVsbG93IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAieWVsbG93IiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2U0YTUwNGYyMjM1YjQzZTlhYjVhODA5ZjViOTAwZjRmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzg3MTVhZTJiNmJlMTRlMjliNzM2ZWU4NTMxZjc4M2IwID0gJCgnPGRpdiBpZD0iaHRtbF84NzE1YWUyYjZiZTE0ZTI5YjczNmVlODUzMWY3ODNiMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+WW9yayBNaWxscyBXZXN0IENsdXN0ZXIgMzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTRhNTA0ZjIyMzViNDNlOWFiNWE4MDlmNWI5MDBmNGYuc2V0Q29udGVudChodG1sXzg3MTVhZTJiNmJlMTRlMjliNzM2ZWU4NTMxZjc4M2IwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2NhMjcyZTIyZmY3OTRjZWM5MzE4NmZkNjQzNWQzNmJjLmJpbmRQb3B1cChwb3B1cF9lNGE1MDRmMjIzNWI0M2U5YWI1YTgwOWY1YjkwMGY0Zik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hZGNiZGVhNjgzYjI0Yzk4OThiMjRmZmVkOThkZmJjNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4MjczNjQsLTc5LjQ0MjI1OTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzkxZjVhYzBlZmU0OTQzNGU5MThkNmE1NTk1MTMzY2ZmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2MzZWUxNzA5MjgwYzQ4OGE4NDM5YmYzNTg5YWU3N2MyID0gJCgnPGRpdiBpZD0iaHRtbF9jM2VlMTcwOTI4MGM0ODhhODQzOWJmMzU4OWFlNzdjMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSBXZXN0IENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTFmNWFjMGVmZTQ5NDM0ZTkxOGQ2YTU1OTUxMzNjZmYuc2V0Q29udGVudChodG1sX2MzZWUxNzA5MjgwYzQ4OGE4NDM5YmYzNTg5YWU3N2MyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2FkY2JkZWE2ODNiMjRjOTg5OGIyNGZmZWQ5OGRmYmM0LmJpbmRQb3B1cChwb3B1cF85MWY1YWMwZWZlNDk0MzRlOTE4ZDZhNTU5NTEzM2NmZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80NDMzZDMzMDc4OTE0MDQ4ODFlNGZmYmY0MGQ3M2NhZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1MzI1ODYsLTc5LjMyOTY1NjVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAieWVsbG93IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAieWVsbG93IiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzA4NWNkZGZkZmM0OTRhOWNhYmZlYjZmNzA2ZGRlZGNkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2Q1YzQxMmMzOGYzYzQ0YzdiNjNhOGY1ZTE0M2Q3MGFmID0gJCgnPGRpdiBpZD0iaHRtbF9kNWM0MTJjMzhmM2M0NGM3YjYzYThmNWUxNDNkNzBhZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGFya3dvb2RzIENsdXN0ZXIgMzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDg1Y2RkZmRmYzQ5NGE5Y2FiZmViNmY3MDZkZGVkY2Quc2V0Q29udGVudChodG1sX2Q1YzQxMmMzOGYzYzQ0YzdiNjNhOGY1ZTE0M2Q3MGFmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzQ0MzNkMzMwNzg5MTQwNDg4MWU0ZmZiZjQwZDczY2FlLmJpbmRQb3B1cChwb3B1cF8wODVjZGRmZGZjNDk0YTljYWJmZWI2ZjcwNmRkZWRjZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yMTA0NmI2NTNkY2I0OTIzYWZkOWEzZmYxMjA2Njk0NSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc0NTkwNTc5OTk5OTk5NiwtNzkuMzUyMTg4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iNWJhNTJiZGQ4YmI0ZmVlODFlNzMyZmIzNDYwNDE1MSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yZmRmNjUwNWUzZTI0ODIxOTAyZTg0N2RhYzdjYWNiYSA9ICQoJzxkaXYgaWQ9Imh0bWxfMmZkZjY1MDVlM2UyNDgyMTkwMmU4NDdkYWM3Y2FjYmEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvbiBNaWxscyBOb3J0aCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I1YmE1MmJkZDhiYjRmZWU4MWU3MzJmYjM0NjA0MTUxLnNldENvbnRlbnQoaHRtbF8yZmRmNjUwNWUzZTI0ODIxOTAyZTg0N2RhYzdjYWNiYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yMTA0NmI2NTNkY2I0OTIzYWZkOWEzZmYxMjA2Njk0NS5iaW5kUG9wdXAocG9wdXBfYjViYTUyYmRkOGJiNGZlZTgxZTczMmZiMzQ2MDQxNTEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOWEwNGJiOTE1NTBhNGI3Nzk0OGQ2NzE2M2I0ZDZjMDQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjU4OTk3MDAwMDAwMSwtNzkuMzQwOTIzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iMDk4MzI1OTRiMjE0YTgxOGZlYThjNWUxOGY1NGQwOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82NjRjOTFjYzNjNmM0Yjc3ODJlYjk2MTFkZDhhOTE2MiA9ICQoJzxkaXYgaWQ9Imh0bWxfNjY0YzkxY2MzYzZjNGI3NzgyZWI5NjExZGQ4YTkxNjIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZsZW1pbmdkb24gUGFyaywgRG9uIE1pbGxzIFNvdXRoIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjA5ODMyNTk0YjIxNGE4MThmZWE4YzVlMThmNTRkMDkuc2V0Q29udGVudChodG1sXzY2NGM5MWNjM2M2YzRiNzc4MmViOTYxMWRkOGE5MTYyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzlhMDRiYjkxNTUwYTRiNzc5NDhkNjcxNjNiNGQ2YzA0LmJpbmRQb3B1cChwb3B1cF9iMDk4MzI1OTRiMjE0YTgxOGZlYThjNWUxOGY1NGQwOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84NjMyMWQ2NDg3ZDA0YWU5YTc5YTllY2I3MjVlZjM1NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NDMyODMsLTc5LjQ0MjI1OTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzIwMjQ2OTJhZDdiMDQyYTBiNTI1ZjYwZjRhZGQ5ZGZhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzNiZGUzYTdmZjg2NjQzMzg5MjI2NTQ4NzBiYzA4M2EzID0gJCgnPGRpdiBpZD0iaHRtbF8zYmRlM2E3ZmY4NjY0MzM4OTIyNjU0ODcwYmMwODNhMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmF0aHVyc3QgTWFub3IsIERvd25zdmlldyBOb3J0aCwgV2lsc29uIEhlaWdodHMgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yMDI0NjkyYWQ3YjA0MmEwYjUyNWY2MGY0YWRkOWRmYS5zZXRDb250ZW50KGh0bWxfM2JkZTNhN2ZmODY2NDMzODkyMjY1NDg3MGJjMDgzYTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfODYzMjFkNjQ4N2QwNGFlOWE3OWE5ZWNiNzI1ZWYzNTcuYmluZFBvcHVwKHBvcHVwXzIwMjQ2OTJhZDdiMDQyYTBiNTI1ZjYwZjRhZGQ5ZGZhKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzEwNTdmMmZiMDgxZjRjZThiODI2MWFhM2I1NGEzYjZkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzY3OTgwMywtNzkuNDg3MjYxOTAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzY5M2MwZDgwMGU3ZjRhMjVhNzUxZGE0NmNjNWMxYWMyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhjZWFjZTQ4YzA2ODRhMTZiYWFhMDE5YThiNjIwOTFmID0gJCgnPGRpdiBpZD0iaHRtbF84Y2VhY2U0OGMwNjg0YTE2YmFhYTAxOWE4YjYyMDkxZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGh3b29kIFBhcmssIFlvcmsgVW5pdmVyc2l0eSBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzY5M2MwZDgwMGU3ZjRhMjVhNzUxZGE0NmNjNWMxYWMyLnNldENvbnRlbnQoaHRtbF84Y2VhY2U0OGMwNjg0YTE2YmFhYTAxOWE4YjYyMDkxZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xMDU3ZjJmYjA4MWY0Y2U4YjgyNjFhYTNiNTRhM2I2ZC5iaW5kUG9wdXAocG9wdXBfNjkzYzBkODAwZTdmNGEyNWE3NTFkYTQ2Y2M1YzFhYzIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDdlZjEzZTIxZjNmNGQ2OWI2MDg4N2JhNWU5M2QzMGIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mzc0NzMyMDAwMDAwMDQsLTc5LjQ2NDc2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInllbGxvdyIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInllbGxvdyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jNmVjYjhkMGU4YzU0ZWMyYTE1Mjg2OWRiYWNiOTIyMSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jODE5ZGViNzdlYzA0N2UzYjhiOTE3NzU1ZjRjZThmMiA9ICQoJzxkaXYgaWQ9Imh0bWxfYzgxOWRlYjc3ZWMwNDdlM2I4YjkxNzc1NWY0Y2U4ZjIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNGQiBUb3JvbnRvLCBEb3duc3ZpZXcgRWFzdCBDbHVzdGVyIDM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M2ZWNiOGQwZThjNTRlYzJhMTUyODY5ZGJhY2I5MjIxLnNldENvbnRlbnQoaHRtbF9jODE5ZGViNzdlYzA0N2UzYjhiOTE3NzU1ZjRjZThmMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8wN2VmMTNlMjFmM2Y0ZDY5YjYwODg3YmE1ZTkzZDMwYi5iaW5kUG9wdXAocG9wdXBfYzZlY2I4ZDBlOGM1NGVjMmExNTI4NjlkYmFjYjkyMjEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTdiODliMzk5MGRmNDY3OWFmYzJiY2U5ZThjMDI1NWEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MzkwMTQ2LC03OS41MDY5NDM2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInllbGxvdyIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInllbGxvdyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yNGM4ZTY1OTM1MmI0ZGQwOGJkMGI2NDIzYzU5ZDQ5MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iMDc3NjA3YWYzY2E0MjEyODdiODRhNjU5NDAyZjk2MiA9ICQoJzxkaXYgaWQ9Imh0bWxfYjA3NzYwN2FmM2NhNDIxMjg3Yjg0YTY1OTQwMmY5NjIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldyBXZXN0IENsdXN0ZXIgMzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMjRjOGU2NTkzNTJiNGRkMDhiZDBiNjQyM2M1OWQ0OTMuc2V0Q29udGVudChodG1sX2IwNzc2MDdhZjNjYTQyMTI4N2I4NGE2NTk0MDJmOTYyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2U3Yjg5YjM5OTBkZjQ2NzlhZmMyYmNlOWU4YzAyNTVhLmJpbmRQb3B1cChwb3B1cF8yNGM4ZTY1OTM1MmI0ZGQwOGJkMGI2NDIzYzU5ZDQ5Myk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zMjE3YjQ2MDlmYmU0YWU5ODk4OGI5NzhmMjFiZjFiZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcyODQ5NjQsLTc5LjQ5NTY5NzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80ZWMzNGNiOTlhYzQ0N2MyYjQ2ZDk5OTc0YzAxNTM4OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85NjhhZDNhYTE1YTY0ZjE1YTQyZTRhMjU0NmFhZDU5NCA9ICQoJzxkaXYgaWQ9Imh0bWxfOTY4YWQzYWExNWE2NGYxNWE0MmU0YTI1NDZhYWQ1OTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldyBDZW50cmFsIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNGVjMzRjYjk5YWM0NDdjMmI0NmQ5OTk3NGMwMTUzODguc2V0Q29udGVudChodG1sXzk2OGFkM2FhMTVhNjRmMTVhNDJlNGEyNTQ2YWFkNTk0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzMyMTdiNDYwOWZiZTRhZTk4OTg4Yjk3OGYyMWJmMWJmLmJpbmRQb3B1cChwb3B1cF80ZWMzNGNiOTlhYzQ0N2MyYjQ2ZDk5OTc0YzAxNTM4OCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YTQ3Njg2YjkwNmQ0YzM5YTZlZTJmMzUyMmRiM2I1OSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2MTYzMTMsLTc5LjUyMDk5OTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80OGY4MDJmZTRmZDc0MjYyOTJhY2NmZWM2ZjVlMDI1NSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xMTNkNDEwNWMwYzE0NmI0YmYxZDliZGQzZDU5NjE5YyA9ICQoJzxkaXYgaWQ9Imh0bWxfMTEzZDQxMDVjMGMxNDZiNGJmMWQ5YmRkM2Q1OTYxOWMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldyBOb3J0aHdlc3QgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80OGY4MDJmZTRmZDc0MjYyOTJhY2NmZWM2ZjVlMDI1NS5zZXRDb250ZW50KGh0bWxfMTEzZDQxMDVjMGMxNDZiNGJmMWQ5YmRkM2Q1OTYxOWMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOWE0NzY4NmI5MDZkNGMzOWE2ZWUyZjM1MjJkYjNiNTkuYmluZFBvcHVwKHBvcHVwXzQ4ZjgwMmZlNGZkNzQyNjI5MmFjY2ZlYzZmNWUwMjU1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzk5NzA0NzIwZGJmYzQ4YjNhY2M3YzQwZmU0N2EwYTA2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI1ODgyMjk5OTk5OTk1LC03OS4zMTU1NzE1OTk5OTk5OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjI0NzJiOTJlNTgwNDVhYjlkYTZjYjY1MGY2MmQyNTYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYWYxNjEwNjAyYjI2NDI1NTk0Y2QwZWFhNTU4MTg5OTMgPSAkKCc8ZGl2IGlkPSJodG1sX2FmMTYxMDYwMmIyNjQyNTU5NGNkMGVhYTU1ODE4OTkzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5WaWN0b3JpYSBWaWxsYWdlIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMjI0NzJiOTJlNTgwNDVhYjlkYTZjYjY1MGY2MmQyNTYuc2V0Q29udGVudChodG1sX2FmMTYxMDYwMmIyNjQyNTU5NGNkMGVhYTU1ODE4OTkzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzk5NzA0NzIwZGJmYzQ4YjNhY2M3YzQwZmU0N2EwYTA2LmJpbmRQb3B1cChwb3B1cF8yMjQ3MmI5MmU1ODA0NWFiOWRhNmNiNjUwZjYyZDI1Nik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84Y2Y2NjAwMDljMTk0MWU0YTdlY2QyYjlmN2I0N2I1ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNjM5NzIsLTc5LjMwOTkzN10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTdmNmJjYzhkNGQ2NDJlNjg5YTE1NDA3NGJmNTE0YzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODA3NjJjZTc5M2ZlNGY5YTg1MjZkYjFhMzFhY2QzNjQgPSAkKCc8ZGl2IGlkPSJodG1sXzgwNzYyY2U3OTNmZTRmOWE4NTI2ZGIxYTMxYWNkMzY0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb29kYmluZSBHYXJkZW5zLCBQYXJrdmlldyBIaWxsIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTdmNmJjYzhkNGQ2NDJlNjg5YTE1NDA3NGJmNTE0YzIuc2V0Q29udGVudChodG1sXzgwNzYyY2U3OTNmZTRmOWE4NTI2ZGIxYTMxYWNkMzY0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzhjZjY2MDAwOWMxOTQxZTRhN2VjZDJiOWY3YjQ3YjVlLmJpbmRQb3B1cChwb3B1cF9hN2Y2YmNjOGQ0ZDY0MmU2ODlhMTU0MDc0YmY1MTRjMik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81OGIxZGRhY2I3YWM0Y2VmODRhZjhhNzc1MmFlNWQ3NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5NTM0MzkwMDAwMDAwNSwtNzkuMzE4Mzg4N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjhmZGQxYjNjZDlkNDFmZmJlMTAwMWQ5MGJjYTQ1ZTYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2QxOWVhZDZlZjM4NGY2NDhjZWIzMzg4ODVhZTk1YWUgPSAkKCc8ZGl2IGlkPSJodG1sX2NkMTllYWQ2ZWYzODRmNjQ4Y2ViMzM4ODg1YWU5NWFlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb29kYmluZSBIZWlnaHRzIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjhmZGQxYjNjZDlkNDFmZmJlMTAwMWQ5MGJjYTQ1ZTYuc2V0Q29udGVudChodG1sX2NkMTllYWQ2ZWYzODRmNjQ4Y2ViMzM4ODg1YWU5NWFlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU4YjFkZGFjYjdhYzRjZWY4NGFmOGE3NzUyYWU1ZDc3LmJpbmRQb3B1cChwb3B1cF9iOGZkZDFiM2NkOWQ0MWZmYmUxMDAxZDkwYmNhNDVlNik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kZTMxZDVmYWUxMGQ0MDg0YjhjZDg0ODRkYWYzODM2MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3NjM1NzM5OTk5OTk5LC03OS4yOTMwMzEyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iM2Q3N2NjNjY5OWE0NTU2OThkODUxMWY0YjFkZmFlMyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iOTA3MmE2Mjc2NDY0ZWExOTg1N2YzYzNlYjJkNjY1OSA9ICQoJzxkaXYgaWQ9Imh0bWxfYjkwNzJhNjI3NjQ2NGVhMTk4NTdmM2MzZWIyZDY2NTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRoZSBCZWFjaGVzIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjNkNzdjYzY2OTlhNDU1Njk4ZDg1MTFmNGIxZGZhZTMuc2V0Q29udGVudChodG1sX2I5MDcyYTYyNzY0NjRlYTE5ODU3ZjNjM2ViMmQ2NjU5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2RlMzFkNWZhZTEwZDQwODRiOGNkODQ4NGRhZjM4MzYyLmJpbmRQb3B1cChwb3B1cF9iM2Q3N2NjNjY5OWE0NTU2OThkODUxMWY0YjFkZmFlMyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zYTJiMTJkN2VkZGI0OGRmYTM0NjE0M2VlZDM4MmNiYyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTA2MDQsLTc5LjM2MzQ1MTddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzg3NGU1NGIwNmM0MTQwN2JiNmViMWViZTg1NTBkN2FhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzRkOGRlZjc2ZDNmMDQyMjNhNDU1NmRmZTc1ZmQ5N2UyID0gJCgnPGRpdiBpZD0iaHRtbF80ZDhkZWY3NmQzZjA0MjIzYTQ1NTZkZmU3NWZkOTdlMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TGVhc2lkZSBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzg3NGU1NGIwNmM0MTQwN2JiNmViMWViZTg1NTBkN2FhLnNldENvbnRlbnQoaHRtbF80ZDhkZWY3NmQzZjA0MjIzYTQ1NTZkZmU3NWZkOTdlMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8zYTJiMTJkN2VkZGI0OGRmYTM0NjE0M2VlZDM4MmNiYy5iaW5kUG9wdXAocG9wdXBfODc0ZTU0YjA2YzQxNDA3YmI2ZWIxZWJlODU1MGQ3YWEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWViYWI2NmNmNmYxNDc3YmJiMzIzNTFjOTQxZjYzNmEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDUzNjg5LC03OS4zNDkzNzE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMDA0Y2Q2M2E0MDczNDJmNDkxNWUzMTc5MmY3OTkzNjQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOGI2MmZhOGEyYjYwNGRiZjliYjRmN2VmMzE1ZGZlYmMgPSAkKCc8ZGl2IGlkPSJodG1sXzhiNjJmYThhMmI2MDRkYmY5YmI0ZjdlZjMxNWRmZWJjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaG9ybmNsaWZmZSBQYXJrIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDA0Y2Q2M2E0MDczNDJmNDkxNWUzMTc5MmY3OTkzNjQuc2V0Q29udGVudChodG1sXzhiNjJmYThhMmI2MDRkYmY5YmI0ZjdlZjMxNWRmZWJjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzFlYmFiNjZjZjZmMTQ3N2JiYjMyMzUxYzk0MWY2MzZhLmJpbmRQb3B1cChwb3B1cF8wMDRjZDYzYTQwNzM0MmY0OTE1ZTMxNzkyZjc5OTM2NCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lMWRhNzg4MmU1YjY0MmNlOWQ4NzU0ZmFhZDY2Mjc0NCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4NTM0NywtNzkuMzM4MTA2NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJ5ZWxsb3ciLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJ5ZWxsb3ciLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjQyNDhmM2EwMjIyNDU4ZmI1NWFiZjFkZTkxNmY5MzYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmZlM2M5Nzk0NDZlNDBmNGIyNDdjMTU4NTRhNDBiNGUgPSAkKCc8ZGl2IGlkPSJodG1sX2ZmZTNjOTc5NDQ2ZTQwZjRiMjQ3YzE1ODU0YTQwYjRlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5FYXN0IFRvcm9udG8gQ2x1c3RlciAzPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82NDI0OGYzYTAyMjI0NThmYjU1YWJmMWRlOTE2ZjkzNi5zZXRDb250ZW50KGh0bWxfZmZlM2M5Nzk0NDZlNDBmNGIyNDdjMTU4NTRhNDBiNGUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZTFkYTc4ODJlNWI2NDJjZTlkODc1NGZhYWQ2NjI3NDQuYmluZFBvcHVwKHBvcHVwXzY0MjQ4ZjNhMDIyMjQ1OGZiNTVhYmYxZGU5MTZmOTM2KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2IzMDc3ODFlY2E3NzQ2Y2I5MmYwNThhMDBlMGM5MDUyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjc5NTU3MSwtNzkuMzUyMTg4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83MjUyZGQwY2RmN2Q0MWYxOGNmOTgyYTk3ZTlmYTdkOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82NWJiNDEzZjhmNTk0ZTc3YTY2YWYzNjJkOWMzYzg5NiA9ICQoJzxkaXYgaWQ9Imh0bWxfNjViYjQxM2Y4ZjU5NGU3N2E2NmFmMzYyZDljM2M4OTYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRoZSBEYW5mb3J0aCBXZXN0LCBSaXZlcmRhbGUgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83MjUyZGQwY2RmN2Q0MWYxOGNmOTgyYTk3ZTlmYTdkOS5zZXRDb250ZW50KGh0bWxfNjViYjQxM2Y4ZjU5NGU3N2E2NmFmMzYyZDljM2M4OTYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjMwNzc4MWVjYTc3NDZjYjkyZjA1OGEwMGUwYzkwNTIuYmluZFBvcHVwKHBvcHVwXzcyNTJkZDBjZGY3ZDQxZjE4Y2Y5ODJhOTdlOWZhN2Q5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzgyZjIwZjZjODA4YTRkMmQ5ZDlhODUxOWYyMzUyZGViID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY4OTk4NSwtNzkuMzE1NTcxNTk5OTk5OThdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2FhNjc2M2I4ZjEyNzQ1ODdhMzYxMmNiYzg5Yjc3NWMxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQ0ODA3MTljZDczYjRhMzM4ZDhlNDkwY2MwZjRjMDgwID0gJCgnPGRpdiBpZD0iaHRtbF80NDgwNzE5Y2Q3M2I0YTMzOGQ4ZTQ5MGNjMGY0YzA4MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEJlYWNoZXMgV2VzdCwgSW5kaWEgQmF6YWFyIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYWE2NzYzYjhmMTI3NDU4N2EzNjEyY2JjODliNzc1YzEuc2V0Q29udGVudChodG1sXzQ0ODA3MTljZDczYjRhMzM4ZDhlNDkwY2MwZjRjMDgwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzgyZjIwZjZjODA4YTRkMmQ5ZDlhODUxOWYyMzUyZGViLmJpbmRQb3B1cChwb3B1cF9hYTY3NjNiOGYxMjc0NTg3YTM2MTJjYmM4OWI3NzVjMSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wNjdiMzhlNzFhMjc0ZGYzOTIwZmUwOWIxMjllNWVhNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1OTUyNTUsLTc5LjM0MDkyM10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzkxMWUxNjJhNDBmNDIxYmFiZGRkOGJiYmNmYmI3NzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMWMwMTAzYjJmYzYyNDBiMmE5ZDI5MTAwYTQzM2Q0MWEgPSAkKCc8ZGl2IGlkPSJodG1sXzFjMDEwM2IyZmM2MjQwYjJhOWQyOTEwMGE0MzNkNDFhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdHVkaW8gRGlzdHJpY3QgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jOTExZTE2MmE0MGY0MjFiYWJkZGQ4YmJiY2ZiYjc3Mi5zZXRDb250ZW50KGh0bWxfMWMwMTAzYjJmYzYyNDBiMmE5ZDI5MTAwYTQzM2Q0MWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMDY3YjM4ZTcxYTI3NGRmMzkyMGZlMDliMTI5ZTVlYTYuYmluZFBvcHVwKHBvcHVwX2M5MTFlMTYyYTQwZjQyMWJhYmRkZDhiYmJjZmJiNzcyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ZkZGNhNzg2NTNhNDRiNTRhYWIwNDY3ZWE1ZWU4YjZiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI4MDIwNSwtNzkuMzg4NzkwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJ5ZWxsb3ciLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJ5ZWxsb3ciLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZWQzYTA3ODE5MDM1NGRmNzk2YjQ1Nzg5YzVmMDIyN2QgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMDA1M2UzZjhlZTIyNGYwOTk0ZDhiNzU0MWJjNjYzZTAgPSAkKCc8ZGl2IGlkPSJodG1sXzAwNTNlM2Y4ZWUyMjRmMDk5NGQ4Yjc1NDFiYzY2M2UwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MYXdyZW5jZSBQYXJrIENsdXN0ZXIgMzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZWQzYTA3ODE5MDM1NGRmNzk2YjQ1Nzg5YzVmMDIyN2Quc2V0Q29udGVudChodG1sXzAwNTNlM2Y4ZWUyMjRmMDk5NGQ4Yjc1NDFiYzY2M2UwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2ZkZGNhNzg2NTNhNDRiNTRhYWIwNDY3ZWE1ZWU4YjZiLmJpbmRQb3B1cChwb3B1cF9lZDNhMDc4MTkwMzU0ZGY3OTZiNDU3ODljNWYwMjI3ZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jZmM5MjBkZjQyYTk0MTY2OTIxN2M4N2RjNjQ1MjM2ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMjc1MTEsLTc5LjM5MDE5NzVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2EzMmZmNjdmZTFiMjRjNGE4NGQ0YWUwM2MwYzIwZGE4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzM5ZGQ1NTQzMDk2ZDQyMjM4MzE3YWQxNTYyMmE2NTUzID0gJCgnPGRpdiBpZD0iaHRtbF8zOWRkNTU0MzA5NmQ0MjIzODMxN2FkMTU2MjJhNjU1MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RGF2aXN2aWxsZSBOb3J0aCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2EzMmZmNjdmZTFiMjRjNGE4NGQ0YWUwM2MwYzIwZGE4LnNldENvbnRlbnQoaHRtbF8zOWRkNTU0MzA5NmQ0MjIzODMxN2FkMTU2MjJhNjU1Myk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jZmM5MjBkZjQyYTk0MTY2OTIxN2M4N2RjNjQ1MjM2ZS5iaW5kUG9wdXAocG9wdXBfYTMyZmY2N2ZlMWIyNGM0YTg0ZDRhZTAzYzBjMjBkYTgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTAyNmQzNzVhNTk4NDdiYThmNzFiNjA1ZjY4Yjk1OTcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTUzODM0LC03OS40MDU2Nzg0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2JjM2JiNGQ5NGE5NGRkYjgxYmJkMGMwOTY0ZTU1ZjMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNTI3YzlkYmFlZDljNDY5YjkyODJlZmQxYzdlYzA1NDcgPSAkKCc8ZGl2IGlkPSJodG1sXzUyN2M5ZGJhZWQ5YzQ2OWI5MjgyZWZkMWM3ZWMwNTQ3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aCBUb3JvbnRvIFdlc3QgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zYmMzYmI0ZDk0YTk0ZGRiODFiYmQwYzA5NjRlNTVmMy5zZXRDb250ZW50KGh0bWxfNTI3YzlkYmFlZDljNDY5YjkyODJlZmQxYzdlYzA1NDcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMTAyNmQzNzVhNTk4NDdiYThmNzFiNjA1ZjY4Yjk1OTcuYmluZFBvcHVwKHBvcHVwXzNiYzNiYjRkOTRhOTRkZGI4MWJiZDBjMDk2NGU1NWYzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBkOTM2ZGIzNjljOTQ0ZGNhMjg3ZmFmM2ZlNDI4YTEwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA0MzI0NCwtNzkuMzg4NzkwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjE4ZWE1NTU1YjM2NDcxODkxZDlmZjBlNGE1OGU5NjUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNWFhZGFiZmZmOTAyNGQwMjhhMDU0MWIxM2Q5NzdjNTYgPSAkKCc8ZGl2IGlkPSJodG1sXzVhYWRhYmZmZjkwMjRkMDI4YTA1NDFiMTNkOTc3YzU2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EYXZpc3ZpbGxlIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjE4ZWE1NTU1YjM2NDcxODkxZDlmZjBlNGE1OGU5NjUuc2V0Q29udGVudChodG1sXzVhYWRhYmZmZjkwMjRkMDI4YTA1NDFiMTNkOTc3YzU2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzBkOTM2ZGIzNjljOTQ0ZGNhMjg3ZmFmM2ZlNDI4YTEwLmJpbmRQb3B1cChwb3B1cF9iMThlYTU1NTViMzY0NzE4OTFkOWZmMGU0YTU4ZTk2NSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iOTZiNTQ0YmRmNTg0MWJmOWI5NGM4YjZiOWY2MjFkZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4OTU3NDMsLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80YzAzYjlkY2ZhMGY0ZDVmYTQzMWMwYTNmNmVmM2EwNiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mYTA5ZDg4YmNiNDE0ZTMyYjYzZDY2MDY3NmE5ODJjNyA9ICQoJzxkaXYgaWQ9Imh0bWxfZmEwOWQ4OGJjYjQxNGUzMmI2M2Q2NjA2NzZhOTgyYzciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1vb3JlIFBhcmssIFN1bW1lcmhpbGwgRWFzdCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzRjMDNiOWRjZmEwZjRkNWZhNDMxYzBhM2Y2ZWYzYTA2LnNldENvbnRlbnQoaHRtbF9mYTA5ZDg4YmNiNDE0ZTMyYjYzZDY2MDY3NmE5ODJjNyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iOTZiNTQ0YmRmNTg0MWJmOWI5NGM4YjZiOWY2MjFkZS5iaW5kUG9wdXAocG9wdXBfNGMwM2I5ZGNmYTBmNGQ1ZmE0MzFjMGEzZjZlZjNhMDYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGNkOWFiODQ2OTUxNGE2OWEyODVjODFlN2Q3YWM4OWUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODY0MTIyOTk5OTk5OSwtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTg5Y2Y1NDI0OWUwNDcwMDk5MDQxYmYwMmUwMTg1NWMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOWU4N2ViN2Y3YWIzNDEzY2EyMWJmZTg5YjA0YmUxMjIgPSAkKCc8ZGl2IGlkPSJodG1sXzllODdlYjdmN2FiMzQxM2NhMjFiZmU4OWIwNGJlMTIyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EZWVyIFBhcmssIEZvcmVzdCBIaWxsIFNFLCBSYXRobmVsbHksIFNvdXRoIEhpbGwsIFN1bW1lcmhpbGwgV2VzdCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzE4OWNmNTQyNDllMDQ3MDA5OTA0MWJmMDJlMDE4NTVjLnNldENvbnRlbnQoaHRtbF85ZTg3ZWI3ZjdhYjM0MTNjYTIxYmZlODliMDRiZTEyMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kY2Q5YWI4NDY5NTE0YTY5YTI4NWM4MWU3ZDdhYzg5ZS5iaW5kUG9wdXAocG9wdXBfMTg5Y2Y1NDI0OWUwNDcwMDk5MDQxYmYwMmUwMTg1NWMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzUxNjUyOGU0MmQ1NDUwYmFjMWVlOTk5YmE1NmFkN2EgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Nzk1NjI2LC03OS4zNzc1Mjk0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJvcmFuZ2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJvcmFuZ2UiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZmVkZTJjYzYxNzUwNGU1YjkyNjZiYTY3NWM0MzJhMjQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOGUxYTViNjdkOTQxNGEwMjgwMmU2OTUzMWE3MzdiM2UgPSAkKCc8ZGl2IGlkPSJodG1sXzhlMWE1YjY3ZDk0MTRhMDI4MDJlNjk1MzFhNzM3YjNlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3NlZGFsZSBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2ZlZGUyY2M2MTc1MDRlNWI5MjY2YmE2NzVjNDMyYTI0LnNldENvbnRlbnQoaHRtbF84ZTFhNWI2N2Q5NDE0YTAyODAyZTY5NTMxYTczN2IzZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jNTE2NTI4ZTQyZDU0NTBiYWMxZWU5OTliYTU2YWQ3YS5iaW5kUG9wdXAocG9wdXBfZmVkZTJjYzYxNzUwNGU1YjkyNjZiYTY3NWM0MzJhMjQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjgwN2MwNzQ0ZGY5NDc0MWE0NGMxNGQ3N2EyZjcxMDMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Njc5NjcsLTc5LjM2NzY3NTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzYwNTEyMzE4YjVmZTRiZDdiZTI4Y2E4ZWE1YjVlMGVmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzI5NDJlYmM3Nzg5ZTQ2NmI4NGIxYWIxMmM3ZWNlNWExID0gJCgnPGRpdiBpZD0iaHRtbF8yOTQyZWJjNzc4OWU0NjZiODRiMWFiMTJjN2VjZTVhMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2FiYmFnZXRvd24sIFN0LiBKYW1lcyBUb3duIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjA1MTIzMThiNWZlNGJkN2JlMjhjYThlYTViNWUwZWYuc2V0Q29udGVudChodG1sXzI5NDJlYmM3Nzg5ZTQ2NmI4NGIxYWIxMmM3ZWNlNWExKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2I4MDdjMDc0NGRmOTQ3NDFhNDRjMTRkNzdhMmY3MTAzLmJpbmRQb3B1cChwb3B1cF82MDUxMjMxOGI1ZmU0YmQ3YmUyOGNhOGVhNWI1ZTBlZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iYjc5NDViZTExM2M0NDUwYmE3ZTE5NjIyM2M2YTdmNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2NTg1OTksLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81MDAyOWQ4ODkzYzU0ZWY1ODVhNTJlZjA3MmMyYzViNiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80MTYyOGE3NGU0MDU0Zjk2YjA5MThlYTMwZDQwYjNhZSA9ICQoJzxkaXYgaWQ9Imh0bWxfNDE2MjhhNzRlNDA1NGY5NmIwOTE4ZWEzMGQ0MGIzYWUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNodXJjaCBhbmQgV2VsbGVzbGV5IENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTAwMjlkODg5M2M1NGVmNTg1YTUyZWYwNzJjMmM1YjYuc2V0Q29udGVudChodG1sXzQxNjI4YTc0ZTQwNTRmOTZiMDkxOGVhMzBkNDBiM2FlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2JiNzk0NWJlMTEzYzQ0NTBiYTdlMTk2MjIzYzZhN2Y3LmJpbmRQb3B1cChwb3B1cF81MDAyOWQ4ODkzYzU0ZWY1ODVhNTJlZjA3MmMyYzViNik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82MGEyOTNmMDkyNTY0MDBkOGQ4ZDAxNDcyYjYzOTIzYSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1NDI1OTksLTc5LjM2MDYzNTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzhmYjk4ZjFjMjc0YzRmNzI4YjM2Mzc1YTlkZGUyNWZhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzcxOTAxMWMzNDIwNTQzNDU4M2MwNGZjNzNiY2JhM2Q0ID0gJCgnPGRpdiBpZD0iaHRtbF83MTkwMTFjMzQyMDU0MzQ1ODNjMDRmYzczYmNiYTNkNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGFyYm91cmZyb250LCBSZWdlbnQgUGFyayBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzhmYjk4ZjFjMjc0YzRmNzI4YjM2Mzc1YTlkZGUyNWZhLnNldENvbnRlbnQoaHRtbF83MTkwMTFjMzQyMDU0MzQ1ODNjMDRmYzczYmNiYTNkNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl82MGEyOTNmMDkyNTY0MDBkOGQ4ZDAxNDcyYjYzOTIzYS5iaW5kUG9wdXAocG9wdXBfOGZiOThmMWMyNzRjNGY3MjhiMzYzNzVhOWRkZTI1ZmEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTcxMWYxZDkyMTFiNGJmNTk2ZGZmZmYyMmJjZmE3NzMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTcxNjE4LC03OS4zNzg5MzcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZmYzZWQ1Y2Q5YzY0NGU3NDhhY2MyYjlkYzA4MDQxYTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjAyOWM4Yjk4OTYwNDMwNDgwM2QwM2ZiOGI3N2RhOWYgPSAkKCc8ZGl2IGlkPSJodG1sX2YwMjljOGI5ODk2MDQzMDQ4MDNkMDNmYjhiNzdkYTlmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SeWVyc29uLCBHYXJkZW4gRGlzdHJpY3QgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mZjNlZDVjZDljNjQ0ZTc0OGFjYzJiOWRjMDgwNDFhMi5zZXRDb250ZW50KGh0bWxfZjAyOWM4Yjk4OTYwNDMwNDgwM2QwM2ZiOGI3N2RhOWYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMTcxMWYxZDkyMTFiNGJmNTk2ZGZmZmYyMmJjZmE3NzMuYmluZFBvcHVwKHBvcHVwX2ZmM2VkNWNkOWM2NDRlNzQ4YWNjMmI5ZGMwODA0MWEyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ2NGM3Nzg3YTdhODRlNTVhMTI3YjMwYTkwNjUxYzA0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUxNDkzOSwtNzkuMzc1NDE3OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzU2MTVlZDE3MmE0NDU1MmFlYzU1MGExZWRkYmJhNzAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOGQ2NzQzZDk0NjI5NDc0OWFlYWIzYjM2NjE5OTFlOTggPSAkKCc8ZGl2IGlkPSJodG1sXzhkNjc0M2Q5NDYyOTQ3NDlhZWFiM2IzNjYxOTkxZTk4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdC4gSmFtZXMgVG93biBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc1NjE1ZWQxNzJhNDQ1NTJhZWM1NTBhMWVkZGJiYTcwLnNldENvbnRlbnQoaHRtbF84ZDY3NDNkOTQ2Mjk0NzQ5YWVhYjNiMzY2MTk5MWU5OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80NjRjNzc4N2E3YTg0ZTU1YTEyN2IzMGE5MDY1MWMwNC5iaW5kUG9wdXAocG9wdXBfNzU2MTVlZDE3MmE0NDU1MmFlYzU1MGExZWRkYmJhNzApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjEyNmI4ODNmYjViNDU1MWE5ZDE4MmI1ZDgxOThhZmIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDQ3NzA3OTk5OTk5OTYsLTc5LjM3MzMwNjRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2FkZjY4YTg4MTdlNDQzZDY5MjEzNWY3NjQ2NDVkYWQ5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2NiZjcxZTVhMTIxNzQxYzc5ZGQ0MzExNTYyODYyNDczID0gJCgnPGRpdiBpZD0iaHRtbF9jYmY3MWU1YTEyMTc0MWM3OWRkNDMxMTU2Mjg2MjQ3MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmVyY3p5IFBhcmsgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hZGY2OGE4ODE3ZTQ0M2Q2OTIxMzVmNzY0NjQ1ZGFkOS5zZXRDb250ZW50KGh0bWxfY2JmNzFlNWExMjE3NDFjNzlkZDQzMTE1NjI4NjI0NzMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjEyNmI4ODNmYjViNDU1MWE5ZDE4MmI1ZDgxOThhZmIuYmluZFBvcHVwKHBvcHVwX2FkZjY4YTg4MTdlNDQzZDY5MjEzNWY3NjQ2NDVkYWQ5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzM4MTdkMDIyYWQxYzQyYzFhMTY1N2I3NjUxYTI3NjdjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjU3OTUyNCwtNzkuMzg3MzgyNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODQ4YWQxOTM3NjBiNDMxY2E1NzNhNGQ2YTdlOTU1MDkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGY3ZjIyYjI4NTY0NGE1Mjg3ZWE4MTU3MzU1OGRkNDIgPSAkKCc8ZGl2IGlkPSJodG1sXzRmN2YyMmIyODU2NDRhNTI4N2VhODE1NzM1NThkZDQyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DZW50cmFsIEJheSBTdHJlZXQgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84NDhhZDE5Mzc2MGI0MzFjYTU3M2E0ZDZhN2U5NTUwOS5zZXRDb250ZW50KGh0bWxfNGY3ZjIyYjI4NTY0NGE1Mjg3ZWE4MTU3MzU1OGRkNDIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMzgxN2QwMjJhZDFjNDJjMWExNjU3Yjc2NTFhMjc2N2MuYmluZFBvcHVwKHBvcHVwXzg0OGFkMTkzNzYwYjQzMWNhNTczYTRkNmE3ZTk1NTA5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYzZjNiNTczZDExYzQ5NDZiYTY3ZjJlMjk4ZmE1MDQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUwNTcxMjAwMDAwMDEsLTc5LjM4NDU2NzVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzJiMTVkYmI5ZWNkYzQ0ZWFiNWFkYjkxYWY3NzJiNDRiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzFjZWY2OWQ5ZjU0NzQzODNiNmQ0ZmRiZDYxN2E4Yjk5ID0gJCgnPGRpdiBpZD0iaHRtbF8xY2VmNjlkOWY1NDc0MzgzYjZkNGZkYmQ2MTdhOGI5OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWRlbGFpZGUsIEtpbmcsIFJpY2htb25kIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMmIxNWRiYjllY2RjNDRlYWI1YWRiOTFhZjc3MmI0NGIuc2V0Q29udGVudChodG1sXzFjZWY2OWQ5ZjU0NzQzODNiNmQ0ZmRiZDYxN2E4Yjk5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzYzZjNiNTczZDExYzQ5NDZiYTY3ZjJlMjk4ZmE1MDQ1LmJpbmRQb3B1cChwb3B1cF8yYjE1ZGJiOWVjZGM0NGVhYjVhZGI5MWFmNzcyYjQ0Yik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xZDM1NGY2OThjOTY0NjU5YWVmNjMyMDhkZDY3YzQ3NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0MDgxNTcsLTc5LjM4MTc1MjI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84NGY0YmFhNGFhNWE0NjA5ODFkOTkxMDhjOTkwOWM0MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zOTM0ZDM5Y2UyNzE0MDUxYWYzMTNmNjYxMDY2MWNiYiA9ICQoJzxkaXYgaWQ9Imh0bWxfMzkzNGQzOWNlMjcxNDA1MWFmMzEzZjY2MTA2NjFjYmIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhhcmJvdXJmcm9udCBFYXN0LCBUb3JvbnRvIElzbGFuZHMsIFVuaW9uIFN0YXRpb24gQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84NGY0YmFhNGFhNWE0NjA5ODFkOTkxMDhjOTkwOWM0My5zZXRDb250ZW50KGh0bWxfMzkzNGQzOWNlMjcxNDA1MWFmMzEzZjY2MTA2NjFjYmIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMWQzNTRmNjk4Yzk2NDY1OWFlZjYzMjA4ZGQ2N2M0NzcuYmluZFBvcHVwKHBvcHVwXzg0ZjRiYWE0YWE1YTQ2MDk4MWQ5OTEwOGM5OTA5YzQzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ZlNzM0N2JmNmE3NTQwMGQ4ZDZjM2FmMTIwNzBhNmIzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ3MTc2OCwtNzkuMzgxNTc2NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E3ZDExMmI4NTlhYTQ4ZmJhYzg1MTE5OTY1YzE5NjAxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzM3YmI1ZDMwOTk4YTQwMjBiNGU2ZWQ3ZjAxNTIyOGVmID0gJCgnPGRpdiBpZD0iaHRtbF8zN2JiNWQzMDk5OGE0MDIwYjRlNmVkN2YwMTUyMjhlZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RGVzaWduIEV4Y2hhbmdlLCBUb3JvbnRvIERvbWluaW9uIENlbnRyZSBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E3ZDExMmI4NTlhYTQ4ZmJhYzg1MTE5OTY1YzE5NjAxLnNldENvbnRlbnQoaHRtbF8zN2JiNWQzMDk5OGE0MDIwYjRlNmVkN2YwMTUyMjhlZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mZTczNDdiZjZhNzU0MDBkOGQ2YzNhZjEyMDcwYTZiMy5iaW5kUG9wdXAocG9wdXBfYTdkMTEyYjg1OWFhNDhmYmFjODUxMTk5NjVjMTk2MDEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYTIyZWRlMTE1NTgyNGQwOGJkNjYyMGYzMDQ0M2U0YWMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDgxOTg1LC03OS4zNzk4MTY5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjhkYmY5Zjc2N2E0NGUwMmIzOGUxMWMzOTliMmFiZTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDY5MzIwZTBmNzExNGY2MzhjMjhmODQxMWI3MzAwYmEgPSAkKCc8ZGl2IGlkPSJodG1sXzQ2OTMyMGUwZjcxMTRmNjM4YzI4Zjg0MTFiNzMwMGJhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db21tZXJjZSBDb3VydCwgVmljdG9yaWEgSG90ZWwgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iOGRiZjlmNzY3YTQ0ZTAyYjM4ZTExYzM5OWIyYWJlMi5zZXRDb250ZW50KGh0bWxfNDY5MzIwZTBmNzExNGY2MzhjMjhmODQxMWI3MzAwYmEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYTIyZWRlMTE1NTgyNGQwOGJkNjYyMGYzMDQ0M2U0YWMuYmluZFBvcHVwKHBvcHVwX2I4ZGJmOWY3NjdhNDRlMDJiMzhlMTFjMzk5YjJhYmUyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI3Y2RjZGY2Y2VkOTQyODY5MjIzMWZkNTcyNjUwYTNjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzMzMjgyNSwtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmQyYTFkM2FmMDBkNDM1Zjk2M2RmNWFhYzBjZmIwNTMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDQwMWQ2YjY4NzU3NGFiZThmMTNhNWQwODNkNDRmYzkgPSAkKCc8ZGl2IGlkPSJodG1sX2Q0MDFkNmI2ODc1NzRhYmU4ZjEzYTVkMDgzZDQ0ZmM5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CZWRmb3JkIFBhcmssIExhd3JlbmNlIE1hbm9yIEVhc3QgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iZDJhMWQzYWYwMGQ0MzVmOTYzZGY1YWFjMGNmYjA1My5zZXRDb250ZW50KGh0bWxfZDQwMWQ2YjY4NzU3NGFiZThmMTNhNWQwODNkNDRmYzkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjdjZGNkZjZjZWQ5NDI4NjkyMjMxZmQ1NzI2NTBhM2MuYmluZFBvcHVwKHBvcHVwX2JkMmExZDNhZjAwZDQzNWY5NjNkZjVhYWMwY2ZiMDUzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2IxNjFhOWZkZDQ3YjQ1MzNhODg4YWI2OTc2Y2MxN2I5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzExNjk0OCwtNzkuNDE2OTM1NTk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2I0OTA3MDAwOGJjNjRjZmNiMjA4MDJiYWM4MDg3N2Q4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk0NmQ5MTk4ZGYwZTQ2ZjBhNWEzZjk2ODk4MWFlYjlhID0gJCgnPGRpdiBpZD0iaHRtbF85NDZkOTE5OGRmMGU0NmYwYTVhM2Y5Njg5ODFhZWI5YSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Um9zZWxhd24gQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iNDkwNzAwMDhiYzY0Y2ZjYjIwODAyYmFjODA4NzdkOC5zZXRDb250ZW50KGh0bWxfOTQ2ZDkxOThkZjBlNDZmMGE1YTNmOTY4OTgxYWViOWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjE2MWE5ZmRkNDdiNDUzM2E4ODhhYjY5NzZjYzE3YjkuYmluZFBvcHVwKHBvcHVwX2I0OTA3MDAwOGJjNjRjZmNiMjA4MDJiYWM4MDg3N2Q4KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYyYjUzZDI0OWQxMzRlMmM5MWQzNDZmYTVmNGY3MWUzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk2OTQ3NiwtNzkuNDExMzA3MjAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAieWVsbG93IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAieWVsbG93IiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2MzZGQ0NGEwNmRiMDQ4NGZiYWRiZDhhOWM5Mzg5NDgyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2M3OTUyODIzN2U1NzQ2YWZhZmE1MDIwMjNiNWJhN2RlID0gJCgnPGRpdiBpZD0iaHRtbF9jNzk1MjgyMzdlNTc0NmFmYWZhNTAyMDIzYjViYTdkZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Rm9yZXN0IEhpbGwgTm9ydGgsIEZvcmVzdCBIaWxsIFdlc3QgQ2x1c3RlciAzPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jM2RkNDRhMDZkYjA0ODRmYmFkYmQ4YTljOTM4OTQ4Mi5zZXRDb250ZW50KGh0bWxfYzc5NTI4MjM3ZTU3NDZhZmFmYTUwMjAyM2I1YmE3ZGUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjJiNTNkMjQ5ZDEzNGUyYzkxZDM0NmZhNWY0ZjcxZTMuYmluZFBvcHVwKHBvcHVwX2MzZGQ0NGEwNmRiMDQ4NGZiYWRiZDhhOWM5Mzg5NDgyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q4ODAxZWQ3MjBlYTQyMGU5MzM5NWZjYjhlY2YxNWVlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjcyNzA5NywtNzkuNDA1Njc4NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E4ZmNiMzJiODNhZjRkM2NiZjUyOWUwZTQ0NzNiNWIyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2U2ZGRjNzY3Yzc1YzRhYTE4YWViZGI0MzhlY2VjY2Y3ID0gJCgnPGRpdiBpZD0iaHRtbF9lNmRkYzc2N2M3NWM0YWExOGFlYmRiNDM4ZWNlY2NmNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEFubmV4LCBOb3J0aCBNaWR0b3duLCBZb3JrdmlsbGUgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hOGZjYjMyYjgzYWY0ZDNjYmY1MjllMGU0NDczYjViMi5zZXRDb250ZW50KGh0bWxfZTZkZGM3NjdjNzVjNGFhMThhZWJkYjQzOGVjZWNjZjcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZDg4MDFlZDcyMGVhNDIwZTkzMzk1ZmNiOGVjZjE1ZWUuYmluZFBvcHVwKHBvcHVwX2E4ZmNiMzJiODNhZjRkM2NiZjUyOWUwZTQ0NzNiNWIyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I0NDBmMzQwNjQwMzRiYjdiZjBhODM4OTIyZTZlZGQ0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYyNjk1NiwtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNWNlNTE3NGYwY2IwNGZjMGFjMjRjMTVmYTZlNjMxMzkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDEzOGYwMjRjNjRhNDBiNjlkMWZkOGUzMDUyZmE3NzkgPSAkKCc8ZGl2IGlkPSJodG1sXzQxMzhmMDI0YzY0YTQwYjY5ZDFmZDhlMzA1MmZhNzc5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IYXJib3JkLCBVbml2ZXJzaXR5IG9mIFRvcm9udG8gQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81Y2U1MTc0ZjBjYjA0ZmMwYWMyNGMxNWZhNmU2MzEzOS5zZXRDb250ZW50KGh0bWxfNDEzOGYwMjRjNjRhNDBiNjlkMWZkOGUzMDUyZmE3NzkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjQ0MGYzNDA2NDAzNGJiN2JmMGE4Mzg5MjJlNmVkZDQuYmluZFBvcHVwKHBvcHVwXzVjZTUxNzRmMGNiMDRmYzBhYzI0YzE1ZmE2ZTYzMTM5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzk5YmEyM2E5MTQ5NDQyOTZiZjBjNjM5MzgyNDkzYWQ4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUzMjA1NywtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMzg1ZDE2M2E0MjczNDNiZmJiNzI2MDIwMzRlYWJmYTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOWRlNGU4NTAzZWMyNDM1MDhiMjZmZDUwYjdhNTU5ZWEgPSAkKCc8ZGl2IGlkPSJodG1sXzlkZTRlODUwM2VjMjQzNTA4YjI2ZmQ1MGI3YTU1OWVhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DaGluYXRvd24sIEdyYW5nZSBQYXJrLCBLZW5zaW5ndG9uIE1hcmtldCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzM4NWQxNjNhNDI3MzQzYmZiYjcyNjAyMDM0ZWFiZmEyLnNldENvbnRlbnQoaHRtbF85ZGU0ZTg1MDNlYzI0MzUwOGIyNmZkNTBiN2E1NTllYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85OWJhMjNhOTE0OTQ0Mjk2YmYwYzYzOTM4MjQ5M2FkOC5iaW5kUG9wdXAocG9wdXBfMzg1ZDE2M2E0MjczNDNiZmJiNzI2MDIwMzRlYWJmYTIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzBlOTI2MzQxNWVkNDlhZGIwZmNmYzQ0YzJkMWE4OTYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Mjg5NDY3LC03OS4zOTQ0MTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83MGQ1YzJlNzQwOGI0M2I1ODI3ZmRhMTllZTJkOTA0OSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xN2RlMzY1MDk0NDQ0NmVkOGY2OTZjNDRkNzM0NzNhMyA9ICQoJzxkaXYgaWQ9Imh0bWxfMTdkZTM2NTA5NDQ0NDZlZDhmNjk2YzQ0ZDczNDczYTMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNOIFRvd2VyLCBCYXRodXJzdCBRdWF5LCBJc2xhbmQgYWlycG9ydCwgSGFyYm91cmZyb250IFdlc3QsIEtpbmcgYW5kIFNwYWRpbmEsIFJhaWx3YXkgTGFuZHMsIFNvdXRoIE5pYWdhcmEgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83MGQ1YzJlNzQwOGI0M2I1ODI3ZmRhMTllZTJkOTA0OS5zZXRDb250ZW50KGh0bWxfMTdkZTM2NTA5NDQ0NDZlZDhmNjk2YzQ0ZDczNDczYTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYzBlOTI2MzQxNWVkNDlhZGIwZmNmYzQ0YzJkMWE4OTYuYmluZFBvcHVwKHBvcHVwXzcwZDVjMmU3NDA4YjQzYjU4MjdmZGExOWVlMmQ5MDQ5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzhiY2Y3ZWU0MWVjOTQ1NTA4MWJiMWJhNmIwZmRiMzk4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ2NDM1MiwtNzkuMzc0ODQ1OTk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzA3NTk0MGVlMjdmMTQxZmY4ZDM5ZWIxMzAwZWJhYmM0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzgzZDkwYzc2NjI1YzQxZTViOTQzMzQyMmIwYWFiOGNmID0gJCgnPGRpdiBpZD0iaHRtbF84M2Q5MGM3NjYyNWM0MWU1Yjk0MzM0MjJiMGFhYjhjZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3RuIEEgUE8gQm94ZXMgMjUgVGhlIEVzcGxhbmFkZSBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzA3NTk0MGVlMjdmMTQxZmY4ZDM5ZWIxMzAwZWJhYmM0LnNldENvbnRlbnQoaHRtbF84M2Q5MGM3NjYyNWM0MWU1Yjk0MzM0MjJiMGFhYjhjZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84YmNmN2VlNDFlYzk0NTUwODFiYjFiYTZiMGZkYjM5OC5iaW5kUG9wdXAocG9wdXBfMDc1OTQwZWUyN2YxNDFmZjhkMzllYjEzMDBlYmFiYzQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGUyNjc3ZTlhODdjNDA2OWI1MDRjZmJkNjIwMTIxZjEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDg0MjkyLC03OS4zODIyODAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lZDk2MmZmMjc2MTE0MTUzYmY5MjUzOTZhMjA5Mzg4ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82YjcxZWYwNGVkZDA0NWE0YThhN2VkZjIxMDFkYjE2MSA9ICQoJzxkaXYgaWQ9Imh0bWxfNmI3MWVmMDRlZGQwNDVhNGE4YTdlZGYyMTAxZGIxNjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZpcnN0IENhbmFkaWFuIFBsYWNlLCBVbmRlcmdyb3VuZCBjaXR5IENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZWQ5NjJmZjI3NjExNDE1M2JmOTI1Mzk2YTIwOTM4OGYuc2V0Q29udGVudChodG1sXzZiNzFlZjA0ZWRkMDQ1YTRhOGE3ZWRmMjEwMWRiMTYxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2RlMjY3N2U5YTg3YzQwNjliNTA0Y2ZiZDYyMDEyMWYxLmJpbmRQb3B1cChwb3B1cF9lZDk2MmZmMjc2MTE0MTUzYmY5MjUzOTZhMjA5Mzg4Zik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MDcyM2U3ODEwZDE0NmI0ODA5NTM3MGZkN2I4MjJkMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxODUxNzk5OTk5OTk5NiwtNzkuNDY0NzYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzg5ZGI2MDc3YTA0NTQyNTI5MzhlMmE1MzBmOWY2MzE5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhlMzg5NTgxYTg1NDRjOWViOGI5ZWZjYWM0MzlhOTRhID0gJCgnPGRpdiBpZD0iaHRtbF84ZTM4OTU4MWE4NTQ0YzllYjhiOWVmY2FjNDM5YTk0YSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TGF3cmVuY2UgSGVpZ2h0cywgTGF3cmVuY2UgTWFub3IgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84OWRiNjA3N2EwNDU0MjUyOTM4ZTJhNTMwZjlmNjMxOS5zZXRDb250ZW50KGh0bWxfOGUzODk1ODFhODU0NGM5ZWI4YjllZmNhYzQzOWE5NGEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNTA3MjNlNzgxMGQxNDZiNDgwOTUzNzBmZDdiODIyZDIuYmluZFBvcHVwKHBvcHVwXzg5ZGI2MDc3YTA0NTQyNTI5MzhlMmE1MzBmOWY2MzE5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzMyYWYxOWM2OTIxZjQwYWZhNDE4ZjNjMDViYWZmZjNjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA5NTc3LC03OS40NDUwNzI1OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTRmNGQzY2MxMzQ5NDlkNjkwYzAzMDZhYjc2Mjg0NDIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2QyM2EyYTEyY2M1NDMwMWJlYjQ1MDA5YThiNjU1MjkgPSAkKCc8ZGl2IGlkPSJodG1sXzNkMjNhMmExMmNjNTQzMDFiZWI0NTAwOWE4YjY1NTI5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HbGVuY2Fpcm4gQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lNGY0ZDNjYzEzNDk0OWQ2OTBjMDMwNmFiNzYyODQ0Mi5zZXRDb250ZW50KGh0bWxfM2QyM2EyYTEyY2M1NDMwMWJlYjQ1MDA5YThiNjU1MjkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMzJhZjE5YzY5MjFmNDBhZmE0MThmM2MwNWJhZmZmM2MuYmluZFBvcHVwKHBvcHVwX2U0ZjRkM2NjMTM0OTQ5ZDY5MGMwMzA2YWI3NjI4NDQyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ2YzUzZDA3YzM5YjRhZDZhZmNhMjQ3YjY2MjA0N2E1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkzNzgxMywtNzkuNDI4MTkxNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzdmYWU3YWI1NDlhZTQ4YjM4YzJhZDRlZjAxY2M3N2I5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzViMzAwNTRiYWM3NDQyZWJhOWY2ZTE3YWM1YmNmY2E0ID0gJCgnPGRpdiBpZD0iaHRtbF81YjMwMDU0YmFjNzQ0MmViYTlmNmUxN2FjNWJjZmNhNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtZXdvb2QtQ2VkYXJ2YWxlIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2ZhZTdhYjU0OWFlNDhiMzhjMmFkNGVmMDFjYzc3Yjkuc2V0Q29udGVudChodG1sXzViMzAwNTRiYWM3NDQyZWJhOWY2ZTE3YWM1YmNmY2E0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzQ2YzUzZDA3YzM5YjRhZDZhZmNhMjQ3YjY2MjA0N2E1LmJpbmRQb3B1cChwb3B1cF83ZmFlN2FiNTQ5YWU0OGIzOGMyYWQ0ZWYwMWNjNzdiOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81NWVhNjUxNmM1ZjA0NjVhOGJlMWFmNzJkNjM1MGZlNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4OTAyNTYsLTc5LjQ1MzUxMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJ5ZWxsb3ciLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJ5ZWxsb3ciLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzVkYzBjMmQ0ZGM2NGJmY2JmYjFmOTQ0OWE2NmJlNzggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjM1N2ZlMzUwMTQ0NDdiOGFlNGNiYmQyZWNkYzdlNzEgPSAkKCc8ZGl2IGlkPSJodG1sXzIzNTdmZTM1MDE0NDQ3YjhhZTRjYmJkMmVjZGM3ZTcxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DYWxlZG9uaWEtRmFpcmJhbmtzIENsdXN0ZXIgMzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzVkYzBjMmQ0ZGM2NGJmY2JmYjFmOTQ0OWE2NmJlNzguc2V0Q29udGVudChodG1sXzIzNTdmZTM1MDE0NDQ3YjhhZTRjYmJkMmVjZGM3ZTcxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU1ZWE2NTE2YzVmMDQ2NWE4YmUxYWY3MmQ2MzUwZmU1LmJpbmRQb3B1cChwb3B1cF83NWRjMGMyZDRkYzY0YmZjYmZiMWY5NDQ5YTY2YmU3OCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hM2QxOTdjODZjYTg0YjAzOGQzNzMyOWY1NmE3ZTM5MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2OTU0MiwtNzkuNDIyNTYzN10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMDUyYzc0MjdlM2VmNDQwN2FmNzFkMWNiZTNmNGFhZmEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjgyZTQ5ZGJiMWQ0NGE4NjkyOGY1ZjcxNjAwYTVlZmIgPSAkKCc8ZGl2IGlkPSJodG1sX2Y4MmU0OWRiYjFkNDRhODY5MjhmNWY3MTYwMGE1ZWZiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DaHJpc3RpZSBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzA1MmM3NDI3ZTNlZjQ0MDdhZjcxZDFjYmUzZjRhYWZhLnNldENvbnRlbnQoaHRtbF9mODJlNDlkYmIxZDQ0YTg2OTI4ZjVmNzE2MDBhNWVmYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hM2QxOTdjODZjYTg0YjAzOGQzNzMyOWY1NmE3ZTM5Mi5iaW5kUG9wdXAocG9wdXBfMDUyYzc0MjdlM2VmNDQwN2FmNzFkMWNiZTNmNGFhZmEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWNmNWYyZmNjMjVmNDI4MWExMDhlMmYxMDQ3YjgzYTEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NjkwMDUxMDAwMDAwMSwtNzkuNDQyMjU5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2U2Njk0YzM1MGIzNDEwMjg0YmQxMjlkYjRhYTk5YzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDdiNzUxNGZhNTQwNDJlMWFkYzE3NTQyMTExM2JjZGUgPSAkKCc8ZGl2IGlkPSJodG1sX2Q3Yjc1MTRmYTU0MDQyZTFhZGMxNzU0MjExMTNiY2RlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3ZlcmNvdXJ0IFZpbGxhZ2UsIER1ZmZlcmluIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfY2U2Njk0YzM1MGIzNDEwMjg0YmQxMjlkYjRhYTk5YzIuc2V0Q29udGVudChodG1sX2Q3Yjc1MTRmYTU0MDQyZTFhZGMxNzU0MjExMTNiY2RlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzFjZjVmMmZjYzI1ZjQyODFhMTA4ZTJmMTA0N2I4M2ExLmJpbmRQb3B1cChwb3B1cF9jZTY2OTRjMzUwYjM0MTAyODRiZDEyOWRiNGFhOTljMik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yODEzMGYwMGUxZjU0MDE3OGIwNTAxOTc5ZTNkYjM4ZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NzkyNjcwMDAwMDAwNiwtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzc2MTcxNjYxNjk0NDc3YzllMzAyZjhhNGMxNzQ4NjAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZGIyMTU5N2VmZTM3NDRkOGI1MTlmNzc0YjBjZGEwNWUgPSAkKCc8ZGl2IGlkPSJodG1sX2RiMjE1OTdlZmUzNzQ0ZDhiNTE5Zjc3NGIwY2RhMDVlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MaXR0bGUgUG9ydHVnYWwsIFRyaW5pdHkgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83NzYxNzE2NjE2OTQ0NzdjOWUzMDJmOGE0YzE3NDg2MC5zZXRDb250ZW50KGh0bWxfZGIyMTU5N2VmZTM3NDRkOGI1MTlmNzc0YjBjZGEwNWUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjgxMzBmMDBlMWY1NDAxNzhiMDUwMTk3OWUzZGIzOGQuYmluZFBvcHVwKHBvcHVwXzc3NjE3MTY2MTY5NDQ3N2M5ZTMwMmY4YTRjMTc0ODYwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQwZWJkNmY4MjYwZDRhZmQ5YTViMmQxNjM0N2RiNjZiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjM2ODQ3MiwtNzkuNDI4MTkxNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2NhYzczMDVkNDA2NTRmMGI5N2Y0ODU0ZjNmZDcwYzgyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2RjNmQ5N2Q5NTg5ZDRmZWU5ZDhhYjZkODhkNzcwNmNhID0gJCgnPGRpdiBpZD0iaHRtbF9kYzZkOTdkOTU4OWQ0ZmVlOWQ4YWI2ZDg4ZDc3MDZjYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnJvY2t0b24sIEV4aGliaXRpb24gUGxhY2UsIFBhcmtkYWxlIFZpbGxhZ2UgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jYWM3MzA1ZDQwNjU0ZjBiOTdmNDg1NGYzZmQ3MGM4Mi5zZXRDb250ZW50KGh0bWxfZGM2ZDk3ZDk1ODlkNGZlZTlkOGFiNmQ4OGQ3NzA2Y2EpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDBlYmQ2ZjgyNjBkNGFmZDlhNWIyZDE2MzQ3ZGI2NmIuYmluZFBvcHVwKHBvcHVwX2NhYzczMDVkNDA2NTRmMGI5N2Y0ODU0ZjNmZDcwYzgyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA3ZGJlMWJmNzY3MzQ4MTRiODdlNzE2MDY5ZjE4MjZkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzEzNzU2MjAwMDAwMDA2LC03OS40OTAwNzM4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInllbGxvdyIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInllbGxvdyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80NTBkMjYyYWU5NGI0NWYzODE5NWFlZGMzNjM1OWJjMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85NWU5MTFiYjJjNjY0NWUzOWIwYWQ5N2M2NWYzYjFlYSA9ICQoJzxkaXYgaWQ9Imh0bWxfOTVlOTExYmIyYzY2NDVlMzliMGFkOTdjNjVmM2IxZWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1hcGxlIExlYWYgUGFyaywgTm9ydGggUGFyaywgVXB3b29kIFBhcmsgQ2x1c3RlciAzPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80NTBkMjYyYWU5NGI0NWYzODE5NWFlZGMzNjM1OWJjMC5zZXRDb250ZW50KGh0bWxfOTVlOTExYmIyYzY2NDVlMzliMGFkOTdjNjVmM2IxZWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMDdkYmUxYmY3NjczNDgxNGI4N2U3MTYwNjlmMTgyNmQuYmluZFBvcHVwKHBvcHVwXzQ1MGQyNjJhZTk0YjQ1ZjM4MTk1YWVkYzM2MzU5YmMwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ5ODg5NTdhMWU3ZDQzNWY4MzQ0ZGY3MDUxNDZjNDNlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkxMTE1OCwtNzkuNDc2MDEzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzNjYzA5Y2MxMjljMDQyNTY5Y2U2YTlkOTkyYzZlOGQxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzdiNTVkMGIwNTQ3YjQ1NGE5ZmM3NmUzNWVlYjdkM2YwID0gJCgnPGRpdiBpZD0iaHRtbF83YjU1ZDBiMDU0N2I0NTRhOWZjNzZlMzVlZWI3ZDNmMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RGVsIFJheSwgS2VlbGVzZGFsZSwgTW91bnQgRGVubmlzLCBTaWx2ZXJ0aG9ybiBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzNjYzA5Y2MxMjljMDQyNTY5Y2U2YTlkOTkyYzZlOGQxLnNldENvbnRlbnQoaHRtbF83YjU1ZDBiMDU0N2I0NTRhOWZjNzZlMzVlZWI3ZDNmMCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80OTg4OTU3YTFlN2Q0MzVmODM0NGRmNzA1MTQ2YzQzZS5iaW5kUG9wdXAocG9wdXBfM2NjMDljYzEyOWMwNDI1NjljZTZhOWQ5OTJjNmU4ZDEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOTNhYmVjODJiZWI4NDQzNGE4YjI2NGUxMjJkY2ZmMTcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NzMxODUyOTk5OTk5OSwtNzkuNDg3MjYxOTAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc4MzVkMjMxZjUyMTRjZGVhNGRiOTg5ZWUwMWQ3ODgwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQyNzE5ZWEyNzhlYTQwZmVhYTAwYzgxYjlkNDljNTgzID0gJCgnPGRpdiBpZD0iaHRtbF80MjcxOWVhMjc4ZWE0MGZlYWEwMGM4MWI5ZDQ5YzU4MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEp1bmN0aW9uIE5vcnRoLCBSdW5ueW1lZGUgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83ODM1ZDIzMWY1MjE0Y2RlYTRkYjk4OWVlMDFkNzg4MC5zZXRDb250ZW50KGh0bWxfNDI3MTllYTI3OGVhNDBmZWFhMDBjODFiOWQ0OWM1ODMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOTNhYmVjODJiZWI4NDQzNGE4YjI2NGUxMjJkY2ZmMTcuYmluZFBvcHVwKHBvcHVwXzc4MzVkMjMxZjUyMTRjZGVhNGRiOTg5ZWUwMWQ3ODgwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2JkNmQzMzU4NTNkNDQzOWY4NjRkNWM1YzY0MjA2NzlmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYxNjA4MywtNzkuNDY0NzYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzIzZjcwYTA0MDM2NjQ1YmI5YjQyYTc5MmY1MzdjYWNiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzFlMDlhYWU0MDVhMDRiNzRiMDMyMThkZjZkNGZhMDgyID0gJCgnPGRpdiBpZD0iaHRtbF8xZTA5YWFlNDA1YTA0Yjc0YjAzMjE4ZGY2ZDRmYTA4MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGlnaCBQYXJrLCBUaGUgSnVuY3Rpb24gU291dGggQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yM2Y3MGEwNDAzNjY0NWJiOWI0MmE3OTJmNTM3Y2FjYi5zZXRDb250ZW50KGh0bWxfMWUwOWFhZTQwNWEwNGI3NGIwMzIxOGRmNmQ0ZmEwODIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYmQ2ZDMzNTg1M2Q0NDM5Zjg2NGQ1YzVjNjQyMDY3OWYuYmluZFBvcHVwKHBvcHVwXzIzZjcwYTA0MDM2NjQ1YmI5YjQyYTc5MmY1MzdjYWNiKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2FlODFkMzA0ZjU2OTQ5Mzc5NjgwZjRjODE0NzM4ZThkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4OTU5NywtNzkuNDU2MzI1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lN2ExNjAwMjI5MmQ0YTI3YTRiZDNmODVlMDBlMjVlNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xODcxZjEzYmQzOGE0NjY4OWY2NjY1MmU5NjkwYWFjYSA9ICQoJzxkaXYgaWQ9Imh0bWxfMTg3MWYxM2JkMzhhNDY2ODlmNjY2NTJlOTY5MGFhY2EiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlBhcmtkYWxlLCBSb25jZXN2YWxsZXMgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lN2ExNjAwMjI5MmQ0YTI3YTRiZDNmODVlMDBlMjVlNy5zZXRDb250ZW50KGh0bWxfMTg3MWYxM2JkMzhhNDY2ODlmNjY2NTJlOTY5MGFhY2EpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYWU4MWQzMDRmNTY5NDkzNzk2ODBmNGM4MTQ3MzhlOGQuYmluZFBvcHVwKHBvcHVwX2U3YTE2MDAyMjkyZDRhMjdhNGJkM2Y4NWUwMGUyNWU3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ExNjk1ZGNjMTI0ZDQzMDRhYTdkZmEzNWQyMjc1ZmQwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUxNTcwNiwtNzkuNDg0NDQ5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTkxYzIzYWNkN2RlNGUyOWJiMTQ2NTJkNGI5NDA0MTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2EzYWM0MGZmMzlmNGQ1OTlmZjMzYmIzYWU3MDJlMTMgPSAkKCc8ZGl2IGlkPSJodG1sXzNhM2FjNDBmZjM5ZjRkNTk5ZmYzM2JiM2FlNzAyZTEzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SdW5ueW1lZGUsIFN3YW5zZWEgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hOTFjMjNhY2Q3ZGU0ZTI5YmIxNDY1MmQ0Yjk0MDQxMS5zZXRDb250ZW50KGh0bWxfM2EzYWM0MGZmMzlmNGQ1OTlmZjMzYmIzYWU3MDJlMTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYTE2OTVkY2MxMjRkNDMwNGFhN2RmYTM1ZDIyNzVmZDAuYmluZFBvcHVwKHBvcHVwX2E5MWMyM2FjZDdkZTRlMjliYjE0NjUyZDRiOTQwNDExKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2JlNmQyNDVlNGFjMzQ5MzhiYmU1N2RkNzFjNmVkYjRiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYyMzAxNSwtNzkuMzg5NDkzOF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZDI0YjhhZTA1NDc1NDdhN2IwMGNkZTg2NTljNjgyMWIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTUwYWI3ZWY0NWJhNDYwMzkwNDA5MjE0YmM0NTgzNjkgPSAkKCc8ZGl2IGlkPSJodG1sX2U1MGFiN2VmNDViYTQ2MDM5MDQwOTIxNGJjNDU4MzY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5RdWVlbiYjMzk7cyBQYXJrIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDI0YjhhZTA1NDc1NDdhN2IwMGNkZTg2NTljNjgyMWIuc2V0Q29udGVudChodG1sX2U1MGFiN2VmNDViYTQ2MDM5MDQwOTIxNGJjNDU4MzY5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2JlNmQyNDVlNGFjMzQ5MzhiYmU1N2RkNzFjNmVkYjRiLmJpbmRQb3B1cChwb3B1cF9kMjRiOGFlMDU0NzU0N2E3YjAwY2RlODY1OWM2ODIxYik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lYTZmOGFmMmIzZGY0Mjk1YmJlYTY5M2ZiYjJiMzVhYyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjk2NTYsLTc5LjYxNTgxODk5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wODEyZWM1YjhhYTY0OWNjYTg0NDFiYTUwMDc0OTlkZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kMmNmN2Q1MTNlMGQ0NTk3YTNkYjUyZDdlODUzNTc0YSA9ICQoJzxkaXYgaWQ9Imh0bWxfZDJjZjdkNTEzZTBkNDU5N2EzZGI1MmQ3ZTg1MzU3NGEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNhbmFkYSBQb3N0IEdhdGV3YXkgUHJvY2Vzc2luZyBDZW50cmUgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wODEyZWM1YjhhYTY0OWNjYTg0NDFiYTUwMDc0OTlkZC5zZXRDb250ZW50KGh0bWxfZDJjZjdkNTEzZTBkNDU5N2EzZGI1MmQ3ZTg1MzU3NGEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZWE2ZjhhZjJiM2RmNDI5NWJiZWE2OTNmYmIyYjM1YWMuYmluZFBvcHVwKHBvcHVwXzA4MTJlYzViOGFhNjQ5Y2NhODQ0MWJhNTAwNzQ5OWRkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYwOWQxMGUxZGVjNDQ1ZmQ5ZDFmNDRlYzliNzZjYzA5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYyNzQzOSwtNzkuMzIxNTU4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hMWY4OGFiMmUwNDg0YzE0YTI5NmI4NTg1MDRjOTYxYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80MDE3NjhjZTY4YjI0ZDI2YmQwNjc0NGZmMTIyMmMzOSA9ICQoJzxkaXYgaWQ9Imh0bWxfNDAxNzY4Y2U2OGIyNGQyNmJkMDY3NDRmZjEyMjJjMzkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJ1c2luZXNzIFJlcGx5IE1haWwgUHJvY2Vzc2luZyBDZW50cmUgOTY5IEVhc3Rlcm4gQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hMWY4OGFiMmUwNDg0YzE0YTI5NmI4NTg1MDRjOTYxYi5zZXRDb250ZW50KGh0bWxfNDAxNzY4Y2U2OGIyNGQyNmJkMDY3NDRmZjEyMjJjMzkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjA5ZDEwZTFkZWM0NDVmZDlkMWY0NGVjOWI3NmNjMDkuYmluZFBvcHVwKHBvcHVwX2ExZjg4YWIyZTA0ODRjMTRhMjk2Yjg1ODUwNGM5NjFiKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzcyNThmODliMTcyNjQ4MTI4NTdkNjhmYjA2OWZlNmNhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjA1NjQ2NiwtNzkuNTAxMzIwNzAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzZlOTNlZjExOGNmYzRkMjZhOWVjZWE3Y2Y2Yjk0NmI5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzlkOWEwMjAyNDY2NjRjYTc5YTc1OTk4NDYwZDEyYjlmID0gJCgnPGRpdiBpZD0iaHRtbF85ZDlhMDIwMjQ2NjY0Y2E3OWE3NTk5ODQ2MGQxMmI5ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtYmVyIEJheSBTaG9yZXMsIE1pbWljbyBTb3V0aCwgTmV3IFRvcm9udG8gQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82ZTkzZWYxMThjZmM0ZDI2YTllY2VhN2NmNmI5NDZiOS5zZXRDb250ZW50KGh0bWxfOWQ5YTAyMDI0NjY2NGNhNzlhNzU5OTg0NjBkMTJiOWYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzI1OGY4OWIxNzI2NDgxMjg1N2Q2OGZiMDY5ZmU2Y2EuYmluZFBvcHVwKHBvcHVwXzZlOTNlZjExOGNmYzRkMjZhOWVjZWE3Y2Y2Yjk0NmI5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzlmM2U2YjUzZjBjYzRlYTliM2MwYjg4NTE3ZjQ3YWI0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjAyNDEzNzAwMDAwMDEsLTc5LjU0MzQ4NDA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82NTczNTAxYWYzYjc0ZDdiYWI1Mzg0ODUwMGRhNTViNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82ZTM0MTM0ODIxYzU0ZjhlYTc4ZjI3N2FlNTM0YjY0NyA9ICQoJzxkaXYgaWQ9Imh0bWxfNmUzNDEzNDgyMWM1NGY4ZWE3OGYyNzdhZTUzNGI2NDciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFsZGVyd29vZCwgTG9uZyBCcmFuY2ggQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82NTczNTAxYWYzYjc0ZDdiYWI1Mzg0ODUwMGRhNTViNy5zZXRDb250ZW50KGh0bWxfNmUzNDEzNDgyMWM1NGY4ZWE3OGYyNzdhZTUzNGI2NDcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOWYzZTZiNTNmMGNjNGVhOWIzYzBiODg1MTdmNDdhYjQuYmluZFBvcHVwKHBvcHVwXzY1NzM1MDFhZjNiNzRkN2JhYjUzODQ4NTAwZGE1NWI3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzlkMTA5MjE0OThkMTRhN2VhNjZmY2I1YWM5MWYwY2Y1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUzNjUzNjAwMDAwMDA1LC03OS41MDY5NDM2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInllbGxvdyIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInllbGxvdyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82NjIzZTU4ZmI5MjU0NDU1YTYwZGIwNjI0NDA4N2YyYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85YzA3ZTRkZjA3Y2M0MzczYWUxMzU4YjgyMzBmMTdlYSA9ICQoJzxkaXYgaWQ9Imh0bWxfOWMwN2U0ZGYwN2NjNDM3M2FlMTM1OGI4MjMwZjE3ZWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRoZSBLaW5nc3dheSwgTW9udGdvbWVyeSBSb2FkLCBPbGQgTWlsbCBOb3J0aCBDbHVzdGVyIDM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzY2MjNlNThmYjkyNTQ0NTVhNjBkYjA2MjQ0MDg3ZjJiLnNldENvbnRlbnQoaHRtbF85YzA3ZTRkZjA3Y2M0MzczYWUxMzU4YjgyMzBmMTdlYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85ZDEwOTIxNDk4ZDE0YTdlYTY2ZmNiNWFjOTFmMGNmNS5iaW5kUG9wdXAocG9wdXBfNjYyM2U1OGZiOTI1NDQ1NWE2MGRiMDYyNDQwODdmMmIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDQzMjFiMmY5ZmRmNGQ3Yjg5M2Q4ODIzNzQyMjVjNTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MzYyNTc5LC03OS40OTg1MDkwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzg5YjkyODYwNDg0OTQ1Yjg5YWQ2NGY3NTI0NjAyOTllID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2U5YzBmNDQ2MjRkMjQ3NTA4YzZhOWFhNWYyODdlNzk3ID0gJCgnPGRpdiBpZD0iaHRtbF9lOWMwZjQ0NjI0ZDI0NzUwOGM2YTlhYTVmMjg3ZTc5NyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtYmVyIEJheSwgS2luZyYjMzk7cyBNaWxsIFBhcmssIEtpbmdzd2F5IFBhcmsgU291dGggRWFzdCwgTWltaWNvIE5FLCBPbGQgTWlsbCBTb3V0aCwgVGhlIFF1ZWVuc3dheSBFYXN0LCBSb3lhbCBZb3JrIFNvdXRoIEVhc3QsIFN1bm55bGVhIENsdXN0ZXIgNDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODliOTI4NjA0ODQ5NDViODlhZDY0Zjc1MjQ2MDI5OWUuc2V0Q29udGVudChodG1sX2U5YzBmNDQ2MjRkMjQ3NTA4YzZhOWFhNWYyODdlNzk3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzQ0MzIxYjJmOWZkZjRkN2I4OTNkODgyMzc0MjI1YzU0LmJpbmRQb3B1cChwb3B1cF84OWI5Mjg2MDQ4NDk0NWI4OWFkNjRmNzUyNDYwMjk5ZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80NjIzMWFjZmJkMjM0MTBlYjUxYWRmM2YyZDg4ODBjMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYyODg0MDgsLTc5LjUyMDk5OTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80MmMzZjM1NGIyZmY0NzY4ODFjMDJiMjY4ZTU0ZWJhNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lYmQ3OGQzYzlkZDg0ODEyOTQ0ZWY1MzQ3YWM5ZTBiMCA9ICQoJzxkaXYgaWQ9Imh0bWxfZWJkNzhkM2M5ZGQ4NDgxMjk0NGVmNTM0N2FjOWUwYjAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPktpbmdzd2F5IFBhcmsgU291dGggV2VzdCwgTWltaWNvIE5XLCBUaGUgUXVlZW5zd2F5IFdlc3QsIFJveWFsIFlvcmsgU291dGggV2VzdCwgU291dGggb2YgQmxvb3IgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80MmMzZjM1NGIyZmY0NzY4ODFjMDJiMjY4ZTU0ZWJhNC5zZXRDb250ZW50KGh0bWxfZWJkNzhkM2M5ZGQ4NDgxMjk0NGVmNTM0N2FjOWUwYjApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDYyMzFhY2ZiZDIzNDEwZWI1MWFkZjNmMmQ4ODgwYzAuYmluZFBvcHVwKHBvcHVwXzQyYzNmMzU0YjJmZjQ3Njg4MWMwMmIyNjhlNTRlYmE0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ZjNzc1MmQzOTgxNTRhMGViMDk2ZDhiMjk0NDExNDhlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUwOTQzMiwtNzkuNTU0NzI0NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2VmZjUwOTRmYjY2NTRhZmFiMGVmYjM2ZmI3YWU1NDE1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzEyM2ZkOTgwOTgzODRjZjBiY2Q4OTg3YjA1NWM4Y2MxID0gJCgnPGRpdiBpZD0iaHRtbF8xMjNmZDk4MDk4Mzg0Y2YwYmNkODk4N2IwNTVjOGNjMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2xvdmVyZGFsZSwgSXNsaW5ndG9uLCBNYXJ0aW4gR3JvdmUsIFByaW5jZXNzIEdhcmRlbnMsIFdlc3QgRGVhbmUgUGFyayBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2VmZjUwOTRmYjY2NTRhZmFiMGVmYjM2ZmI3YWU1NDE1LnNldENvbnRlbnQoaHRtbF8xMjNmZDk4MDk4Mzg0Y2YwYmNkODk4N2IwNTVjOGNjMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mYzc3NTJkMzk4MTU0YTBlYjA5NmQ4YjI5NDQxMTQ4ZS5iaW5kUG9wdXAocG9wdXBfZWZmNTA5NGZiNjY1NGFmYWIwZWZiMzZmYjdhZTU0MTUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTI4MDU1YzhkNmU5NGIwMDg0MDdkOWVjMWZjZDNhOTYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDM1MTUyLC03OS41NzcyMDA3OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJyZWQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2ZlZjIzOThhNDQxNGE2Zjg3OGQ5MjUwODVmMzkxNzcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmZjMTFkYzdjMDU0NDk5NjhiZDg4OGQ3Yjg5YWNhODcgPSAkKCc8ZGl2IGlkPSJodG1sX2ZmYzExZGM3YzA1NDQ5OTY4YmQ4ODhkN2I4OWFjYTg3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CbG9vcmRhbGUgR2FyZGVucywgRXJpbmdhdGUsIE1hcmtsYW5kIFdvb2QsIE9sZCBCdXJuaGFtdGhvcnBlIENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfY2ZlZjIzOThhNDQxNGE2Zjg3OGQ5MjUwODVmMzkxNzcuc2V0Q29udGVudChodG1sX2ZmYzExZGM3YzA1NDQ5OTY4YmQ4ODhkN2I4OWFjYTg3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzEyODA1NWM4ZDZlOTRiMDA4NDA3ZDllYzFmY2QzYTk2LmJpbmRQb3B1cChwb3B1cF9jZmVmMjM5OGE0NDE0YTZmODc4ZDkyNTA4NWYzOTE3Nyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lMDJiYmNmMGQ5MDQ0OGFkYTA4ZjdhN2UxM2RiMWJlMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NjMwMzMsLTc5LjU2NTk2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJibHVlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2JiZjMzYTdmNTY3YzQwMzg4MDk0ODIzOGM4MDE2YTg0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2QwODlmNzdhZGExNzQ3MjI4ZjFkZWM2ZTcxOTRkYmVlID0gJCgnPGRpdiBpZD0iaHRtbF9kMDg5Zjc3YWRhMTc0NzIyOGYxZGVjNmU3MTk0ZGJlZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtYmVyIFN1bW1pdCBDbHVzdGVyIDI8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2JiZjMzYTdmNTY3YzQwMzg4MDk0ODIzOGM4MDE2YTg0LnNldENvbnRlbnQoaHRtbF9kMDg5Zjc3YWRhMTc0NzIyOGYxZGVjNmU3MTk0ZGJlZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lMDJiYmNmMGQ5MDQ0OGFkYTA4ZjdhN2UxM2RiMWJlMi5iaW5kUG9wdXAocG9wdXBfYmJmMzNhN2Y1NjdjNDAzODgwOTQ4MjM4YzgwMTZhODQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOGUwN2M2ZjEzM2NiNDE4ZThiYjcyNWY4NzFjYjczODQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjQ3NjU5LC03OS41MzIyNDI0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJncmVlbiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogImdyZWVuIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2M3MTdjOTU1NGQ1MDQyNGQ4Mzc0ZDhiYWI0ZjgzMzE5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzg3MGVkMDljMzJkMjRiZjhiZWI4YzYzOWFjY2ZkMmQ3ID0gJCgnPGRpdiBpZD0iaHRtbF84NzBlZDA5YzMyZDI0YmY4YmViOGM2MzlhY2NmZDJkNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RW1lcnksIEh1bWJlcmxlYSBDbHVzdGVyIDQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M3MTdjOTU1NGQ1MDQyNGQ4Mzc0ZDhiYWI0ZjgzMzE5LnNldENvbnRlbnQoaHRtbF84NzBlZDA5YzMyZDI0YmY4YmViOGM2MzlhY2NmZDJkNyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84ZTA3YzZmMTMzY2I0MThlOGJiNzI1Zjg3MWNiNzM4NC5iaW5kUG9wdXAocG9wdXBfYzcxN2M5NTU0ZDUwNDI0ZDgzNzRkOGJhYjRmODMzMTkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGNiYzkxZjczYzRhNDEzNWFjNTRmNTY2OGVmMTNjODUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY4NzYsLTc5LjUxODE4ODQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInllbGxvdyIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInllbGxvdyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jNjU5OWEzZDQxYTU0N2ZhYjRkYWE1MTY1YjlmZTU5YyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kODY3ZTZkMGI3NDQ0YzMyYWI4NWJmMTViNDdhOWE2ZiA9ICQoJzxkaXYgaWQ9Imh0bWxfZDg2N2U2ZDBiNzQ0NGMzMmFiODViZjE1YjQ3YTlhNmYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldlc3RvbiBDbHVzdGVyIDM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M2NTk5YTNkNDFhNTQ3ZmFiNGRhYTUxNjViOWZlNTljLnNldENvbnRlbnQoaHRtbF9kODY3ZTZkMGI3NDQ0YzMyYWI4NWJmMTViNDdhOWE2Zik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kY2JjOTFmNzNjNGE0MTM1YWM1NGY1NjY4ZWYxM2M4NS5iaW5kUG9wdXAocG9wdXBfYzY1OTlhM2Q0MWE1NDdmYWI0ZGFhNTE2NWI5ZmU1OWMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjFmNmYxNzY2NjkxNDQwN2JkYTgyZDg5ZDlkYzkyMTggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTYzMTksLTc5LjUzMjI0MjQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogInJlZCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iMmJmYWU2ZTFkYzE0MTE4OTkxY2VmZDhhODAzNzc2Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iNGU5ZDBjNWY4YjY0NzE2ODA3ZGVjMDY4Yzc4YTJhYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xNjhlODg0ZDYzNTY0YjY4ODFhMTY1NzFmN2RhZDk0YyA9ICQoJzxkaXYgaWQ9Imh0bWxfMTY4ZTg4NGQ2MzU2NGI2ODgxYTE2NTcxZjdkYWQ5NGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldlc3Rtb3VudCBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I0ZTlkMGM1ZjhiNjQ3MTY4MDdkZWMwNjhjNzhhMmFhLnNldENvbnRlbnQoaHRtbF8xNjhlODg0ZDYzNTY0YjY4ODFhMTY1NzFmN2RhZDk0Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl82MWY2ZjE3NjY2OTE0NDA3YmRhODJkODlkOWRjOTIxOC5iaW5kUG9wdXAocG9wdXBfYjRlOWQwYzVmOGI2NDcxNjgwN2RlYzA2OGM3OGEyYWEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTY1MTdkNjg0YTM3NDAzYmJmOTdkZGY4MGM2ZGQzN2MgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODg5MDU0LC03OS41NTQ3MjQ0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJ5ZWxsb3ciLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJ5ZWxsb3ciLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYjJiZmFlNmUxZGMxNDExODk5MWNlZmQ4YTgwMzc3NmIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjJlYzY3Zjg4NmRmNDNjYjgyNzFiMjExZDJiNmQ5MGMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2NiM2FlMTY5YzA1NDc4ZGJlODliY2Y3YzhhZjM3YjMgPSAkKCc8ZGl2IGlkPSJodG1sXzNjYjNhZTE2OWMwNTQ3OGRiZTg5YmNmN2M4YWYzN2IzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5LaW5nc3ZpZXcgVmlsbGFnZSwgTWFydGluIEdyb3ZlIEdhcmRlbnMsIFJpY2h2aWV3IEdhcmRlbnMsIFN0LiBQaGlsbGlwcyBDbHVzdGVyIDM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzYyZWM2N2Y4ODZkZjQzY2I4MjcxYjIxMWQyYjZkOTBjLnNldENvbnRlbnQoaHRtbF8zY2IzYWUxNjljMDU0NzhkYmU4OWJjZjdjOGFmMzdiMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lNjUxN2Q2ODRhMzc0MDNiYmY5N2RkZjgwYzZkZDM3Yy5iaW5kUG9wdXAocG9wdXBfNjJlYzY3Zjg4NmRmNDNjYjgyNzFiMjExZDJiNmQ5MGMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDE2MGJjZTA4ZjkxNDJmZWI1ODgxZTg5YWZhYzNjZTAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mzk0MTYzOTk5OTk5OTYsLTc5LjU4ODQzNjldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzM5ODllMWM2ZjNjZDRhMjBhZjdiYmVjZGY2OThiNzFjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc1ZDRmNzkyNjJiYjQ2YzBiYmMyMmUxMGRlNTNkMTkzID0gJCgnPGRpdiBpZD0iaHRtbF83NWQ0Zjc5MjYyYmI0NmMwYmJjMjJlMTBkZTUzZDE5MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWxiaW9uIEdhcmRlbnMsIEJlYXVtb25kIEhlaWdodHMsIEh1bWJlcmdhdGUsIEphbWVzdG93biwgTW91bnQgT2xpdmUsIFNpbHZlcnN0b25lLCBTb3V0aCBTdGVlbGVzLCBUaGlzdGxldG93biBDbHVzdGVyIDE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzM5ODllMWM2ZjNjZDRhMjBhZjdiYmVjZGY2OThiNzFjLnNldENvbnRlbnQoaHRtbF83NWQ0Zjc5MjYyYmI0NmMwYmJjMjJlMTBkZTUzZDE5Myk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8wMTYwYmNlMDhmOTE0MmZlYjU4ODFlODlhZmFjM2NlMC5iaW5kUG9wdXAocG9wdXBfMzk4OWUxYzZmM2NkNGEyMGFmN2JiZWNkZjY5OGI3MWMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfM2IwYjY5MzBlYzA0NDM1Mzg3NWZlMTM0YTE3ZTc2ODkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY3NDgyOTk5OTk5OTQsLTc5LjU5NDA1NDRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAicmVkIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2IyYmZhZTZlMWRjMTQxMTg5OTFjZWZkOGE4MDM3NzZiKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQwZjc0MDk3NDE1ZTQ0Y2FiYmQ5OWE2ZWJhNDIzZjlkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzY1NDE2MjMzNjJjMDQzZDU4MGMyZjY4MWNkMzQ0MTI3ID0gJCgnPGRpdiBpZD0iaHRtbF82NTQxNjIzMzYyYzA0M2Q1ODBjMmY2ODFjZDM0NDEyNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGh3ZXN0IENsdXN0ZXIgMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDBmNzQwOTc0MTVlNDRjYWJiZDk5YTZlYmE0MjNmOWQuc2V0Q29udGVudChodG1sXzY1NDE2MjMzNjJjMDQzZDU4MGMyZjY4MWNkMzQ0MTI3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzNiMGI2OTMwZWMwNDQzNTM4NzVmZTEzNGExN2U3Njg5LmJpbmRQb3B1cChwb3B1cF80MGY3NDA5NzQxNWU0NGNhYmJkOTlhNmViYTQyM2Y5ZCk7CgogICAgICAgICAgICAKICAgICAgICAKPC9zY3JpcHQ+\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7f48cb45cd68>"
]
},
"execution_count": 139,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"map_clusters_mean = folium.Map(location=[43.7,-79.4], zoom_start=10.5)\n",
"\n",
"# add markers to the map\n",
"markers_colors = []\n",
"for lat, lon, poi, cluster in zip(df_full_clust['Latitude'], df_full_clust['Longitude'], df_full_clust['Neighbourhood'], df_full_clust['Cluster Mean']):\n",
" label = folium.Popup(str(poi) + ' Cluster ' + str(cluster), parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat, lon],\n",
" radius=5,\n",
" popup=label,\n",
" color=rainbow[cluster-1],\n",
" fill=True,\n",
" fill_color=rainbow[cluster-1],\n",
" fill_opacity=0.7).add_to(map_clusters_mean)\n",
" \n",
"map_clusters_mean"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The mean based clustering is, as expected, less sensitive to the highly developed city center and provides some interesting distinctions between areas. Lets examine the cluster centers to see what venues are underlying this clustering."
]
},
{
"cell_type": "code",
"execution_count": 168,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Accessories Store</th>\n",
" <th>Adult Boutique</th>\n",
" <th>Afghan Restaurant</th>\n",
" <th>Airport</th>\n",
" <th>Airport Food Court</th>\n",
" <th>Airport Gate</th>\n",
" <th>Airport Lounge</th>\n",
" <th>Airport Service</th>\n",
" <th>Airport Terminal</th>\n",
" <th>American Restaurant</th>\n",
" <th>...</th>\n",
" <th>Vegetarian / Vegan Restaurant</th>\n",
" <th>Video Game Store</th>\n",
" <th>Video Store</th>\n",
" <th>Vietnamese Restaurant</th>\n",
" <th>Warehouse Store</th>\n",
" <th>Wine Bar</th>\n",
" <th>Wine Shop</th>\n",
" <th>Wings Joint</th>\n",
" <th>Women's Store</th>\n",
" <th>Yoga Studio</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>yellow</th>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>1 rows × 272 columns</p>\n",
"</div>"
],
"text/plain": [
" Accessories Store Adult Boutique Afghan Restaurant Airport \\\n",
"yellow 0.0 0.0 0.0 0.0 \n",
"\n",
" Airport Food Court Airport Gate Airport Lounge Airport Service \\\n",
"yellow 0.0 0.0 0.0 0.0 \n",
"\n",
" Airport Terminal American Restaurant ... \\\n",
"yellow 0.0 0.0 ... \n",
"\n",
" Vegetarian / Vegan Restaurant Video Game Store Video Store \\\n",
"yellow 0.0 0.0 0.0 \n",
"\n",
" Vietnamese Restaurant Warehouse Store Wine Bar Wine Shop \\\n",
"yellow 0.0 0.0 0.0 0.0 \n",
"\n",
" Wings Joint Women's Store Yoga Studio \n",
"yellow 0.0 0.0 0.0 \n",
"\n",
"[1 rows x 272 columns]"
]
},
"execution_count": 168,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_centers = pd.DataFrame(kmeans_mean.cluster_centers_, columns = toronto_grouped_clustering_sum.columns )\n",
"df_centers.index = rainbow\n",
"df_centers[df_centers.index=='yellow']"
]
},
{
"cell_type": "code",
"execution_count": 185,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"---- Common Venues in red----\n",
"Playground: 0.5833333333333334\n",
"Park: 0.33333333333333337\n",
"Trail: 0.08333333333333333\n",
"Coffee Shop: 6.938893903907228e-18\n",
"Convenience Store: 3.469446951953614e-18\n",
"---- Common Venues in blue----\n",
"Coffee Shop: 0.06988870717161973\n",
"Pizza Place: 0.03999215651083617\n",
"Café: 0.03348035519950057\n",
"Fast Food Restaurant: 0.031637771502868575\n",
"Bar: 0.027122873469672557\n",
"---- Common Venues in yellow----\n",
"Empanada Restaurant: 1.0\n",
"Accessories Store: 0.0\n",
"Adult Boutique: 0.0\n",
"Afghan Restaurant: 0.0\n",
"Airport: 0.0\n",
"---- Common Venues in green----\n",
"Park: 0.32638888888888884\n",
"Convenience Store: 0.10416666666666666\n",
"Bank: 0.0625\n",
"Bus Line: 0.0625\n",
"Grocery Store: 0.041666666666666685\n",
"---- Common Venues in orange----\n",
"Baseball Field: 1.0\n",
"Accessories Store: 0.0\n",
"Adult Boutique: 0.0\n",
"Afghan Restaurant: 0.0\n",
"Airport: 0.0\n"
]
}
],
"source": [
"num_top_venues = 5\n",
"\n",
"for c in df_centers.index:\n",
" print(\"---- Common Venue Type in \"+c+\"----\")\n",
" temp = df_centers[df_centers.index==c]\n",
" for _ in range(num_top_venues):\n",
" ven_type = temp.idxmax(axis=1)[0]\n",
" print('{}: {}'.format(ven_type, temp.loc[c, ven_type]))\n",
" temp = temp.drop(temp.idxmax(axis=1), axis=1)\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment