diff options
Diffstat (limited to 'notebooks/Segmenting_and_Clustering_Neighbourhoods_in_Toronto.ipynb')
-rw-r--r-- | notebooks/Segmenting_and_Clustering_Neighbourhoods_in_Toronto.ipynb | 3650 |
1 files changed, 3650 insertions, 0 deletions
diff --git a/notebooks/Segmenting_and_Clustering_Neighbourhoods_in_Toronto.ipynb b/notebooks/Segmenting_and_Clustering_Neighbourhoods_in_Toronto.ipynb new file mode 100644 index 0000000..b5ec4cc --- /dev/null +++ b/notebooks/Segmenting_and_Clustering_Neighbourhoods_in_Toronto.ipynb @@ -0,0 +1,3650 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Segmenting and Clustering Neighbourhoods in Toronto\n", + "---\n", + "# Part 1\n", + "Import libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import requests" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get the HTML page of Wikipedia and use read_html we convert the html data into list of Data frame objects.\n", + "\n", + "Remove cells which have neighbourhood as \"Not assigned.\"" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "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>Postal Code</th>\n", + " <th>Borough</th>\n", + " <th>Neighbourhood</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>M3A</td>\n", + " <td>North York</td>\n", + " <td>Parkwoods</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>M4A</td>\n", + " <td>North York</td>\n", + " <td>Victoria Village</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>M5A</td>\n", + " <td>Downtown Toronto</td>\n", + " <td>Regent Park, Harbourfront</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>M6A</td>\n", + " <td>North York</td>\n", + " <td>Lawrence Manor, Lawrence Heights</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>M7A</td>\n", + " <td>Downtown Toronto</td>\n", + " <td>Queen's Park, Ontario Provincial Government</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Postal Code Borough Neighbourhood\n", + "0 M3A North York Parkwoods\n", + "1 M4A North York Victoria Village\n", + "2 M5A Downtown Toronto Regent Park, Harbourfront\n", + "3 M6A North York Lawrence Manor, Lawrence Heights\n", + "4 M7A Downtown Toronto Queen's Park, Ontario Provincial Government" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wiki = 'https://en.wikipedia.org/wiki/List_of_postal_codes_of_Canada:_M'\n", + "wiki_page = requests.get(wiki)\n", + "\n", + "wiki_raw = pd.read_html(wiki_page.content, header = 0)[0]\n", + "df = wiki_raw[wiki_raw.Neighbourhood != 'Not assigned']\n", + "df.reset_index(inplace=True, drop=True)\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "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>Borough</th>\n", + " <th>Neighbourhood</th>\n", + " </tr>\n", + " <tr>\n", + " <th>Postal Code</th>\n", + " <th></th>\n", + " <th></th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>M1B</th>\n", + " <td>Scarborough</td>\n", + " <td>Malvern, Rouge</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M1C</th>\n", + " <td>Scarborough</td>\n", + " <td>Rouge Hill, Port Union, Highland Creek</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M1E</th>\n", + " <td>Scarborough</td>\n", + " <td>Guildwood, Morningside, West Hill</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M1G</th>\n", + " <td>Scarborough</td>\n", + " <td>Woburn</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M1H</th>\n", + " <td>Scarborough</td>\n", + " <td>Cedarbrae</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M9N</th>\n", + " <td>York</td>\n", + " <td>Weston</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M9P</th>\n", + " <td>Etobicoke</td>\n", + " <td>Westmount</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M9R</th>\n", + " <td>Etobicoke</td>\n", + " <td>Kingsview Village, St. Phillips, Martin Grove ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M9V</th>\n", + " <td>Etobicoke</td>\n", + " <td>South Steeles, Silverstone, Humbergate, Jamest...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>M9W</th>\n", + " <td>Etobicoke</td>\n", + " <td>Northwest, West Humber - Clairville</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>103 rows × 2 columns</p>\n", + "</div>" + ], + "text/plain": [ + " Borough Neighbourhood\n", + "Postal Code \n", + "M1B Scarborough Malvern, Rouge\n", + "M1C Scarborough Rouge Hill, Port Union, Highland Creek\n", + "M1E Scarborough Guildwood, Morningside, West Hill\n", + "M1G Scarborough Woburn\n", + "M1H Scarborough Cedarbrae\n", + "... ... ...\n", + "M9N York Weston\n", + "M9P Etobicoke Westmount\n", + "M9R Etobicoke Kingsview Village, St. Phillips, Martin Grove ...\n", + "M9V Etobicoke South Steeles, Silverstone, Humbergate, Jamest...\n", + "M9W Etobicoke Northwest, West Humber - Clairville\n", + "\n", + "[103 rows x 2 columns]" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.groupby(['Postal Code']).first()" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "103" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(df['Postal Code'].unique())" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "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>Postal Code</th>\n", + " <th>Borough</th>\n", + " <th>Neighbourhood</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: [Postal Code, Borough, Neighbourhood]\n", + "Index: []" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df[df['Borough'] == 'Not assigned']" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(103, 3)" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "# Part 2" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: geocoder in c:\\users\\my_user\\anaconda3\\lib\\site-packages (1.38.1)\n", + "Requirement already satisfied: future in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (0.18.2)\n", + "Requirement already satisfied: ratelim in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (0.1.6)\n", + "Requirement already satisfied: requests in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (2.22.0)\n", + "Requirement already satisfied: click in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (7.0)\n", + "Requirement already satisfied: six in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (1.14.0)\n", + "Requirement already satisfied: decorator in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from ratelim->geocoder) (4.4.1)\n", + "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (1.25.8)\n", + "Requirement already satisfied: idna<2.9,>=2.5 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (2.8)\n", + "Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (2019.11.28)\n", + "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (3.0.4)\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install geocoder" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [], + "source": [ + "import geocoder" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "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>Postal Code</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>43.806686</td>\n", + " <td>-79.194353</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>M1C</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>43.763573</td>\n", + " <td>-79.188711</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>M1G</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>43.773136</td>\n", + " <td>-79.239476</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Postal Code Latitude Longitude\n", + "0 M1B 43.806686 -79.194353\n", + "1 M1C 43.784535 -79.160497\n", + "2 M1E 43.763573 -79.188711\n", + "3 M1G 43.770992 -79.216917\n", + "4 M1H 43.773136 -79.239476" + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "url = 'http://cocl.us/Geospatial_data'\n", + "df_geo = pd.read_csv(url)\n", + "df_geo.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Postal Code object\n", + "Latitude float64\n", + "Longitude float64\n", + "dtype: object" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_geo.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Postal Code object\n", + "Borough object\n", + "Neighbourhood object\n", + "dtype: object" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(103, 3)" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(103, 3)" + ] + }, + "execution_count": 80, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_geo.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "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>Postal Code</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>M3A</td>\n", + " <td>North York</td>\n", + " <td>Parkwoods</td>\n", + " <td>43.753259</td>\n", + " <td>-79.329656</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>M4A</td>\n", + " <td>North York</td>\n", + " <td>Victoria Village</td>\n", + " <td>43.725882</td>\n", + " <td>-79.315572</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>M5A</td>\n", + " <td>Downtown Toronto</td>\n", + " <td>Regent Park, Harbourfront</td>\n", + " <td>43.654260</td>\n", + " <td>-79.360636</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>M6A</td>\n", + " <td>North York</td>\n", + " <td>Lawrence Manor, Lawrence Heights</td>\n", + " <td>43.718518</td>\n", + " <td>-79.464763</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>M7A</td>\n", + " <td>Downtown Toronto</td>\n", + " <td>Queen's Park, Ontario Provincial Government</td>\n", + " <td>43.662301</td>\n", + " <td>-79.389494</td>\n", + " </tr>\n", + " <tr>\n", + " <th>5</th>\n", + " <td>M9A</td>\n", + " <td>Etobicoke</td>\n", + " <td>Islington Avenue, Humber Valley Village</td>\n", + " <td>43.667856</td>\n", + " <td>-79.532242</td>\n", + " </tr>\n", + " <tr>\n", + " <th>6</th>\n", + " <td>M1B</td>\n", + " <td>Scarborough</td>\n", + " <td>Malvern, Rouge</td>\n", + " <td>43.806686</td>\n", + " <td>-79.194353</td>\n", + " </tr>\n", + " <tr>\n", + " <th>7</th>\n", + " <td>M3B</td>\n", + " <td>North York</td>\n", + " <td>Don Mills</td>\n", + " <td>43.745906</td>\n", + " <td>-79.352188</td>\n", + " </tr>\n", + " <tr>\n", + " <th>8</th>\n", + " <td>M4B</td>\n", + " <td>East York</td>\n", + " <td>Parkview Hill, Woodbine Gardens</td>\n", + " <td>43.706397</td>\n", + " <td>-79.309937</td>\n", + " </tr>\n", + " <tr>\n", + " <th>9</th>\n", + " <td>M5B</td>\n", + " <td>Downtown Toronto</td>\n", + " <td>Garden District, Ryerson</td>\n", + " <td>43.657162</td>\n", + " <td>-79.378937</td>\n", + " </tr>\n", + " <tr>\n", + " <th>10</th>\n", + " <td>M6B</td>\n", + " <td>North York</td>\n", + " <td>Glencairn</td>\n", + " <td>43.709577</td>\n", + " <td>-79.445073</td>\n", + " </tr>\n", + " <tr>\n", + " <th>11</th>\n", + " <td>M9B</td>\n", + " <td>Etobicoke</td>\n", + " <td>West Deane Park, Princess Gardens, Martin Grov...</td>\n", + " <td>43.650943</td>\n", + " <td>-79.554724</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Postal Code Borough \\\n", + "0 M3A North York \n", + "1 M4A North York \n", + "2 M5A Downtown Toronto \n", + "3 M6A North York \n", + "4 M7A Downtown Toronto \n", + "5 M9A Etobicoke \n", + "6 M1B Scarborough \n", + "7 M3B North York \n", + "8 M4B East York \n", + "9 M5B Downtown Toronto \n", + "10 M6B North York \n", + "11 M9B Etobicoke \n", + "\n", + " Neighbourhood Latitude Longitude \n", + "0 Parkwoods 43.753259 -79.329656 \n", + "1 Victoria Village 43.725882 -79.315572 \n", + "2 Regent Park, Harbourfront 43.654260 -79.360636 \n", + "3 Lawrence Manor, Lawrence Heights 43.718518 -79.464763 \n", + "4 Queen's Park, Ontario Provincial Government 43.662301 -79.389494 \n", + "5 Islington Avenue, Humber Valley Village 43.667856 -79.532242 \n", + "6 Malvern, Rouge 43.806686 -79.194353 \n", + "7 Don Mills 43.745906 -79.352188 \n", + "8 Parkview Hill, Woodbine Gardens 43.706397 -79.309937 \n", + "9 Garden District, Ryerson 43.657162 -79.378937 \n", + "10 Glencairn 43.709577 -79.445073 \n", + "11 West Deane Park, Princess Gardens, Martin Grov... 43.650943 -79.554724 " + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = df.join(df_geo.set_index('Postal Code'), on='Postal Code')\n", + "df.head(12)" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(103, 5)" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "# Part 3\n", + "Using the foursquere API to segment and cluster the neighborhoods of Toronto" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting package metadata (current_repodata.json): ...working... done\n", + "Solving environment: ...working... done\n", + "\n", + "# All requested packages already installed.\n", + "\n", + "Collecting geopy\n", + " Downloading geopy-2.0.0-py3-none-any.whl (111 kB)\n", + "Collecting geographiclib<2,>=1.49\n", + " Downloading geographiclib-1.50-py3-none-any.whl (38 kB)\n", + "Installing collected packages: geographiclib, geopy\n", + "Successfully installed geographiclib-1.50 geopy-2.0.0\n", + "The geograpical coordinate of Toronto are 43.6534817, -79.3839347.\n" + ] + } + ], + "source": [ + "!conda install -c conda-forge geocoder --yes\n", + "import geocoder\n", + "!pip install geopy\n", + "from geopy.geocoders import Nominatim \n", + "\n", + "address = 'Toronto, Ontario'\n", + "\n", + "geolocator = Nominatim(user_agent=\"toronto_explorer\")\n", + "location = geolocator.geocode(address)\n", + "latitude = location.latitude\n", + "longitude = location.longitude\n", + "print('The geograpical coordinate of Toronto are {}, {}.'.format(latitude, longitude))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Printing the map" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgCiAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICAgTF9OT19UT1VDSCA9IGZhbHNlOwogICAgICAgICAgICBMX0RJU0FCTEVfM0QgPSBmYWxzZTsKICAgICAgICA8L3NjcmlwdD4KICAgIAogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY29kZS5qcXVlcnkuY29tL2pxdWVyeS0xLjEyLjQubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9qcy9ib290c3RyYXAubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5qcyI+PC9zY3JpcHQ+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vYm9vdHN0cmFwLzMuMi4wL2Nzcy9ib290c3RyYXAubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLXRoZW1lLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9mb250LWF3ZXNvbWUvNC42LjMvY3NzL2ZvbnQtYXdlc29tZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL0xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLzIuMC4yL2xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3Jhd2Nkbi5naXRoYWNrLmNvbS9weXRob24tdmlzdWFsaXphdGlvbi9mb2xpdW0vbWFzdGVyL2ZvbGl1bS90ZW1wbGF0ZXMvbGVhZmxldC5hd2Vzb21lLnJvdGF0ZS5jc3MiLz4KICAgIDxzdHlsZT5odG1sLCBib2R5IHt3aWR0aDogMTAwJTtoZWlnaHQ6IDEwMCU7bWFyZ2luOiAwO3BhZGRpbmc6IDA7fTwvc3R5bGU+CiAgICA8c3R5bGU+I21hcCB7cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7Ym90dG9tOjA7cmlnaHQ6MDtsZWZ0OjA7fTwvc3R5bGU+CiAgICAKICAgICAgICAgICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwKICAgICAgICAgICAgICAgIGluaXRpYWwtc2NhbGU9MS4wLCBtYXhpbXVtLXNjYWxlPTEuMCwgdXNlci1zY2FsYWJsZT1ubyIgLz4KICAgICAgICAgICAgPHN0eWxlPgogICAgICAgICAgICAgICAgI21hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCB7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlOwogICAgICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAuMCU7CiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICAgICAgbGVmdDogMC4wJTsKICAgICAgICAgICAgICAgICAgICB0b3A6IDAuMCU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIDwvc3R5bGU+CiAgICAgICAgCjwvaGVhZD4KPGJvZHk+ICAgIAogICAgCiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImZvbGl1bS1tYXAiIGlkPSJtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgiID48L2Rpdj4KICAgICAgICAKPC9ib2R5Pgo8c2NyaXB0PiAgICAKICAgIAogICAgICAgICAgICB2YXIgbWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4ID0gTC5tYXAoCiAgICAgICAgICAgICAgICAibWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4IiwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjZW50ZXI6IFs0My42NTM0ODE3LCAtNzkuMzgzOTM0N10sCiAgICAgICAgICAgICAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICAgICAgICAgICAgICB6b29tOiAxMCwKICAgICAgICAgICAgICAgICAgICB6b29tQ29udHJvbDogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBwcmVmZXJDYW52YXM6IGZhbHNlLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApOwoKICAgICAgICAgICAgCgogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyXzE5ZGE5ZmMzYzZiMDRhMGE4OGMwZjdlMzhkZDY0MTBhID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAiaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmciLAogICAgICAgICAgICAgICAgeyJhdHRyaWJ1dGlvbiI6ICJEYXRhIGJ5IFx1MDAyNmNvcHk7IFx1MDAzY2EgaHJlZj1cImh0dHA6Ly9vcGVuc3RyZWV0bWFwLm9yZ1wiXHUwMDNlT3BlblN0cmVldE1hcFx1MDAzYy9hXHUwMDNlLCB1bmRlciBcdTAwM2NhIGhyZWY9XCJodHRwOi8vd3d3Lm9wZW5zdHJlZXRtYXAub3JnL2NvcHlyaWdodFwiXHUwMDNlT0RiTFx1MDAzYy9hXHUwMDNlLiIsICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwgIm1heE5hdGl2ZVpvb20iOiAxOCwgIm1heFpvb20iOiAxOCwgIm1pblpvb20iOiAwLCAibm9XcmFwIjogZmFsc2UsICJvcGFjaXR5IjogMSwgInN1YmRvbWFpbnMiOiAiYWJjIiwgInRtcyI6IGZhbHNlfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTQ5YTMyZjFlYzZjNDljYWFjMmFkMTgzYzhmYjBhNGYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTMyNTg2LCAtNzkuMzI5NjU2NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9hZTBhYjMzYmFiYjc0OTRlYWQyZWRlMzNiNWM2OWUxOCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZDM4NDk2OWZjMjZhNDI3M2JkY2VmYTIyYjY2ZTIwMjMgPSAkKGA8ZGl2IGlkPSJodG1sX2QzODQ5NjlmYzI2YTQyNzNiZGNlZmEyMmI2NmUyMDIzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrd29vZHMsIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYWUwYWIzM2JhYmI3NDk0ZWFkMmVkZTMzYjVjNjllMTguc2V0Q29udGVudChodG1sX2QzODQ5NjlmYzI2YTQyNzNiZGNlZmEyMmI2NmUyMDIzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81NDlhMzJmMWVjNmM0OWNhYWMyYWQxODNjOGZiMGE0Zi5iaW5kUG9wdXAocG9wdXBfYWUwYWIzM2JhYmI3NDk0ZWFkMmVkZTMzYjVjNjllMTgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA1YWEyOWY2MDVkOTQ4NGE5Y2Y4MjY4ZDIzMjA3ZjM0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI1ODgyMjk5OTk5OTk1LCAtNzkuMzE1NTcxNTk5OTk5OThdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYjYyNWY1ODI4ZjY1NDQ0YWI0OTk3ZTRkOTFmNmJkNmIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2FiMDdkMDRjNjM4NDQwODFhMzdjZTE0OGUzZThiMjU5ID0gJChgPGRpdiBpZD0iaHRtbF9hYjA3ZDA0YzYzODQ0MDgxYTM3Y2UxNDhlM2U4YjI1OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VmljdG9yaWEgVmlsbGFnZSwgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iNjI1ZjU4MjhmNjU0NDRhYjQ5OTdlNGQ5MWY2YmQ2Yi5zZXRDb250ZW50KGh0bWxfYWIwN2QwNGM2Mzg0NDA4MWEzN2NlMTQ4ZTNlOGIyNTkpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzA1YWEyOWY2MDVkOTQ4NGE5Y2Y4MjY4ZDIzMjA3ZjM0LmJpbmRQb3B1cChwb3B1cF9iNjI1ZjU4MjhmNjU0NDRhYjQ5OTdlNGQ5MWY2YmQ2YikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWY0OWM3NjQyNjQ4NDQwZmJmY2VhODEyOGMyYjg0YTAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTQyNTk5LCAtNzkuMzYwNjM1OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF81NmM3NTM3MGJmNTM0MmY1YTQxNTIwNWZhMGQyY2U1YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfY2I4ODI0OTc2YjI5NDc0NWFkNmNjZWJiYzJlNGI2MGQgPSAkKGA8ZGl2IGlkPSJodG1sX2NiODgyNDk3NmIyOTQ3NDVhZDZjY2ViYmMyZTRiNjBkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SZWdlbnQgUGFyaywgSGFyYm91cmZyb250LCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzU2Yzc1MzcwYmY1MzQyZjVhNDE1MjA1ZmEwZDJjZTViLnNldENvbnRlbnQoaHRtbF9jYjg4MjQ5NzZiMjk0NzQ1YWQ2Y2NlYmJjMmU0YjYwZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMWY0OWM3NjQyNjQ4NDQwZmJmY2VhODEyOGMyYjg0YTAuYmluZFBvcHVwKHBvcHVwXzU2Yzc1MzcwYmY1MzQyZjVhNDE1MjA1ZmEwZDJjZTViKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kZTg1N2MxNzUwYzE0NGJlYWUwZWNmZjM3MTJhNDQzYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxODUxNzk5OTk5OTk5NiwgLTc5LjQ2NDc2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2Q1NGQyZThjYWIyNjQzYmFhYjA1MzVlNGM4OTkyMzg1ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jNzRmMDM0MmY3NTI0ZjYxYTJiNzA0ODk2OTc3ZmZjYSA9ICQoYDxkaXYgaWQ9Imh0bWxfYzc0ZjAzNDJmNzUyNGY2MWEyYjcwNDg5Njk3N2ZmY2EiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxhd3JlbmNlIE1hbm9yLCBMYXdyZW5jZSBIZWlnaHRzLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Q1NGQyZThjYWIyNjQzYmFhYjA1MzVlNGM4OTkyMzg1LnNldENvbnRlbnQoaHRtbF9jNzRmMDM0MmY3NTI0ZjYxYTJiNzA0ODk2OTc3ZmZjYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZGU4NTdjMTc1MGMxNDRiZWFlMGVjZmYzNzEyYTQ0M2IuYmluZFBvcHVwKHBvcHVwX2Q1NGQyZThjYWIyNjQzYmFhYjA1MzVlNGM4OTkyMzg1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85NjZlMDIyY2YxYTg0OWQzYjlmMTI0NTliNTNiMmE0ZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MjMwMTUsIC03OS4zODk0OTM4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzFjMDI3MDAwNmE0YzQ5ODM5M2JhYTFmZGY2MzJhODRlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mZWEzZWU0OWRkNzY0YzcyYjFhNmIzM2FkOTEwYzVlNSA9ICQoYDxkaXYgaWQ9Imh0bWxfZmVhM2VlNDlkZDc2NGM3MmIxYTZiMzNhZDkxMGM1ZTUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlF1ZWVuJiMzOTtzIFBhcmssIE9udGFyaW8gUHJvdmluY2lhbCBHb3Zlcm5tZW50LCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzFjMDI3MDAwNmE0YzQ5ODM5M2JhYTFmZGY2MzJhODRlLnNldENvbnRlbnQoaHRtbF9mZWEzZWU0OWRkNzY0YzcyYjFhNmIzM2FkOTEwYzVlNSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTY2ZTAyMmNmMWE4NDlkM2I5ZjEyNDU5YjUzYjJhNGQuYmluZFBvcHVwKHBvcHVwXzFjMDI3MDAwNmE0YzQ5ODM5M2JhYTFmZGY2MzJhODRlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MzcwYmZiNjQyYzg0MmY1OWQ4YzI1YWZhMmQ3ODI1NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Nzg1NTYsIC03OS41MzIyNDI0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yMGVmZDg2ODc5ODc0ZDdlOTVkNTIzNTJlOTdmYjZjYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMGYxNmU1YTJhOWQ0NGQyNmExOTY1MTE2YjRmNjhlMWYgPSAkKGA8ZGl2IGlkPSJodG1sXzBmMTZlNWEyYTlkNDRkMjZhMTk2NTExNmI0ZjY4ZTFmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Jc2xpbmd0b24gQXZlbnVlLCBIdW1iZXIgVmFsbGV5IFZpbGxhZ2UsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8yMGVmZDg2ODc5ODc0ZDdlOTVkNTIzNTJlOTdmYjZjYS5zZXRDb250ZW50KGh0bWxfMGYxNmU1YTJhOWQ0NGQyNmExOTY1MTE2YjRmNjhlMWYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzUzNzBiZmI2NDJjODQyZjU5ZDhjMjVhZmEyZDc4MjU2LmJpbmRQb3B1cChwb3B1cF8yMGVmZDg2ODc5ODc0ZDdlOTVkNTIzNTJlOTdmYjZjYSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjVjYWU1MTAwMmNmNDMyNjk4NTJmZWNlMWJhNWI2OGMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My44MDY2ODYyOTk5OTk5OTYsIC03OS4xOTQzNTM0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zODAyYTEyNWFkYWI0ZGUzYWRkOWQ0OTE4YTA2MGQ3NCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfY2M0NTE4Y2VhOTYyNGY3YmEwM2ViNTk4YzhhOTg5ZjIgPSAkKGA8ZGl2IGlkPSJodG1sX2NjNDUxOGNlYTk2MjRmN2JhMDNlYjU5OGM4YTk4OWYyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5NYWx2ZXJuLCBSb3VnZSwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzgwMmExMjVhZGFiNGRlM2FkZDlkNDkxOGEwNjBkNzQuc2V0Q29udGVudChodG1sX2NjNDUxOGNlYTk2MjRmN2JhMDNlYjU5OGM4YTk4OWYyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iNWNhZTUxMDAyY2Y0MzI2OTg1MmZlY2UxYmE1YjY4Yy5iaW5kUG9wdXAocG9wdXBfMzgwMmExMjVhZGFiNGRlM2FkZDlkNDkxOGEwNjBkNzQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q1ZWZmODExOGQwODRmYjE4ZDE2ZjRlMzkwMTVhYWQyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzQ1OTA1Nzk5OTk5OTk2LCAtNzkuMzUyMTg4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzEyMGQyMzQ5ZWE4YzQwMzI5ZWQ5MzJmZTMwNzZjNDEyID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zY2Y1Yjk3M2IzNzQ0ZDBmYTM0MWM5NGEzYjExMWY3OSA9ICQoYDxkaXYgaWQ9Imh0bWxfM2NmNWI5NzNiMzc0NGQwZmEzNDFjOTRhM2IxMTFmNzkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvbiBNaWxscywgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8xMjBkMjM0OWVhOGM0MDMyOWVkOTMyZmUzMDc2YzQxMi5zZXRDb250ZW50KGh0bWxfM2NmNWI5NzNiMzc0NGQwZmEzNDFjOTRhM2IxMTFmNzkpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q1ZWZmODExOGQwODRmYjE4ZDE2ZjRlMzkwMTVhYWQyLmJpbmRQb3B1cChwb3B1cF8xMjBkMjM0OWVhOGM0MDMyOWVkOTMyZmUzMDc2YzQxMikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGNjZmM5MDQxNWQ1NDk3MzhiOTI5MGNiZmJkMzFmNGMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDYzOTcyLCAtNzkuMzA5OTM3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2I4MDBhZDVmZDVmODRkNzdiMDM5YWI1ZTk5MTZlZDAwID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zNTVhMzhjZTFlYjM0ZTk2YWU3NWNkMjk0NmZiODljNCA9ICQoYDxkaXYgaWQ9Imh0bWxfMzU1YTM4Y2UxZWIzNGU5NmFlNzVjZDI5NDZmYjg5YzQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlBhcmt2aWV3IEhpbGwsIFdvb2RiaW5lIEdhcmRlbnMsIEVhc3QgWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iODAwYWQ1ZmQ1Zjg0ZDc3YjAzOWFiNWU5OTE2ZWQwMC5zZXRDb250ZW50KGh0bWxfMzU1YTM4Y2UxZWIzNGU5NmFlNzVjZDI5NDZmYjg5YzQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2RjY2ZjOTA0MTVkNTQ5NzM4YjkyOTBjYmZiZDMxZjRjLmJpbmRQb3B1cChwb3B1cF9iODAwYWQ1ZmQ1Zjg0ZDc3YjAzOWFiNWU5OTE2ZWQwMCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGE3NzI5OGJkMzk0NGUwNmI5YmIxZDZjYzYwZDU3NmYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTcxNjE4LCAtNzkuMzc4OTM3MDk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfM2NiN2VkMWZkZjg2NGZlZDk4MTIwNmI3Mzk5M2M5NTcgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRmYzI0NWJjZDk5MTRlNmE5M2UyMmFiNWIyOTY2NjMyID0gJChgPGRpdiBpZD0iaHRtbF80ZmMyNDViY2Q5OTE0ZTZhOTNlMjJhYjViMjk2NjYzMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R2FyZGVuIERpc3RyaWN0LCBSeWVyc29uLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzNjYjdlZDFmZGY4NjRmZWQ5ODEyMDZiNzM5OTNjOTU3LnNldENvbnRlbnQoaHRtbF80ZmMyNDViY2Q5OTE0ZTZhOTNlMjJhYjViMjk2NjYzMik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZGE3NzI5OGJkMzk0NGUwNmI5YmIxZDZjYzYwZDU3NmYuYmluZFBvcHVwKHBvcHVwXzNjYjdlZDFmZGY4NjRmZWQ5ODEyMDZiNzM5OTNjOTU3KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83ZGIwZTEwOThjN2I0YzRmYjRmNzEwYWQxM2I1MmFhZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTU3NywgLTc5LjQ0NTA3MjU5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzljMThjMWRiMTUxYzRlMTNhOWM5MDlmZDM4MzRlN2U2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9kNTcyMWNlNzQxNTA0ZWI4OGJkMmUxY2E1MTM4M2NmZCA9ICQoYDxkaXYgaWQ9Imh0bWxfZDU3MjFjZTc0MTUwNGViODhiZDJlMWNhNTEzODNjZmQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkdsZW5jYWlybiwgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85YzE4YzFkYjE1MWM0ZTEzYTljOTA5ZmQzODM0ZTdlNi5zZXRDb250ZW50KGh0bWxfZDU3MjFjZTc0MTUwNGViODhiZDJlMWNhNTEzODNjZmQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzdkYjBlMTA5OGM3YjRjNGZiNGY3MTBhZDEzYjUyYWFkLmJpbmRQb3B1cChwb3B1cF85YzE4YzFkYjE1MWM0ZTEzYTljOTA5ZmQzODM0ZTdlNikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDI1MDJhNzE5ZTgzNDk5NDgzNjZjNWRlZmExYTkyZTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTA5NDMyLCAtNzkuNTU0NzI0NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZjUzMTJkMjEyZDBlNDdjYzg5ZGUzZTljZGYxZTIyYjkgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2Y2OGU1ZTBjNTBhNjQ0MzRhYjViNDQ5ZThmNGIyODJhID0gJChgPGRpdiBpZD0iaHRtbF9mNjhlNWUwYzUwYTY0NDM0YWI1YjQ0OWU4ZjRiMjgyYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2VzdCBEZWFuZSBQYXJrLCBQcmluY2VzcyBHYXJkZW5zLCBNYXJ0aW4gR3JvdmUsIElzbGluZ3RvbiwgQ2xvdmVyZGFsZSwgRXRvYmljb2tlPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Y1MzEyZDIxMmQwZTQ3Y2M4OWRlM2U5Y2RmMWUyMmI5LnNldENvbnRlbnQoaHRtbF9mNjhlNWUwYzUwYTY0NDM0YWI1YjQ0OWU4ZjRiMjgyYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNDI1MDJhNzE5ZTgzNDk5NDgzNjZjNWRlZmExYTkyZTQuYmluZFBvcHVwKHBvcHVwX2Y1MzEyZDIxMmQwZTQ3Y2M4OWRlM2U5Y2RmMWUyMmI5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82ODE5ODg2ZDg3NzQ0ZTU4YjVlYzkzNmM0OTRhZmZhYSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4NDUzNTEsIC03OS4xNjA0OTcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yZmU0N2UxYjFlMTM0MjBjYjg1YjgxNDQ5ODdkNTkwNSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfM2FlYjdlMzgwNWQ3NDI1MmJiNTU3M2U3OTE0MmY4NjkgPSAkKGA8ZGl2IGlkPSJodG1sXzNhZWI3ZTM4MDVkNzQyNTJiYjU1NzNlNzkxNDJmODY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3VnZSBIaWxsLCBQb3J0IFVuaW9uLCBIaWdobGFuZCBDcmVlaywgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMmZlNDdlMWIxZTEzNDIwY2I4NWI4MTQ0OTg3ZDU5MDUuc2V0Q29udGVudChodG1sXzNhZWI3ZTM4MDVkNzQyNTJiYjU1NzNlNzkxNDJmODY5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82ODE5ODg2ZDg3NzQ0ZTU4YjVlYzkzNmM0OTRhZmZhYS5iaW5kUG9wdXAocG9wdXBfMmZlNDdlMWIxZTEzNDIwY2I4NWI4MTQ0OTg3ZDU5MDUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYwZjc0NjgzOTBlMTQzMmNhYTBiZTU3NjNhMjc1NDQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI1ODk5NzAwMDAwMDEsIC03OS4zNDA5MjNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZmNjZTMyYmQwMjc2NDYyZmE3NGIyZDMyMzliODYyMDIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzI0ZmE3ZTM1MzVlMjRjZmZiYmQ4MDY3NTJlMDRmNTYyID0gJChgPGRpdiBpZD0iaHRtbF8yNGZhN2UzNTM1ZTI0Y2ZmYmJkODA2NzUyZTA0ZjU2MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG9uIE1pbGxzLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2ZjY2UzMmJkMDI3NjQ2MmZhNzRiMmQzMjM5Yjg2MjAyLnNldENvbnRlbnQoaHRtbF8yNGZhN2UzNTM1ZTI0Y2ZmYmJkODA2NzUyZTA0ZjU2Mik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNjBmNzQ2ODM5MGUxNDMyY2FhMGJlNTc2M2EyNzU0NDUuYmluZFBvcHVwKHBvcHVwX2ZjY2UzMmJkMDI3NjQ2MmZhNzRiMmQzMjM5Yjg2MjAyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83ZWIxYWQyMzA5NDU0ZDhmYTdhMmQxNTU4ZmFjMjdiNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5NTM0MzkwMDAwMDAwNSwgLTc5LjMxODM4ODddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOTY3OWY2MzQyNDg5NDE5MDgwMjQ1ZjdhMzExNTVhMTMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2NjZGQxZGVlNmZhMDQ3MDFhODNiOTg2ZmRhNDU5YjRlID0gJChgPGRpdiBpZD0iaHRtbF9jY2RkMWRlZTZmYTA0NzAxYTgzYjk4NmZkYTQ1OWI0ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V29vZGJpbmUgSGVpZ2h0cywgRWFzdCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzk2NzlmNjM0MjQ4OTQxOTA4MDI0NWY3YTMxMTU1YTEzLnNldENvbnRlbnQoaHRtbF9jY2RkMWRlZTZmYTA0NzAxYTgzYjk4NmZkYTQ1OWI0ZSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfN2ViMWFkMjMwOTQ1NGQ4ZmE3YTJkMTU1OGZhYzI3YjcuYmluZFBvcHVwKHBvcHVwXzk2NzlmNjM0MjQ4OTQxOTA4MDI0NWY3YTMxMTU1YTEzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xZmQ4MmU4MDVkNWU0ZDNlYjExYmU2ODU4YmE2NjVkNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MTQ5MzksIC03OS4zNzU0MTc5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2MwNDBlN2YwYTViMTQ4N2VhYzhlYjk1NzU1YmNhNjM1ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8yN2NkNGViMjA0NjU0YmE1ODhmMzQ0OGEwNzRhNDhiMSA9ICQoYDxkaXYgaWQ9Imh0bWxfMjdjZDRlYjIwNDY1NGJhNTg4ZjM0NDhhMDc0YTQ4YjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0LiBKYW1lcyBUb3duLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2MwNDBlN2YwYTViMTQ4N2VhYzhlYjk1NzU1YmNhNjM1LnNldENvbnRlbnQoaHRtbF8yN2NkNGViMjA0NjU0YmE1ODhmMzQ0OGEwNzRhNDhiMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMWZkODJlODA1ZDVlNGQzZWIxMWJlNjg1OGJhNjY1ZDcuYmluZFBvcHVwKHBvcHVwX2MwNDBlN2YwYTViMTQ4N2VhYzhlYjk1NzU1YmNhNjM1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iZjEwNGE0Y2YyOGM0YjI0ODg0NWJkM2QyZjI2Y2MzOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5Mzc4MTMsIC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8xNmY1ZmI1ZmUzOGQ0NjI4ODRhNDBhZmEyODAzMWUyOSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNmM5NmYwZDRkYTU1NDc3Mjk4ZDVhMTM4YTVmY2NiNDIgPSAkKGA8ZGl2IGlkPSJodG1sXzZjOTZmMGQ0ZGE1NTQ3NzI5OGQ1YTEzOGE1ZmNjYjQyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IdW1ld29vZC1DZWRhcnZhbGUsIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMTZmNWZiNWZlMzhkNDYyODg0YTQwYWZhMjgwMzFlMjkuc2V0Q29udGVudChodG1sXzZjOTZmMGQ0ZGE1NTQ3NzI5OGQ1YTEzOGE1ZmNjYjQyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iZjEwNGE0Y2YyOGM0YjI0ODg0NWJkM2QyZjI2Y2MzOC5iaW5kUG9wdXAocG9wdXBfMTZmNWZiNWZlMzhkNDYyODg0YTQwYWZhMjgwMzFlMjkpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA0NjlkMjhiOTEzNDRmYzRiODY2NmFiZWFjM2QxZThlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQzNTE1MiwgLTc5LjU3NzIwMDc5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2VlY2JiMTE2ODdhNzQ0ZDViODc4M2JkOGYxMTE2MjM3ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81YzExOTc0MTEzZWY0MjRiYWVlY2FmZTYyYWU3ZTIxNCA9ICQoYDxkaXYgaWQ9Imh0bWxfNWMxMTk3NDExM2VmNDI0YmFlZWNhZmU2MmFlN2UyMTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVyaW5nYXRlLCBCbG9vcmRhbGUgR2FyZGVucywgT2xkIEJ1cm5oYW10aG9ycGUsIE1hcmtsYW5kIFdvb2QsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9lZWNiYjExNjg3YTc0NGQ1Yjg3ODNiZDhmMTExNjIzNy5zZXRDb250ZW50KGh0bWxfNWMxMTk3NDExM2VmNDI0YmFlZWNhZmU2MmFlN2UyMTQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzA0NjlkMjhiOTEzNDRmYzRiODY2NmFiZWFjM2QxZThlLmJpbmRQb3B1cChwb3B1cF9lZWNiYjExNjg3YTc0NGQ1Yjg3ODNiZDhmMTExNjIzNykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWM1OTA2MDNmOWY5NGZlYjgwOGRkNjIwMzUwOTgxZDMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NjM1NzI2LCAtNzkuMTg4NzExNV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83MDc0ZWYyNzI1NWI0ZDc5OTVlYjg1MzBiZDYxZjk3YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNjY2NGExYmFlMDY5NGQ4M2JiYTY4ZjQyYmQ0ZDM5ZDkgPSAkKGA8ZGl2IGlkPSJodG1sXzY2NjRhMWJhZTA2OTRkODNiYmE2OGY0MmJkNGQzOWQ5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HdWlsZHdvb2QsIE1vcm5pbmdzaWRlLCBXZXN0IEhpbGwsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzcwNzRlZjI3MjU1YjRkNzk5NWViODUzMGJkNjFmOTdiLnNldENvbnRlbnQoaHRtbF82NjY0YTFiYWUwNjk0ZDgzYmJhNjhmNDJiZDRkMzlkOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYWM1OTA2MDNmOWY5NGZlYjgwOGRkNjIwMzUwOTgxZDMuYmluZFBvcHVwKHBvcHVwXzcwNzRlZjI3MjU1YjRkNzk5NWViODUzMGJkNjFmOTdiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hNjllM2I2YmI1NGU0OTM0OGNmZGYyOTZjYmQxZDY5YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3NjM1NzM5OTk5OTk5LCAtNzkuMjkzMDMxMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iMmI1MDZlOTY3MDU0MTI0OTRhMGYyZWEyZGRjOGIxYyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNmNjMzdmYzBlYWIzNDRlZWFmNmJmOGJlMzJjN2YxYmEgPSAkKGA8ZGl2IGlkPSJodG1sXzZjYzM3ZmMwZWFiMzQ0ZWVhZjZiZjhiZTMyYzdmMWJhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgQmVhY2hlcywgRWFzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2IyYjUwNmU5NjcwNTQxMjQ5NGEwZjJlYTJkZGM4YjFjLnNldENvbnRlbnQoaHRtbF82Y2MzN2ZjMGVhYjM0NGVlYWY2YmY4YmUzMmM3ZjFiYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTY5ZTNiNmJiNTRlNDkzNDhjZmRmMjk2Y2JkMWQ2OWIuYmluZFBvcHVwKHBvcHVwX2IyYjUwNmU5NjcwNTQxMjQ5NGEwZjJlYTJkZGM4YjFjKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lOTA5ZjUxYTNlZDI0NTQ5OGU2NzE5MWQxYjA5Zjk0ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NDc3MDc5OTk5OTk5NiwgLTc5LjM3MzMwNjRdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNzUzOTBhNDMwNmRkNDFmZWFhM2U5NWJiNGY5NmY3M2IgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzMxYTQ2OTExZjZlZTRlNTM5ODljNjI1ZGQ3MzVmOTU4ID0gJChgPGRpdiBpZD0iaHRtbF8zMWE0NjkxMWY2ZWU0ZTUzOTg5YzYyNWRkNzM1Zjk1OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmVyY3p5IFBhcmssIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNzUzOTBhNDMwNmRkNDFmZWFhM2U5NWJiNGY5NmY3M2Iuc2V0Q29udGVudChodG1sXzMxYTQ2OTExZjZlZTRlNTM5ODljNjI1ZGQ3MzVmOTU4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9lOTA5ZjUxYTNlZDI0NTQ5OGU2NzE5MWQxYjA5Zjk0ZS5iaW5kUG9wdXAocG9wdXBfNzUzOTBhNDMwNmRkNDFmZWFhM2U5NWJiNGY5NmY3M2IpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzJlNWQ3ZmQzYjNlOTQ2MmFiOTU1NWQ4MzE0ODM2NjdhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg5MDI1NiwgLTc5LjQ1MzUxMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zYTIzMDk1YzJjNDQ0OWIwODM0MGM2MDYxNGY0MGRhOSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZjUwMzM5MDFkZWM4NDRmNWJhN2EwNGMyZmNjMmI0NzkgPSAkKGA8ZGl2IGlkPSJodG1sX2Y1MDMzOTAxZGVjODQ0ZjViYTdhMDRjMmZjYzJiNDc5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DYWxlZG9uaWEtRmFpcmJhbmtzLCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzNhMjMwOTVjMmM0NDQ5YjA4MzQwYzYwNjE0ZjQwZGE5LnNldENvbnRlbnQoaHRtbF9mNTAzMzkwMWRlYzg0NGY1YmE3YTA0YzJmY2MyYjQ3OSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMmU1ZDdmZDNiM2U5NDYyYWI5NTU1ZDgzMTQ4MzY2N2EuYmluZFBvcHVwKHBvcHVwXzNhMjMwOTVjMmM0NDQ5YjA4MzQwYzYwNjE0ZjQwZGE5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iYzlhMTI0ZjlkNmM0NmM2YmZjNWUyNjliMWFjZmZkMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MDk5MjEsIC03OS4yMTY5MTc0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80YTY4ZjgzZTlkMjY0ZjdlODliMGFlODVmZDA0MDA3ZSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMGFiYmY2NWNkNGZhNDRiN2ExODIzNTkzODk2Y2U3MzAgPSAkKGA8ZGl2IGlkPSJodG1sXzBhYmJmNjVjZDRmYTQ0YjdhMTgyMzU5Mzg5NmNlNzMwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb2J1cm4sIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzRhNjhmODNlOWQyNjRmN2U4OWIwYWU4NWZkMDQwMDdlLnNldENvbnRlbnQoaHRtbF8wYWJiZjY1Y2Q0ZmE0NGI3YTE4MjM1OTM4OTZjZTczMCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYmM5YTEyNGY5ZDZjNDZjNmJmYzVlMjY5YjFhY2ZmZDIuYmluZFBvcHVwKHBvcHVwXzRhNjhmODNlOWQyNjRmN2U4OWIwYWU4NWZkMDQwMDdlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xNTQyNzVjYmVjOTA0NmM0YTNmZGQ3OGMzNzAxNmU5MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTA2MDQsIC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2IzZjllZTg2YTg2MDQ5YzdhNDA1Y2VhM2RmZmI4OWVjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85NzY0NTAzNmRkNGY0NmIwOWQ1OGVjOWUwZjg0NmQxMyA9ICQoYDxkaXYgaWQ9Imh0bWxfOTc2NDUwMzZkZDRmNDZiMDlkNThlYzllMGY4NDZkMTMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxlYXNpZGUsIEVhc3QgWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iM2Y5ZWU4NmE4NjA0OWM3YTQwNWNlYTNkZmZiODllYy5zZXRDb250ZW50KGh0bWxfOTc2NDUwMzZkZDRmNDZiMDlkNThlYzllMGY4NDZkMTMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzE1NDI3NWNiZWM5MDQ2YzRhM2ZkZDc4YzM3MDE2ZTkzLmJpbmRQb3B1cChwb3B1cF9iM2Y5ZWU4NmE4NjA0OWM3YTQwNWNlYTNkZmZiODllYykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMzYxYzNjOWY0ZGYzNDY1MWJmMWIzYmU5NDZlMDBhYTAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTc5NTI0LCAtNzkuMzg3MzgyNl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9jMmI5ZDI5NWNmMzY0MWRiOTAwODFmMWYxNmFlNTc0YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMWVlNTA4NGEzYjRiNDU3N2I2YTYwMjEyNGE0NjU1MzggPSAkKGA8ZGl2IGlkPSJodG1sXzFlZTUwODRhM2I0YjQ1NzdiNmE2MDIxMjRhNDY1NTM4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DZW50cmFsIEJheSBTdHJlZXQsIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYzJiOWQyOTVjZjM2NDFkYjkwMDgxZjFmMTZhZTU3NGIuc2V0Q29udGVudChodG1sXzFlZTUwODRhM2I0YjQ1NzdiNmE2MDIxMjRhNDY1NTM4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8zNjFjM2M5ZjRkZjM0NjUxYmYxYjNiZTk0NmUwMGFhMC5iaW5kUG9wdXAocG9wdXBfYzJiOWQyOTVjZjM2NDFkYjkwMDgxZjFmMTZhZTU3NGIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NlMTI4YzQwNjZlNjQ4ZmRhODkxNzFjMTEwNTRhZmM4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY5NTQyLCAtNzkuNDIyNTYzN10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83N2E2M2ExMTg5NTk0MTg2Yjk0OWQ3ODE5YzRhMjlhYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMzM2ZTAzODMxMGE5NDkzZDg0M2Q0NTg1ZTU5Y2VkMWUgPSAkKGA8ZGl2IGlkPSJodG1sXzMzNmUwMzgzMTBhOTQ5M2Q4NDNkNDU4NWU1OWNlZDFlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DaHJpc3RpZSwgRG93bnRvd24gVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83N2E2M2ExMTg5NTk0MTg2Yjk0OWQ3ODE5YzRhMjlhYS5zZXRDb250ZW50KGh0bWxfMzM2ZTAzODMxMGE5NDkzZDg0M2Q0NTg1ZTU5Y2VkMWUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2NlMTI4YzQwNjZlNjQ4ZmRhODkxNzFjMTEwNTRhZmM4LmJpbmRQb3B1cChwb3B1cF83N2E2M2ExMTg5NTk0MTg2Yjk0OWQ3ODE5YzRhMjlhYSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMmM2ZTRhZTlkMmFlNDExN2FkODkyNDFjZGVlYWMzYzQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzMxMzYsIC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF84NmE2MTBiY2I1NWY0ODE2OGEyZDJjN2I1OTkwMGRlYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMDBiNzI4NWYyMTc2NDA4NGIxMDhmODE4NTdmODU0ZjkgPSAkKGA8ZGl2IGlkPSJodG1sXzAwYjcyODVmMjE3NjQwODRiMTA4ZjgxODU3Zjg1NGY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DZWRhcmJyYWUsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzg2YTYxMGJjYjU1ZjQ4MTY4YTJkMmM3YjU5OTAwZGVhLnNldENvbnRlbnQoaHRtbF8wMGI3Mjg1ZjIxNzY0MDg0YjEwOGY4MTg1N2Y4NTRmOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMmM2ZTRhZTlkMmFlNDExN2FkODkyNDFjZGVlYWMzYzQuYmluZFBvcHVwKHBvcHVwXzg2YTYxMGJjYjU1ZjQ4MTY4YTJkMmM3YjU5OTAwZGVhKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82Y2ZlY2NkMDNhZmY0Nzg1OTllNTRmOTllNDliODExMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwMzc2MjIsIC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2I4YTkxZmZhODk5YzQxY2ViNTE2MDBjZjE5OGJjMDBiID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81YzY0ZDc1ZDliZWI0ODdiOWI2ZDdmMjEzZDA2Y2NjMSA9ICQoYDxkaXYgaWQ9Imh0bWxfNWM2NGQ3NWQ5YmViNDg3YjliNmQ3ZjIxM2QwNmNjYzEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhpbGxjcmVzdCBWaWxsYWdlLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2I4YTkxZmZhODk5YzQxY2ViNTE2MDBjZjE5OGJjMDBiLnNldENvbnRlbnQoaHRtbF81YzY0ZDc1ZDliZWI0ODdiOWI2ZDdmMjEzZDA2Y2NjMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNmNmZWNjZDAzYWZmNDc4NTk5ZTU0Zjk5ZTQ5YjgxMTMuYmluZFBvcHVwKHBvcHVwX2I4YTkxZmZhODk5YzQxY2ViNTE2MDBjZjE5OGJjMDBiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wM2Q1MjFkYmI5N2Y0NjljYmY2MTZhMzFhZmE5MTY3MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NDMyODMsIC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzlhZWQ3ZWQ5Zjk3YTRhMDc4ZjhmNTgzNDFiYzAzZjliID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85ODA4NjY3NjQ4ODI0ZmM3YWEyODViNWM5ZmFiN2Q5MSA9ICQoYDxkaXYgaWQ9Imh0bWxfOTgwODY2NzY0ODgyNGZjN2FhMjg1YjVjOWZhYjdkOTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJhdGh1cnN0IE1hbm9yLCBXaWxzb24gSGVpZ2h0cywgRG93bnN2aWV3IE5vcnRoLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzlhZWQ3ZWQ5Zjk3YTRhMDc4ZjhmNTgzNDFiYzAzZjliLnNldENvbnRlbnQoaHRtbF85ODA4NjY3NjQ4ODI0ZmM3YWEyODViNWM5ZmFiN2Q5MSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMDNkNTIxZGJiOTdmNDY5Y2JmNjE2YTMxYWZhOTE2NzEuYmluZFBvcHVwKHBvcHVwXzlhZWQ3ZWQ5Zjk3YTRhMDc4ZjhmNTgzNDFiYzAzZjliKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jNDJiYmEwNzUzZDQ0ZDI1YWQyODMxYmU3ZDEwYmJjZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNTM2ODksIC03OS4zNDkzNzE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9hNDMzZmY1MTk4OTU0ZGVmOWViMzhhNTVhOGRkODZjZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZmRkMjIzNjgxYTQ0NDNiNmExYTQzYjM5MTI1MTIwYjMgPSAkKGA8ZGl2IGlkPSJodG1sX2ZkZDIyMzY4MWE0NDQzYjZhMWE0M2IzOTEyNTEyMGIzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaG9ybmNsaWZmZSBQYXJrLCBFYXN0IFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYTQzM2ZmNTE5ODk1NGRlZjllYjM4YTU1YThkZDg2Y2Quc2V0Q29udGVudChodG1sX2ZkZDIyMzY4MWE0NDQzYjZhMWE0M2IzOTEyNTEyMGIzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jNDJiYmEwNzUzZDQ0ZDI1YWQyODMxYmU3ZDEwYmJjZS5iaW5kUG9wdXAocG9wdXBfYTQzM2ZmNTE5ODk1NGRlZjllYjM4YTU1YThkZDg2Y2QpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzU0YjVhNjdmZjk1MTQxMWRiZjE2NTRhM2YxNTJmN2JmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUwNTcxMjAwMDAwMDEsIC03OS4zODQ1Njc1XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzY5M2U5MDZlOTE2MDQ3MTVhMzkzMTNiODIzNTc3N2I4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jMmRlODlmZjlhNjM0ZGE4OGIyYTk5NGM0NTE5MDBlOSA9ICQoYDxkaXYgaWQ9Imh0bWxfYzJkZTg5ZmY5YTYzNGRhODhiMmE5OTRjNDUxOTAwZTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJpY2htb25kLCBBZGVsYWlkZSwgS2luZywgRG93bnRvd24gVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF82OTNlOTA2ZTkxNjA0NzE1YTM5MzEzYjgyMzU3NzdiOC5zZXRDb250ZW50KGh0bWxfYzJkZTg5ZmY5YTYzNGRhODhiMmE5OTRjNDUxOTAwZTkpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzU0YjVhNjdmZjk1MTQxMWRiZjE2NTRhM2YxNTJmN2JmLmJpbmRQb3B1cChwb3B1cF82OTNlOTA2ZTkxNjA0NzE1YTM5MzEzYjgyMzU3NzdiOCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjZmOTNhYzljZTIwNDMyOWE0OWU5NDkwYTY1MzU4MmEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NjkwMDUxMDAwMDAwMSwgLTc5LjQ0MjI1OTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYWM1ZWU1OWM1ZGFiNDQzMTk4YmEzMDU4MmM5ZmU0MGUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRiMTdjM2Y5M2M0NTRhOTFhNGM3MGM2ZGMyN2NkMjI5ID0gJChgPGRpdiBpZD0iaHRtbF80YjE3YzNmOTNjNDU0YTkxYTRjNzBjNmRjMjdjZDIyOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RHVmZmVyaW4sIERvdmVyY291cnQgVmlsbGFnZSwgV2VzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2FjNWVlNTljNWRhYjQ0MzE5OGJhMzA1ODJjOWZlNDBlLnNldENvbnRlbnQoaHRtbF80YjE3YzNmOTNjNDU0YTkxYTRjNzBjNmRjMjdjZDIyOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYjZmOTNhYzljZTIwNDMyOWE0OWU5NDkwYTY1MzU4MmEuYmluZFBvcHVwKHBvcHVwX2FjNWVlNTljNWRhYjQ0MzE5OGJhMzA1ODJjOWZlNDBlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zOGVkYzRlYmFiYTE0ZDI3YTI4NDIwYWJkM2EzNzE5YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc0NDczNDIsIC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85NmNlMjhlOGQ1ZWE0YjE1YmNjZTNiNjAwMzI0YTJiMCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYWMyMzUxMWJjNjQyNDQyY2JmOTA3MmFhYWJkMjFjMWMgPSAkKGA8ZGl2IGlkPSJodG1sX2FjMjM1MTFiYzY0MjQ0MmNiZjkwNzJhYWFiZDIxYzFjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TY2FyYm9yb3VnaCBWaWxsYWdlLCBTY2FyYm9yb3VnaDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85NmNlMjhlOGQ1ZWE0YjE1YmNjZTNiNjAwMzI0YTJiMC5zZXRDb250ZW50KGh0bWxfYWMyMzUxMWJjNjQyNDQyY2JmOTA3MmFhYWJkMjFjMWMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzM4ZWRjNGViYWJhMTRkMjdhMjg0MjBhYmQzYTM3MTliLmJpbmRQb3B1cChwb3B1cF85NmNlMjhlOGQ1ZWE0YjE1YmNjZTNiNjAwMzI0YTJiMCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYmI3ZjZhOTA5ZTg5NGQzMTkxMjk4NDM4MTljMTBlMmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Nzg1MTc1LCAtNzkuMzQ2NTU1N10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9mMzA5M2YwMzZiODY0NWYxODNkYjA3ZWJhYWY1N2NiMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZDllZjg4Y2JkNWZmNGRjOTgyNWQ3MzQxNjgyMzRmYzMgPSAkKGA8ZGl2IGlkPSJodG1sX2Q5ZWY4OGNiZDVmZjRkYzk4MjVkNzM0MTY4MjM0ZmMzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5GYWlydmlldywgSGVucnkgRmFybSwgT3Jpb2xlLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2YzMDkzZjAzNmI4NjQ1ZjE4M2RiMDdlYmFhZjU3Y2IzLnNldENvbnRlbnQoaHRtbF9kOWVmODhjYmQ1ZmY0ZGM5ODI1ZDczNDE2ODIzNGZjMyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYmI3ZjZhOTA5ZTg5NGQzMTkxMjk4NDM4MTljMTBlMmQuYmluZFBvcHVwKHBvcHVwX2YzMDkzZjAzNmI4NjQ1ZjE4M2RiMDdlYmFhZjU3Y2IzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMjEwZmU1MTNkNDk0MGJmYjJiZjQ3MzA5MDM1MGM5YSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2Nzk4MDMsIC03OS40ODcyNjE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82OThmZmI4MWZiYjI0ZGMzYmQyOGFhNjhiYzQzMzJjNCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZGNjNDFiZWQxNTI4NGFkYTk4NGJjMTAwNTg3Mzk5MjUgPSAkKGA8ZGl2IGlkPSJodG1sX2RjYzQxYmVkMTUyODRhZGE5ODRiYzEwMDU4NzM5OTI1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aHdvb2QgUGFyaywgWW9yayBVbml2ZXJzaXR5LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzY5OGZmYjgxZmJiMjRkYzNiZDI4YWE2OGJjNDMzMmM0LnNldENvbnRlbnQoaHRtbF9kY2M0MWJlZDE1Mjg0YWRhOTg0YmMxMDA1ODczOTkyNSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYjIxMGZlNTEzZDQ5NDBiZmIyYmY0NzMwOTAzNTBjOWEuYmluZFBvcHVwKHBvcHVwXzY5OGZmYjgxZmJiMjRkYzNiZDI4YWE2OGJjNDMzMmM0KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MWRhOThiNmQ5OGQ0YmI4OWY5YTk2ZjFlMTkzYWM3YyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4NTM0NywgLTc5LjMzODEwNjVdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMjE0MDdkZDU2ZGY4NDZiNWI0ZGE1ZjY1ZmMwMDJhMzMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzNlZmU1N2RmNTBjNjRiMTU5MTI0MjYzMTMzMmNhMmI1ID0gJChgPGRpdiBpZD0iaHRtbF8zZWZlNTdkZjUwYzY0YjE1OTEyNDI2MzEzMzJjYTJiNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RWFzdCBUb3JvbnRvLCBCcm9hZHZpZXcgTm9ydGggKE9sZCBFYXN0IFlvcmspLCBFYXN0IFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMjE0MDdkZDU2ZGY4NDZiNWI0ZGE1ZjY1ZmMwMDJhMzMuc2V0Q29udGVudChodG1sXzNlZmU1N2RmNTBjNjRiMTU5MTI0MjYzMTMzMmNhMmI1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81MWRhOThiNmQ5OGQ0YmI4OWY5YTk2ZjFlMTkzYWM3Yy5iaW5kUG9wdXAocG9wdXBfMjE0MDdkZDU2ZGY4NDZiNWI0ZGE1ZjY1ZmMwMDJhMzMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzlmZTY4N2QwOTQwMDRiOTI4NDgyZTFiZTIyNDNmZjQ2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQwODE1NywgLTc5LjM4MTc1MjI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2VmZjgxMzA4YjU3NDQzNWNiMGRhZjRiODRhNTcwZWQ0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF84ZGM3MGViOTQwNDQ0Zjg1YmVjNzNmNzY0MzQwNDQ4NCA9ICQoYDxkaXYgaWQ9Imh0bWxfOGRjNzBlYjk0MDQ0NGY4NWJlYzczZjc2NDM0MDQ0ODQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhhcmJvdXJmcm9udCBFYXN0LCBVbmlvbiBTdGF0aW9uLCBUb3JvbnRvIElzbGFuZHMsIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWZmODEzMDhiNTc0NDM1Y2IwZGFmNGI4NGE1NzBlZDQuc2V0Q29udGVudChodG1sXzhkYzcwZWI5NDA0NDRmODViZWM3M2Y3NjQzNDA0NDg0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85ZmU2ODdkMDk0MDA0YjkyODQ4MmUxYmUyMjQzZmY0Ni5iaW5kUG9wdXAocG9wdXBfZWZmODEzMDhiNTc0NDM1Y2IwZGFmNGI4NGE1NzBlZDQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdjZDZmMGUwOWRjNjQ3ZTE4MDg5OGU0MWE2MzMzOWQxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ3OTI2NzAwMDAwMDA2LCAtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83OTVhNjBkNGQ3MDk0MTA0YmEzMDdiNGVkMjgyMmZhMSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNjVlYmQxZjNlNWY5NDJhMmE4NzU5OTM2Y2FlMmJkZDYgPSAkKGA8ZGl2IGlkPSJodG1sXzY1ZWJkMWYzZTVmOTQyYTJhODc1OTkzNmNhZTJiZGQ2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MaXR0bGUgUG9ydHVnYWwsIFRyaW5pdHksIFdlc3QgVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83OTVhNjBkNGQ3MDk0MTA0YmEzMDdiNGVkMjgyMmZhMS5zZXRDb250ZW50KGh0bWxfNjVlYmQxZjNlNWY5NDJhMmE4NzU5OTM2Y2FlMmJkZDYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzdjZDZmMGUwOWRjNjQ3ZTE4MDg5OGU0MWE2MzMzOWQxLmJpbmRQb3B1cChwb3B1cF83OTVhNjBkNGQ3MDk0MTA0YmEzMDdiNGVkMjgyMmZhMSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWVhMGJkZjNjZGIwNDhkMTk2MmRjNjVmMGQ5YzJmM2UgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjc5MjkyLCAtNzkuMjYyMDI5NDAwMDAwMDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNjliZWMxNDNjYmE3NDg0OWI4MzFkNDc2ZTJhZjg5YWEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2VjMDczMzcxMDJjNzQwMjNhNzU1ZDA3MTllOWYwYTM4ID0gJChgPGRpdiBpZD0iaHRtbF9lYzA3MzM3MTAyYzc0MDIzYTc1NWQwNzE5ZTlmMGEzOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+S2VubmVkeSBQYXJrLCBJb252aWV3LCBFYXN0IEJpcmNobW91bnQgUGFyaywgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNjliZWMxNDNjYmE3NDg0OWI4MzFkNDc2ZTJhZjg5YWEuc2V0Q29udGVudChodG1sX2VjMDczMzcxMDJjNzQwMjNhNzU1ZDA3MTllOWYwYTM4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xZWEwYmRmM2NkYjA0OGQxOTYyZGM2NWYwZDljMmYzZS5iaW5kUG9wdXAocG9wdXBfNjliZWMxNDNjYmE3NDg0OWI4MzFkNDc2ZTJhZjg5YWEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI3YWNmMzA0ZjFhMDQ2M2RiZDg0ZmE1MThkMmUzOWQ0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg2OTQ3MywgLTc5LjM4NTk3NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF84ZTMzYzk2ZWNiODQ0ZGU3YmYwNWFjNTI5ZDgxMzAzMCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDEyMWFhNzQxYTkwNDFlZjgzYzZkNDk0YTc0ZDRiZjkgPSAkKGA8ZGl2IGlkPSJodG1sXzQxMjFhYTc0MWE5MDQxZWY4M2M2ZDQ5NGE3NGQ0YmY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CYXl2aWV3IFZpbGxhZ2UsIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOGUzM2M5NmVjYjg0NGRlN2JmMDVhYzUyOWQ4MTMwMzAuc2V0Q29udGVudChodG1sXzQxMjFhYTc0MWE5MDQxZWY4M2M2ZDQ5NGE3NGQ0YmY5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8yN2FjZjMwNGYxYTA0NjNkYmQ4NGZhNTE4ZDJlMzlkNC5iaW5kUG9wdXAocG9wdXBfOGUzM2M5NmVjYjg0NGRlN2JmMDVhYzUyOWQ4MTMwMzApCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI3YThmZjRkZmRmYzQ2NDdhZmNmZTgwZGViOThkMTczID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM3NDczMjAwMDAwMDA0LCAtNzkuNDY0NzYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOTgzN2FhMDA1OTkzNDFjNWFkYzFmMWIxMjk2ZmYzNzkgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzAyMjA1MTY2MmEwODQxYmY4ZGE4ZGE1YTM0ZmRjNWY2ID0gJChgPGRpdiBpZD0iaHRtbF8wMjIwNTE2NjJhMDg0MWJmOGRhOGRhNWEzNGZkYzVmNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG93bnN2aWV3LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzk4MzdhYTAwNTk5MzQxYzVhZGMxZjFiMTI5NmZmMzc5LnNldENvbnRlbnQoaHRtbF8wMjIwNTE2NjJhMDg0MWJmOGRhOGRhNWEzNGZkYzVmNik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjdhOGZmNGRmZGZjNDY0N2FmY2ZlODBkZWI5OGQxNzMuYmluZFBvcHVwKHBvcHVwXzk4MzdhYTAwNTk5MzQxYzVhZGMxZjFiMTI5NmZmMzc5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lMTFmMjkyMzk5ZjI0NjlmODAxMDc1ZWQ0Yjc3YjM4NCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3OTU1NzEsIC03OS4zNTIxODhdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOWQ0YmQ0MGMxYTVhNDdjNGJkZTY1MmRmZTdlNmIwYWMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzEyODYyYWE3NDEzMjQ1Y2FiNmNkZDFjOWM2MzUzMjA2ID0gJChgPGRpdiBpZD0iaHRtbF8xMjg2MmFhNzQxMzI0NWNhYjZjZGQxYzljNjM1MzIwNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIERhbmZvcnRoIFdlc3QsIFJpdmVyZGFsZSwgRWFzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzlkNGJkNDBjMWE1YTQ3YzRiZGU2NTJkZmU3ZTZiMGFjLnNldENvbnRlbnQoaHRtbF8xMjg2MmFhNzQxMzI0NWNhYjZjZGQxYzljNjM1MzIwNik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZTExZjI5MjM5OWYyNDY5ZjgwMTA3NWVkNGI3N2IzODQuYmluZFBvcHVwKHBvcHVwXzlkNGJkNDBjMWE1YTQ3YzRiZGU2NTJkZmU3ZTZiMGFjKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMTAyYjhjMTAwYjU0NzU5ODQyM2EwNGEwZjM0NDQyZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NzE3NjgsIC03OS4zODE1NzY0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9mNzlhZTMzMGU3MDM0NDc3OGFkMDM0Njc0OGVjM2ZhMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfN2ZkMzJiNzFhNmFiNDA4YmEzYjE2YTExNDJmZWY1NDMgPSAkKGA8ZGl2IGlkPSJodG1sXzdmZDMyYjcxYTZhYjQwOGJhM2IxNmExMTQyZmVmNTQzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ub3JvbnRvIERvbWluaW9uIENlbnRyZSwgRGVzaWduIEV4Y2hhbmdlLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Y3OWFlMzMwZTcwMzQ0Nzc4YWQwMzQ2NzQ4ZWMzZmEzLnNldENvbnRlbnQoaHRtbF83ZmQzMmI3MWE2YWI0MDhiYTNiMTZhMTE0MmZlZjU0Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTEwMmI4YzEwMGI1NDc1OTg0MjNhMDRhMGYzNDQ0MmQuYmluZFBvcHVwKHBvcHVwX2Y3OWFlMzMwZTcwMzQ0Nzc4YWQwMzQ2NzQ4ZWMzZmEzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iNmU2ZmQwNGE3ZDY0YmNlODkxYzNjZjhiZjg4MTRhZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjg0NzIsIC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8xN2FkMzQxZTk5OTk0MGM5ODEyNjA1ZjBmNjk0ZTBlZiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMTYzOTYwMTI0YWE3NDYxMGJlYjQ1YjIzMGVmYWNmMGQgPSAkKGA8ZGl2IGlkPSJodG1sXzE2Mzk2MDEyNGFhNzQ2MTBiZWI0NWIyMzBlZmFjZjBkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ccm9ja3RvbiwgUGFya2RhbGUgVmlsbGFnZSwgRXhoaWJpdGlvbiBQbGFjZSwgV2VzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzE3YWQzNDFlOTk5OTQwYzk4MTI2MDVmMGY2OTRlMGVmLnNldENvbnRlbnQoaHRtbF8xNjM5NjAxMjRhYTc0NjEwYmViNDViMjMwZWZhY2YwZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYjZlNmZkMDRhN2Q2NGJjZTg5MWMzY2Y4YmY4ODE0YWYuYmluZFBvcHVwKHBvcHVwXzE3YWQzNDFlOTk5OTQwYzk4MTI2MDVmMGY2OTRlMGVmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YzMyY2Y1NzJkOTI0Njg2YWZmNzIyYzNhNzNiZmI4OSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMTExMTcwMDAwMDAwNCwgLTc5LjI4NDU3NzJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTE4MjRjYzUyYTA0NDBjNDk3ZDFjYWM5ZDMwNWYzNjQgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2VlYWY2MmI1MWJjNTQwMTZiZmQ0ZWQwNGFjNTExMzMwID0gJChgPGRpdiBpZD0iaHRtbF9lZWFmNjJiNTFiYzU0MDE2YmZkNGVkMDRhYzUxMTMzMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R29sZGVuIE1pbGUsIENsYWlybGVhLCBPYWtyaWRnZSwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZTE4MjRjYzUyYTA0NDBjNDk3ZDFjYWM5ZDMwNWYzNjQuc2V0Q29udGVudChodG1sX2VlYWY2MmI1MWJjNTQwMTZiZmQ0ZWQwNGFjNTExMzMwKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85YzMyY2Y1NzJkOTI0Njg2YWZmNzIyYzNhNzNiZmI4OS5iaW5kUG9wdXAocG9wdXBfZTE4MjRjYzUyYTA0NDBjNDk3ZDFjYWM5ZDMwNWYzNjQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdiMzYxNzEyOWFlNDRhNWM5MTQ4ZjZjMDY4ZjU1ZmYyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU3NDkwMiwgLTc5LjM3NDcxNDA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzcyZmNjMTE0YzIzNDQ3ZGE5ZjkyYjNiNmIxODEwOWVjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8yMGMxY2ZiMTRhMzQ0NjgzYmE2ZGJiZGNiZjBiNWVkYiA9ICQoYDxkaXYgaWQ9Imh0bWxfMjBjMWNmYjE0YTM0NDY4M2JhNmRiYmRjYmYwYjVlZGIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPllvcmsgTWlsbHMsIFNpbHZlciBIaWxscywgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83MmZjYzExNGMyMzQ0N2RhOWY5MmIzYjZiMTgxMDllYy5zZXRDb250ZW50KGh0bWxfMjBjMWNmYjE0YTM0NDY4M2JhNmRiYmRjYmYwYjVlZGIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzdiMzYxNzEyOWFlNDRhNWM5MTQ4ZjZjMDY4ZjU1ZmYyLmJpbmRQb3B1cChwb3B1cF83MmZjYzExNGMyMzQ0N2RhOWY5MmIzYjZiMTgxMDllYykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDEyNGE2MmYzOWVjNDFkNmExMmZjMWVmMGEzYWJmZjYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MzkwMTQ2LCAtNzkuNTA2OTQzNl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iNTAzNGUwMDI3ZGQ0MTg0YTFlNGMyYzM2ZDA2M2Y0NiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNzI5YmViNmNmNjFkNDEyOThmNzk5ZTkwM2RlZTM2M2MgPSAkKGA8ZGl2IGlkPSJodG1sXzcyOWJlYjZjZjYxZDQxMjk4Zjc5OWU5MDNkZWUzNjNjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3duc3ZpZXcsIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYjUwMzRlMDAyN2RkNDE4NGExZTRjMmMzNmQwNjNmNDYuc2V0Q29udGVudChodG1sXzcyOWJlYjZjZjYxZDQxMjk4Zjc5OWU5MDNkZWUzNjNjKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl80MTI0YTYyZjM5ZWM0MWQ2YTEyZmMxZWYwYTNhYmZmNi5iaW5kUG9wdXAocG9wdXBfYjUwMzRlMDAyN2RkNDE4NGExZTRjMmMzNmQwNjNmNDYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYwYzNkMDNmOGJlMDRjZmE4MzA3NzkzNTE4MGI0MDQ2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY4OTk4NSwgLTc5LjMxNTU3MTU5OTk5OTk4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzYyNzQ1NDlhODNmZTRjYzZiY2FjN2E2MDU2YTc2NTc5ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lMzE2NTc1ZGQ1NWM0NDFkYmY3ZDQ0ZGRlNzRjOGQwNCA9ICQoYDxkaXYgaWQ9Imh0bWxfZTMxNjU3NWRkNTVjNDQxZGJmN2Q0NGRkZTc0YzhkMDQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkluZGlhIEJhemFhciwgVGhlIEJlYWNoZXMgV2VzdCwgRWFzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzYyNzQ1NDlhODNmZTRjYzZiY2FjN2E2MDU2YTc2NTc5LnNldENvbnRlbnQoaHRtbF9lMzE2NTc1ZGQ1NWM0NDFkYmY3ZDQ0ZGRlNzRjOGQwNCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNjBjM2QwM2Y4YmUwNGNmYTgzMDc3OTM1MTgwYjQwNDYuYmluZFBvcHVwKHBvcHVwXzYyNzQ1NDlhODNmZTRjYzZiY2FjN2E2MDU2YTc2NTc5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kMzc4MGQ4ZmMzYTk0Y2Y5YTE2Yjg1NTYwNWJjYWQ1NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0ODE5ODUsIC03OS4zNzk4MTY5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80OGJhY2VlOTI0ZDg0OTFlYjM5OTJiNWZjZWQ3ZTgzNCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfOGE4YTQ2ODIzZjkzNDU2MmE4ZWQ5ZGY1MzFlMWI1MjkgPSAkKGA8ZGl2IGlkPSJodG1sXzhhOGE0NjgyM2Y5MzQ1NjJhOGVkOWRmNTMxZTFiNTI5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db21tZXJjZSBDb3VydCwgVmljdG9yaWEgSG90ZWwsIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDhiYWNlZTkyNGQ4NDkxZWIzOTkyYjVmY2VkN2U4MzQuc2V0Q29udGVudChodG1sXzhhOGE0NjgyM2Y5MzQ1NjJhOGVkOWRmNTMxZTFiNTI5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9kMzc4MGQ4ZmMzYTk0Y2Y5YTE2Yjg1NTYwNWJjYWQ1Ny5iaW5kUG9wdXAocG9wdXBfNDhiYWNlZTkyNGQ4NDkxZWIzOTkyYjVmY2VkN2U4MzQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzZmNTU4NmFkNjZkNzQxMWJhODU0ODNhYmU1MWQ5YjVkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzEzNzU2MjAwMDAwMDA2LCAtNzkuNDkwMDczOF0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF81MzAxZTViMzRiZjY0NGUwYmMxN2ViM2UzYzBmZjlmMiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZmFiNjViOGM1ZDBjNGUzZjliNzNkZDFiZGYzMDY2YTggPSAkKGA8ZGl2IGlkPSJodG1sX2ZhYjY1YjhjNWQwYzRlM2Y5YjczZGQxYmRmMzA2NmE4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aCBQYXJrLCBNYXBsZSBMZWFmIFBhcmssIFVwd29vZCBQYXJrLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzUzMDFlNWIzNGJmNjQ0ZTBiYzE3ZWIzZTNjMGZmOWYyLnNldENvbnRlbnQoaHRtbF9mYWI2NWI4YzVkMGM0ZTNmOWI3M2RkMWJkZjMwNjZhOCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNmY1NTg2YWQ2NmQ3NDExYmE4NTQ4M2FiZTUxZDliNWQuYmluZFBvcHVwKHBvcHVwXzUzMDFlNWIzNGJmNjQ0ZTBiYzE3ZWIzZTNjMGZmOWYyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82NTc3MzA4YTM3YTg0YzI5ODE1YzAwMzIxNThhMmZkZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NjMwMzMsIC03OS41NjU5NjMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zMWRjOGI2OTRhMmM0YTdiODhmOGM2YmQxMGQ1MDc2OCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNTMwMGY1NmYyZWNiNGNkMDhmMDFkMDk3N2Y3M2IyMmEgPSAkKGA8ZGl2IGlkPSJodG1sXzUzMDBmNTZmMmVjYjRjZDA4ZjAxZDA5NzdmNzNiMjJhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IdW1iZXIgU3VtbWl0LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzMxZGM4YjY5NGEyYzRhN2I4OGY4YzZiZDEwZDUwNzY4LnNldENvbnRlbnQoaHRtbF81MzAwZjU2ZjJlY2I0Y2QwOGYwMWQwOTc3ZjczYjIyYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNjU3NzMwOGEzN2E4NGMyOTgxNWMwMDMyMTU4YTJmZGQuYmluZFBvcHVwKHBvcHVwXzMxZGM4YjY5NGEyYzRhN2I4OGY4YzZiZDEwZDUwNzY4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kN2I2NTU5MjZhNjY0YjMzOTVlNjNhZmFkZTJlZTFjMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxNjMxNiwgLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzc2ODI0YmZhZDNlNjQ1OGZiZTJmNWU1YjkyNGVlODZmID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8yOTc0YTFkZTZmNTg0YTA3YmRiYjUwZjQwN2FiMDE3NSA9ICQoYDxkaXYgaWQ9Imh0bWxfMjk3NGExZGU2ZjU4NGEwN2JkYmI1MGY0MDdhYjAxNzUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsaWZmc2lkZSwgQ2xpZmZjcmVzdCwgU2NhcmJvcm91Z2ggVmlsbGFnZSBXZXN0LCBTY2FyYm9yb3VnaDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83NjgyNGJmYWQzZTY0NThmYmUyZjVlNWI5MjRlZTg2Zi5zZXRDb250ZW50KGh0bWxfMjk3NGExZGU2ZjU4NGEwN2JkYmI1MGY0MDdhYjAxNzUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q3YjY1NTkyNmE2NjRiMzM5NWU2M2FmYWRlMmVlMWMwLmJpbmRQb3B1cChwb3B1cF83NjgyNGJmYWQzZTY0NThmYmUyZjVlNWI5MjRlZTg2ZikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjhhNmFlN2VjM2EwNDQ4OGJlM2Q0MDZjYjAxZjc4OWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43ODkwNTMsIC03OS40MDg0OTI3OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83OWFkYjE0YzVlYjI0ZmE0YjJjZDc0ZTYwNmFkM2MxOCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNzBkODk0ZTBiMzhjNDg0NGI5NzE3N2ZmNmZmM2FhYzUgPSAkKGA8ZGl2IGlkPSJodG1sXzcwZDg5NGUwYjM4YzQ4NDRiOTcxNzdmZjZmZjNhYWM1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaWxsb3dkYWxlLCBOZXd0b25icm9vaywgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83OWFkYjE0YzVlYjI0ZmE0YjJjZDc0ZTYwNmFkM2MxOC5zZXRDb250ZW50KGh0bWxfNzBkODk0ZTBiMzhjNDg0NGI5NzE3N2ZmNmZmM2FhYzUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzI4YTZhZTdlYzNhMDQ0ODhiZTNkNDA2Y2IwMWY3ODliLmJpbmRQb3B1cChwb3B1cF83OWFkYjE0YzVlYjI0ZmE0YjJjZDc0ZTYwNmFkM2MxOCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZWQ5YzE2ZmU0OGFkNDQ2NzliNzFiZWFjNTM2MDQ0ZTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjg0OTY0LCAtNzkuNDk1Njk3NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMTQ2MmQ4MmIyZTdiNDM5ZmFhYWI5NDAxMzgzM2UwMzEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2EyNTk0ZTZhY2NhMzRmOWI5YjFjYTVkYWQ2ZjNiYmQ1ID0gJChgPGRpdiBpZD0iaHRtbF9hMjU5NGU2YWNjYTM0ZjliOWIxY2E1ZGFkNmYzYmJkNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG93bnN2aWV3LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzE0NjJkODJiMmU3YjQzOWZhYWFiOTQwMTM4MzNlMDMxLnNldENvbnRlbnQoaHRtbF9hMjU5NGU2YWNjYTM0ZjliOWIxY2E1ZGFkNmYzYmJkNSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZWQ5YzE2ZmU0OGFkNDQ2NzliNzFiZWFjNTM2MDQ0ZTUuYmluZFBvcHVwKHBvcHVwXzE0NjJkODJiMmU3YjQzOWZhYWFiOTQwMTM4MzNlMDMxKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wYjZhNjg0ODFlOTU0NjEzYTJmYzliOTU0YzM2ZTRmYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1OTUyNTUsIC03OS4zNDA5MjNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMmZmNzA1OTdmYTIzNGE2NmEwZGRmMWRlNzQ1ZDcxOTIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzNiNDg5Y2VlZGZhNzRhNTc5NTEzZDVkYWNkYjMwZDRiID0gJChgPGRpdiBpZD0iaHRtbF8zYjQ4OWNlZWRmYTc0YTU3OTUxM2Q1ZGFjZGIzMGQ0YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3R1ZGlvIERpc3RyaWN0LCBFYXN0IFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMmZmNzA1OTdmYTIzNGE2NmEwZGRmMWRlNzQ1ZDcxOTIuc2V0Q29udGVudChodG1sXzNiNDg5Y2VlZGZhNzRhNTc5NTEzZDVkYWNkYjMwZDRiKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wYjZhNjg0ODFlOTU0NjEzYTJmYzliOTU0YzM2ZTRmYi5iaW5kUG9wdXAocG9wdXBfMmZmNzA1OTdmYTIzNGE2NmEwZGRmMWRlNzQ1ZDcxOTIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzIwMDhjM2I5NzI5NjQ5OGU4NDA1ZmY3YWNjM2M4ZTlkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzMzMjgyNSwgLTc5LjQxOTc0OTddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZWFhZmVkYmQzMDU2NGM1NTllOGM1ZWM1NWQwYWQ5YTggPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzJhMDkwYjhhODkyZTRhZTlhMzJmZjJiZjIxY2M3ZTZiID0gJChgPGRpdiBpZD0iaHRtbF8yYTA5MGI4YTg5MmU0YWU5YTMyZmYyYmYyMWNjN2U2YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmVkZm9yZCBQYXJrLCBMYXdyZW5jZSBNYW5vciBFYXN0LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2VhYWZlZGJkMzA1NjRjNTU5ZThjNWVjNTVkMGFkOWE4LnNldENvbnRlbnQoaHRtbF8yYTA5MGI4YTg5MmU0YWU5YTMyZmYyYmYyMWNjN2U2Yik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjAwOGMzYjk3Mjk2NDk4ZTg0MDVmZjdhY2MzYzhlOWQuYmluZFBvcHVwKHBvcHVwX2VhYWZlZGJkMzA1NjRjNTU5ZThjNWVjNTVkMGFkOWE4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mNmY5YjJkMmJjM2U0NmEzYWNhYmJiNjBhMjU0NTAxMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5MTExNTgsIC03OS40NzYwMTMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9mMzc2YWUyMDk5ZWU0ZTFlYjM5NzljNDE2ODlkZTcxMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMWM3NjM0YmYzMDI5NGFjMThiMzY3YmQxMzJjOTE1NzMgPSAkKGA8ZGl2IGlkPSJodG1sXzFjNzYzNGJmMzAyOTRhYzE4YjM2N2JkMTMyYzkxNTczIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EZWwgUmF5LCBNb3VudCBEZW5uaXMsIEtlZWxzZGFsZSBhbmQgU2lsdmVydGhvcm4sIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZjM3NmFlMjA5OWVlNGUxZWIzOTc5YzQxNjg5ZGU3MTMuc2V0Q29udGVudChodG1sXzFjNzYzNGJmMzAyOTRhYzE4YjM2N2JkMTMyYzkxNTczKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9mNmY5YjJkMmJjM2U0NmEzYWNhYmJiNjBhMjU0NTAxMS5iaW5kUG9wdXAocG9wdXBfZjM3NmFlMjA5OWVlNGUxZWIzOTc5YzQxNjg5ZGU3MTMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYxOTQ1NjcwOWZmOTRkZTRiMGM3NjcyOTE5Yzk0YjIxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI0NzY1OSwgLTc5LjUzMjI0MjQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2ZmZTE2NWFiZGYwMDQ4ZTlhNjY4NTE3Yjg3ZDE2NzA2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9iMzg0MTEyZTgyYjM0ZDg4OGY0OGZkNGZlNWNlYjI4ZCA9ICQoYDxkaXYgaWQ9Imh0bWxfYjM4NDExMmU4MmIzNGQ4ODhmNDhmZDRmZTVjZWIyOGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkh1bWJlcmxlYSwgRW1lcnksIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZmZlMTY1YWJkZjAwNDhlOWE2Njg1MTdiODdkMTY3MDYuc2V0Q29udGVudChodG1sX2IzODQxMTJlODJiMzRkODg4ZjQ4ZmQ0ZmU1Y2ViMjhkKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82MTk0NTY3MDlmZjk0ZGU0YjBjNzY3MjkxOWM5NGIyMS5iaW5kUG9wdXAocG9wdXBfZmZlMTY1YWJkZjAwNDhlOWE2Njg1MTdiODdkMTY3MDYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2M3ZjNiNzI3Njg0ZTRiMDY5NTg5N2FjMGUxNGU0MDM3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkyNjU3MDAwMDAwMDA0LCAtNzkuMjY0ODQ4MV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80YWY1YTBkYjdjZmI0OWM2YjQyNGI3OGQwMDQxMDlhYiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNzkzNTMzMTNmYTllNDQ1ZTlkOGE4YjAxOGVmYTM2YjQgPSAkKGA8ZGl2IGlkPSJodG1sXzc5MzUzMzEzZmE5ZTQ0NWU5ZDhhOGIwMThlZmEzNmI0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CaXJjaCBDbGlmZiwgQ2xpZmZzaWRlIFdlc3QsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzRhZjVhMGRiN2NmYjQ5YzZiNDI0Yjc4ZDAwNDEwOWFiLnNldENvbnRlbnQoaHRtbF83OTM1MzMxM2ZhOWU0NDVlOWQ4YThiMDE4ZWZhMzZiNCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYzdmM2I3Mjc2ODRlNGIwNjk1ODk3YWMwZTE0ZTQwMzcuYmluZFBvcHVwKHBvcHVwXzRhZjVhMGRiN2NmYjQ5YzZiNDI0Yjc4ZDAwNDEwOWFiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82MDE0YzI0YzNiNGU0N2U3OGY4ODQ0ZjFmNWIwZGUwYSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MDExOTksIC03OS40MDg0OTI3OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lYzRlODZjMmRmYjE0MDhkOTA5ZDRmZWQ1ODQyNGE5NSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDU4NzNjODEzOTJhNDI2MGFlY2YwNWY4NmM2YjRjZDUgPSAkKGA8ZGl2IGlkPSJodG1sXzQ1ODczYzgxMzkyYTQyNjBhZWNmMDVmODZjNmI0Y2Q1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaWxsb3dkYWxlLCBXaWxsb3dkYWxlIEVhc3QsIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWM0ZTg2YzJkZmIxNDA4ZDkwOWQ0ZmVkNTg0MjRhOTUuc2V0Q29udGVudChodG1sXzQ1ODczYzgxMzkyYTQyNjBhZWNmMDVmODZjNmI0Y2Q1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82MDE0YzI0YzNiNGU0N2U3OGY4ODQ0ZjFmNWIwZGUwYS5iaW5kUG9wdXAocG9wdXBfZWM0ZTg2YzJkZmIxNDA4ZDkwOWQ0ZmVkNTg0MjRhOTUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY1MDE0YWI5N2U4OTQxYjU5ZWJiYjk3ZmMzYTM0Njc4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzYxNjMxMywgLTc5LjUyMDk5OTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2JjZGNkODVkNDY0ZTQxZWE4NGM0ZTJmZGJmMjNkMWRlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8wMjljYWYxOGFhY2U0OThmOTQyNDUxZGZmYzE3YzBjNSA9ICQoYDxkaXYgaWQ9Imh0bWxfMDI5Y2FmMThhYWNlNDk4Zjk0MjQ1MWRmZmMxN2MwYzUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldywgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iY2RjZDg1ZDQ2NGU0MWVhODRjNGUyZmRiZjIzZDFkZS5zZXRDb250ZW50KGh0bWxfMDI5Y2FmMThhYWNlNDk4Zjk0MjQ1MWRmZmMxN2MwYzUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzY1MDE0YWI5N2U4OTQxYjU5ZWJiYjk3ZmMzYTM0Njc4LmJpbmRQb3B1cChwb3B1cF9iY2RjZDg1ZDQ2NGU0MWVhODRjNGUyZmRiZjIzZDFkZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMmFiZDFiZTZkZmQxNDU5NTljYmVjNWFkNjI3M2E4NTcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjgwMjA1LCAtNzkuMzg4NzkwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iZjlmODQ1NmY1NzM0MzdhOGY0NGMyMmYxNmQ5OGQ4MiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfY2M2MTcyZDMyNWY1NDg4MmJhNWE1MWNjOTFhZDYxMTMgPSAkKGA8ZGl2IGlkPSJodG1sX2NjNjE3MmQzMjVmNTQ4ODJiYTVhNTFjYzkxYWQ2MTEzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MYXdyZW5jZSBQYXJrLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYmY5Zjg0NTZmNTczNDM3YThmNDRjMjJmMTZkOThkODIuc2V0Q29udGVudChodG1sX2NjNjE3MmQzMjVmNTQ4ODJiYTVhNTFjYzkxYWQ2MTEzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8yYWJkMWJlNmRmZDE0NTk1OWNiZWM1YWQ2MjczYTg1Ny5iaW5kUG9wdXAocG9wdXBfYmY5Zjg0NTZmNTczNDM3YThmNDRjMjJmMTZkOThkODIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA3MWUxNWViNzk0NjQ3NDRiMDgyMDcxNTBkODZkMjNmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzExNjk0OCwgLTc5LjQxNjkzNTU5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzM0ZjFiZDAyOTRkMzQxMGRiZjZlYjY2ZTEyMjdiMTY4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lOWM5YjI1YzU5MjM0NzBkYWFmMGRkN2I1OWFkZjFhNSA9ICQoYDxkaXYgaWQ9Imh0bWxfZTljOWIyNWM1OTIzNDcwZGFhZjBkZDdiNTlhZGYxYTUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJvc2VsYXduLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzRmMWJkMDI5NGQzNDEwZGJmNmViNjZlMTIyN2IxNjguc2V0Q29udGVudChodG1sX2U5YzliMjVjNTkyMzQ3MGRhYWYwZGQ3YjU5YWRmMWE1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wNzFlMTVlYjc5NDY0NzQ0YjA4MjA3MTUwZDg2ZDIzZi5iaW5kUG9wdXAocG9wdXBfMzRmMWJkMDI5NGQzNDEwZGJmNmViNjZlMTIyN2IxNjgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzFiYjE2NjA3MWY0YjQ1NjFhOTEzYWJhYzA3MTNiODllID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjczMTg1Mjk5OTk5OTksIC03OS40ODcyNjE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9hY2M3ZGM1ZWVhZDM0MjFlYmM2MmRmYTg0YjlkMTcyYiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNGQxNmVjMDc2NjBiNDllZDk5MDNhYWRiZDg3NjM4MDUgPSAkKGA8ZGl2IGlkPSJodG1sXzRkMTZlYzA3NjYwYjQ5ZWQ5OTAzYWFkYmQ4NzYzODA1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SdW5ueW1lZGUsIFRoZSBKdW5jdGlvbiBOb3J0aCwgWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9hY2M3ZGM1ZWVhZDM0MjFlYmM2MmRmYTg0YjlkMTcyYi5zZXRDb250ZW50KGh0bWxfNGQxNmVjMDc2NjBiNDllZDk5MDNhYWRiZDg3NjM4MDUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzFiYjE2NjA3MWY0YjQ1NjFhOTEzYWJhYzA3MTNiODllLmJpbmRQb3B1cChwb3B1cF9hY2M3ZGM1ZWVhZDM0MjFlYmM2MmRmYTg0YjlkMTcyYikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMmEyNGY3MWZlODkyNDJhODlhM2Q3YjZlMTc2OTAzMjMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY4NzYsIC03OS41MTgxODg0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lZmJkMjJmZDhjYjQ0NTQzYWIyMjY0MjI4ZjUxMjUzNCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZTk5Y2VkNTI2NjRhNGU5Mjg1M2U5YTg1MjU3NTdlNmEgPSAkKGA8ZGl2IGlkPSJodG1sX2U5OWNlZDUyNjY0YTRlOTI4NTNlOWE4NTI1NzU3ZTZhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XZXN0b24sIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWZiZDIyZmQ4Y2I0NDU0M2FiMjI2NDIyOGY1MTI1MzQuc2V0Q29udGVudChodG1sX2U5OWNlZDUyNjY0YTRlOTI4NTNlOWE4NTI1NzU3ZTZhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8yYTI0ZjcxZmU4OTI0MmE4OWEzZDdiNmUxNzY5MDMyMy5iaW5kUG9wdXAocG9wdXBfZWZiZDIyZmQ4Y2I0NDU0M2FiMjI2NDIyOGY1MTI1MzQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzg4NzVjMzAwZDc1ZDQ1NThhZjA0ZGZiZDQ1YmFmODJjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU3NDA5NiwgLTc5LjI3MzMwNDAwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzhjMDhmOTU3YTY4MDQxMjQ4ZGIzZTIwY2Y1NTVmMjQ0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF80NTE1ZTg2MGI2OWI0NjM1OGJmNzRkMTgxNDM1MGZkZCA9ICQoYDxkaXYgaWQ9Imh0bWxfNDUxNWU4NjBiNjliNDYzNThiZjc0ZDE4MTQzNTBmZGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvcnNldCBQYXJrLCBXZXhmb3JkIEhlaWdodHMsIFNjYXJib3JvdWdoIFRvd24gQ2VudHJlLCBTY2FyYm9yb3VnaDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF84YzA4Zjk1N2E2ODA0MTI0OGRiM2UyMGNmNTU1ZjI0NC5zZXRDb250ZW50KGh0bWxfNDUxNWU4NjBiNjliNDYzNThiZjc0ZDE4MTQzNTBmZGQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzg4NzVjMzAwZDc1ZDQ1NThhZjA0ZGZiZDQ1YmFmODJjLmJpbmRQb3B1cChwb3B1cF84YzA4Zjk1N2E2ODA0MTI0OGRiM2UyMGNmNTU1ZjI0NCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzBmOTIzMDY0ZGYyNDNhM2IyYzUzYjM2YTkzYjIxZjUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTI3NTgyOTk5OTk5OTYsIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzcwNWZkNTY2OWY1NDRhODZiMzUyNmQ1ODVlMWI1MGU0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81ZTY4ZjFiMWUyN2Y0YTIzOTNlOGQwYzliN2VkZjgxOCA9ICQoYDxkaXYgaWQ9Imh0bWxfNWU2OGYxYjFlMjdmNGEyMzkzZThkMGM5YjdlZGY4MTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPllvcmsgTWlsbHMgV2VzdCwgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83MDVmZDU2NjlmNTQ0YTg2YjM1MjZkNTg1ZTFiNTBlNC5zZXRDb250ZW50KGh0bWxfNWU2OGYxYjFlMjdmNGEyMzkzZThkMGM5YjdlZGY4MTgpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2MwZjkyMzA2NGRmMjQzYTNiMmM1M2IzNmE5M2IyMWY1LmJpbmRQb3B1cChwb3B1cF83MDVmZDU2NjlmNTQ0YTg2YjM1MjZkNTg1ZTFiNTBlNCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDU5ZDRiYTc5YmQwNGMzYmE4ZmU2ZTExZmZhZGUwYzEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTI3NTExLCAtNzkuMzkwMTk3NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9hNDlhNDc0NzAyNzg0MGRhYThiYWRjYjQ2ZjE3NjBlYyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMWY3NmNkYTk1NTUyNDRlM2JiYzNhYmQ0OGJiZjIzOWEgPSAkKGA8ZGl2IGlkPSJodG1sXzFmNzZjZGE5NTU1MjQ0ZTNiYmMzYWJkNDhiYmYyMzlhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EYXZpc3ZpbGxlIE5vcnRoLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYTQ5YTQ3NDcwMjc4NDBkYWE4YmFkY2I0NmYxNzYwZWMuc2V0Q29udGVudChodG1sXzFmNzZjZGE5NTU1MjQ0ZTNiYmMzYWJkNDhiYmYyMzlhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wNTlkNGJhNzliZDA0YzNiYThmZTZlMTFmZmFkZTBjMS5iaW5kUG9wdXAocG9wdXBfYTQ5YTQ3NDcwMjc4NDBkYWE4YmFkY2I0NmYxNzYwZWMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA5ODJlMzYzNjg2YjRiZDdiZWRlNzgyYzgwYzk2NDA0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk2OTQ3NiwgLTc5LjQxMTMwNzIwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2U2ZDE4ODIxYTY0MzRmMTM4NDJjODNlZTZkZTUzYzA2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83YmI4NzYwMDA1M2U0YmJiODNlNGI4YWRmNDY5YTk0MyA9ICQoYDxkaXYgaWQ9Imh0bWxfN2JiODc2MDAwNTNlNGJiYjgzZTRiOGFkZjQ2OWE5NDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZvcmVzdCBIaWxsIE5vcnRoICZhbXA7IFdlc3QsIEZvcmVzdCBIaWxsIFJvYWQgUGFyaywgQ2VudHJhbCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2U2ZDE4ODIxYTY0MzRmMTM4NDJjODNlZTZkZTUzYzA2LnNldENvbnRlbnQoaHRtbF83YmI4NzYwMDA1M2U0YmJiODNlNGI4YWRmNDY5YTk0Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMDk4MmUzNjM2ODZiNGJkN2JlZGU3ODJjODBjOTY0MDQuYmluZFBvcHVwKHBvcHVwX2U2ZDE4ODIxYTY0MzRmMTM4NDJjODNlZTZkZTUzYzA2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jOWRiOTViMTExYTk0MjcxODQ4MjBiNDI3MTk5ZjUzOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MTYwODMsIC03OS40NjQ3NjMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9jZTBlMTJmMDc3NWE0MWRlOWRlZjk4ODRiNDY3NGY2MiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMzg0MGNiODJkYmYzNGE3ZWE0NTU3MjU1OTM5NmE4NjMgPSAkKGA8ZGl2IGlkPSJodG1sXzM4NDBjYjgyZGJmMzRhN2VhNDU1NzI1NTkzOTZhODYzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IaWdoIFBhcmssIFRoZSBKdW5jdGlvbiBTb3V0aCwgV2VzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2NlMGUxMmYwNzc1YTQxZGU5ZGVmOTg4NGI0Njc0ZjYyLnNldENvbnRlbnQoaHRtbF8zODQwY2I4MmRiZjM0YTdlYTQ1NTcyNTU5Mzk2YTg2Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYzlkYjk1YjExMWE5NDI3MTg0ODIwYjQyNzE5OWY1MzguYmluZFBvcHVwKHBvcHVwX2NlMGUxMmYwNzc1YTQxZGU5ZGVmOTg4NGI0Njc0ZjYyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MGRjNDgwYzlhY2E0OWJjYTI0ZDcyMGRlZGFkMGY3NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5NjMxOSwgLTc5LjUzMjI0MjQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzM1ODhiNzhkNzNiNjQzYzI5ZGM3MmI4MzMxMGQxZTAwID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8yODZhZDA3MGJkYzI0ZWUzYjM3ZTJhZDFhMTZhMjM5MyA9ICQoYDxkaXYgaWQ9Imh0bWxfMjg2YWQwNzBiZGMyNGVlM2IzN2UyYWQxYTE2YTIzOTMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldlc3Rtb3VudCwgRXRvYmljb2tlPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzM1ODhiNzhkNzNiNjQzYzI5ZGM3MmI4MzMxMGQxZTAwLnNldENvbnRlbnQoaHRtbF8yODZhZDA3MGJkYzI0ZWUzYjM3ZTJhZDFhMTZhMjM5Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNTBkYzQ4MGM5YWNhNDliY2EyNGQ3MjBkZWRhZDBmNzcuYmluZFBvcHVwKHBvcHVwXzM1ODhiNzhkNzNiNjQzYzI5ZGM3MmI4MzMxMGQxZTAwKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hOTZmM2M1ZGQ0NmQ0ZGM2OTI3YWQyN2IwNmVkZWRkOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1MDA3MTUwMDAwMDAwNCwgLTc5LjI5NTg0OTFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMmUzNGFmYTUwYzE3NGIyMzk4MjYzMjI1M2U2YjE5NWMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzcwMDk1NDEzYjA3ZjRiZjI4MzAyZmRiYTNkMTFmNTJmID0gJChgPGRpdiBpZD0iaHRtbF83MDA5NTQxM2IwN2Y0YmYyODMwMmZkYmEzZDExZjUyZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2V4Zm9yZCwgTWFyeXZhbGUsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzJlMzRhZmE1MGMxNzRiMjM5ODI2MzIyNTNlNmIxOTVjLnNldENvbnRlbnQoaHRtbF83MDA5NTQxM2IwN2Y0YmYyODMwMmZkYmEzZDExZjUyZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTk2ZjNjNWRkNDZkNGRjNjkyN2FkMjdiMDZlZGVkZDguYmluZFBvcHVwKHBvcHVwXzJlMzRhZmE1MGMxNzRiMjM5ODI2MzIyNTNlNmIxOTVjKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mOTc5NGZkYWI1YmQ0NDJmYTJiZWMzNWFmOWUwMzRiOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4MjczNjQsIC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2IyZjhiY2ViNWJhNDQxMWQ4NDkyOWIzMjIwOWEwMDdlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zZjE2ODkwYTNkNjM0NzU5OGM3NTE0N2E0ODY5OTI3MiA9ICQoYDxkaXYgaWQ9Imh0bWxfM2YxNjg5MGEzZDYzNDc1OThjNzUxNDdhNDg2OTkyNzIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldpbGxvd2RhbGUsIFdpbGxvd2RhbGUgV2VzdCwgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iMmY4YmNlYjViYTQ0MTFkODQ5MjliMzIyMDlhMDA3ZS5zZXRDb250ZW50KGh0bWxfM2YxNjg5MGEzZDYzNDc1OThjNzUxNDdhNDg2OTkyNzIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Y5Nzk0ZmRhYjViZDQ0MmZhMmJlYzM1YWY5ZTAzNGI4LmJpbmRQb3B1cChwb3B1cF9iMmY4YmNlYjViYTQ0MTFkODQ5MjliMzIyMDlhMDA3ZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWMyNmViZjQ1YzQ4NDM4Y2E2NjZhNzAyM2QzODQ3N2EgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTUzODM0LCAtNzkuNDA1Njc4NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOGYzNmU3ODkwOTYxNDk2NTgxM2JkMzVhMmU2OTI3NWUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzVjNTQwYzc0YTA3MzRiNTNhNzNkNjVlZmYyM2E2YjcyID0gJChgPGRpdiBpZD0iaHRtbF81YzU0MGM3NGEwNzM0YjUzYTczZDY1ZWZmMjNhNmI3MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGggVG9yb250byBXZXN0LCBMYXdyZW5jZSBQYXJrLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOGYzNmU3ODkwOTYxNDk2NTgxM2JkMzVhMmU2OTI3NWUuc2V0Q29udGVudChodG1sXzVjNTQwYzc0YTA3MzRiNTNhNzNkNjVlZmYyM2E2YjcyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9hYzI2ZWJmNDVjNDg0MzhjYTY2NmE3MDIzZDM4NDc3YS5iaW5kUG9wdXAocG9wdXBfOGYzNmU3ODkwOTYxNDk2NTgxM2JkMzVhMmU2OTI3NWUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NjMjk0YWVhNDIwMjRkYjJiMzhkYmYwYzliOWViNjE2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjcyNzA5NywgLTc5LjQwNTY3ODQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzE4NTU4N2Q1MzNkZjQwMDg4Y2E5NjZiNzM2MDkzMDI2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jOTdhNDQ2YjY1NjI0Y2MzOTEzMDI0NTQyMzI2ZjEzZSA9ICQoYDxkaXYgaWQ9Imh0bWxfYzk3YTQ0NmI2NTYyNGNjMzkxMzAyNDU0MjMyNmYxM2UiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRoZSBBbm5leCwgTm9ydGggTWlkdG93biwgWW9ya3ZpbGxlLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMTg1NTg3ZDUzM2RmNDAwODhjYTk2NmI3MzYwOTMwMjYuc2V0Q29udGVudChodG1sX2M5N2E0NDZiNjU2MjRjYzM5MTMwMjQ1NDIzMjZmMTNlKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jYzI5NGFlYTQyMDI0ZGIyYjM4ZGJmMGM5YjllYjYxNi5iaW5kUG9wdXAocG9wdXBfMTg1NTg3ZDUzM2RmNDAwODhjYTk2NmI3MzYwOTMwMjYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdmNGNiMjVjMjEyZjRjNzNiZmEwMWZlOTUxNDg5NGQ5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4OTU5NywgLTc5LjQ1NjMyNV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8wYjMyZWNlOWUzNDA0NWE3YjNjOTgzODBmNWI3YzYyYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYzkyYTI3NDg3Y2ZjNDgxNDkxN2NkZGY4Mjk4ZTA0M2QgPSAkKGA8ZGl2IGlkPSJodG1sX2M5MmEyNzQ4N2NmYzQ4MTQ5MTdjZGRmODI5OGUwNDNkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrZGFsZSwgUm9uY2VzdmFsbGVzLCBXZXN0IFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMGIzMmVjZTllMzQwNDVhN2IzYzk4MzgwZjViN2M2MmEuc2V0Q29udGVudChodG1sX2M5MmEyNzQ4N2NmYzQ4MTQ5MTdjZGRmODI5OGUwNDNkKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl83ZjRjYjI1YzIxMmY0YzczYmZhMDFmZTk1MTQ4OTRkOS5iaW5kUG9wdXAocG9wdXBfMGIzMmVjZTllMzQwNDVhN2IzYzk4MzgwZjViN2M2MmEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdlYmE2MmMzZWFkOTQ1YzhhZTBkMDVkMTYyZTA2MWQwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjM2OTY1NiwgLTc5LjYxNTgxODk5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2RiZWEyYmE2YTQxMjRhZGQ5ODQ1ODExN2NiMTM0NzVlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8wNTFlZWYyYTg4YjA0NDVhOWJmMzlkM2MwNWVjN2U4YyA9ICQoYDxkaXYgaWQ9Imh0bWxfMDUxZWVmMmE4OGIwNDQ1YTliZjM5ZDNjMDVlYzdlOGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNhbmFkYSBQb3N0IEdhdGV3YXkgUHJvY2Vzc2luZyBDZW50cmUsIE1pc3Npc3NhdWdhPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2RiZWEyYmE2YTQxMjRhZGQ5ODQ1ODExN2NiMTM0NzVlLnNldENvbnRlbnQoaHRtbF8wNTFlZWYyYTg4YjA0NDVhOWJmMzlkM2MwNWVjN2U4Yyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfN2ViYTYyYzNlYWQ5NDVjOGFlMGQwNWQxNjJlMDYxZDAuYmluZFBvcHVwKHBvcHVwX2RiZWEyYmE2YTQxMjRhZGQ5ODQ1ODExN2NiMTM0NzVlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lY2M5MDY4MTZhNmI0MDFkODA2Zjc4ZmE2MTk0NWM3NCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4ODkwNTQsIC03OS41NTQ3MjQ0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85OTI4ODdlNWY1MzA0MzE0YWEwZTBjZjNiNDdkOGE4YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZjdlMmY3MzA1NGEzNGNiMGI0YzRmMzZiOWQyNDQ5YWEgPSAkKGA8ZGl2IGlkPSJodG1sX2Y3ZTJmNzMwNTRhMzRjYjBiNGM0ZjM2YjlkMjQ0OWFhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5LaW5nc3ZpZXcgVmlsbGFnZSwgU3QuIFBoaWxsaXBzLCBNYXJ0aW4gR3JvdmUgR2FyZGVucywgUmljaHZpZXcgR2FyZGVucywgRXRvYmljb2tlPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzk5Mjg4N2U1ZjUzMDQzMTRhYTBlMGNmM2I0N2Q4YThiLnNldENvbnRlbnQoaHRtbF9mN2UyZjczMDU0YTM0Y2IwYjRjNGYzNmI5ZDI0NDlhYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZWNjOTA2ODE2YTZiNDAxZDgwNmY3OGZhNjE5NDVjNzQuYmluZFBvcHVwKHBvcHVwXzk5Mjg4N2U1ZjUzMDQzMTRhYTBlMGNmM2I0N2Q4YThiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kOTk3YTE4MDhmZWU0MTBkOGIyNzQ2YTIzYmUyYzlkYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5NDIwMDMsIC03OS4yNjIwMjk0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yN2E0OGY5NTFiNTM0MTYwODlkNjc5MDhhNTVlM2UxMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDZlNzJjNTcxNmM5NGUyOGEwMDM4ZThhYTEwZmJhZDQgPSAkKGA8ZGl2IGlkPSJodG1sXzQ2ZTcyYzU3MTZjOTRlMjhhMDAzOGU4YWExMGZiYWQ0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BZ2luY291cnQsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzI3YTQ4Zjk1MWI1MzQxNjA4OWQ2NzkwOGE1NWUzZTEzLnNldENvbnRlbnQoaHRtbF80NmU3MmM1NzE2Yzk0ZTI4YTAwMzhlOGFhMTBmYmFkNCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDk5N2ExODA4ZmVlNDEwZDhiMjc0NmEyM2JlMmM5ZGIuYmluZFBvcHVwKHBvcHVwXzI3YTQ4Zjk1MWI1MzQxNjA4OWQ2NzkwOGE1NWUzZTEzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMGYxODY5ZGRmNDQ0N2NhYTQwNmUwNjBjZDk5NmE3OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNDMyNDQsIC03OS4zODg3OTAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2I0YjAwMTg4Y2QwMTQzMjFiZjY1ODc4M2VhOTNkMGJkID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9kZDAwNWVjNGI1ZmU0OGZmOGE5ZjkyNjI1OGNmZjEzNCA9ICQoYDxkaXYgaWQ9Imh0bWxfZGQwMDVlYzRiNWZlNDhmZjhhOWY5MjYyNThjZmYxMzQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRhdmlzdmlsbGUsIENlbnRyYWwgVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iNGIwMDE4OGNkMDE0MzIxYmY2NTg3ODNlYTkzZDBiZC5zZXRDb250ZW50KGh0bWxfZGQwMDVlYzRiNWZlNDhmZjhhOWY5MjYyNThjZmYxMzQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2IwZjE4NjlkZGY0NDQ3Y2FhNDA2ZTA2MGNkOTk2YTc4LmJpbmRQb3B1cChwb3B1cF9iNGIwMDE4OGNkMDE0MzIxYmY2NTg3ODNlYTkzZDBiZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTUyN2UwMThmOGI1NDYyNTlmOTc3YWIyM2M3ODlhMmIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NjI2OTU2LCAtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83M2QxMzdkMzZkODQ0ZjIyYjUwMjI5OWE2NWI2MzNkYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDcyMzA2YzNjN2JiNDdmYTg3M2Y2YzIwNTUxYWM2NjUgPSAkKGA8ZGl2IGlkPSJodG1sXzQ3MjMwNmMzYzdiYjQ3ZmE4NzNmNmMyMDU1MWFjNjY1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Vbml2ZXJzaXR5IG9mIFRvcm9udG8sIEhhcmJvcmQsIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNzNkMTM3ZDM2ZDg0NGYyMmI1MDIyOTlhNjViNjMzZGEuc2V0Q29udGVudChodG1sXzQ3MjMwNmMzYzdiYjQ3ZmE4NzNmNmMyMDU1MWFjNjY1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNTI3ZTAxOGY4YjU0NjI1OWY5NzdhYjIzYzc4OWEyYi5iaW5kUG9wdXAocG9wdXBfNzNkMTM3ZDM2ZDg0NGYyMmI1MDIyOTlhNjViNjMzZGEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2E2NDM1OTEyNzgzODQwNDQ4YTdhODU0MTZhODdhYjlmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUxNTcwNiwgLTc5LjQ4NDQ0OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMDU4OTRjYmE3OTdmNDdlZTg5ZmRlZGE0ZTIzN2I3MzYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2U5ODgzNGI2ZGU0YzQ5MDhiNzE5MDhlMDk1M2NkN2M5ID0gJChgPGRpdiBpZD0iaHRtbF9lOTg4MzRiNmRlNGM0OTA4YjcxOTA4ZTA5NTNjZDdjOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UnVubnltZWRlLCBTd2Fuc2VhLCBXZXN0IFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMDU4OTRjYmE3OTdmNDdlZTg5ZmRlZGE0ZTIzN2I3MzYuc2V0Q29udGVudChodG1sX2U5ODgzNGI2ZGU0YzQ5MDhiNzE5MDhlMDk1M2NkN2M5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9hNjQzNTkxMjc4Mzg0MDQ0OGE3YTg1NDE2YTg3YWI5Zi5iaW5kUG9wdXAocG9wdXBfMDU4OTRjYmE3OTdmNDdlZTg5ZmRlZGE0ZTIzN2I3MzYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzVlYmU3ZjM5ZDViNDRjODZiZGJjYmUxNjI2MmQ4YjVmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzgxNjM3NSwgLTc5LjMwNDMwMjFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNTliMjNhNTZhMzhhNGU0MDhmMzUxODljZGFlYjcyNTcgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzU1ZTJjZTBmYWU2MjQ5ZDI4MzY5MTU1ZDk0ZThiNTFhID0gJChgPGRpdiBpZD0iaHRtbF81NWUyY2UwZmFlNjI0OWQyODM2OTE1NWQ5NGU4YjUxYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2xhcmtzIENvcm5lcnMsIFRhbSBPJiMzOTtTaGFudGVyLCBTdWxsaXZhbiwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNTliMjNhNTZhMzhhNGU0MDhmMzUxODljZGFlYjcyNTcuc2V0Q29udGVudChodG1sXzU1ZTJjZTBmYWU2MjQ5ZDI4MzY5MTU1ZDk0ZThiNTFhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81ZWJlN2YzOWQ1YjQ0Yzg2YmRiY2JlMTYyNjJkOGI1Zi5iaW5kUG9wdXAocG9wdXBfNTliMjNhNTZhMzhhNGU0MDhmMzUxODljZGFlYjcyNTcpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzEzM2VjMjUxYmU2YzQ1OTY4ODMzZTg5NjZhZDYyYWU1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg5NTc0MywgLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzY2ZjU2NDExZjE2YjQxZTM4NWJmM2Q1OTZiYzE3MDY5ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mNjI3ZDZlMTA4NTY0ZmNmYmIwOGE3YzFmZTQ4MzJlZiA9ICQoYDxkaXYgaWQ9Imh0bWxfZjYyN2Q2ZTEwODU2NGZjZmJiMDhhN2MxZmU0ODMyZWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1vb3JlIFBhcmssIFN1bW1lcmhpbGwgRWFzdCwgQ2VudHJhbCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzY2ZjU2NDExZjE2YjQxZTM4NWJmM2Q1OTZiYzE3MDY5LnNldENvbnRlbnQoaHRtbF9mNjI3ZDZlMTA4NTY0ZmNmYmIwOGE3YzFmZTQ4MzJlZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMTMzZWMyNTFiZTZjNDU5Njg4MzNlODk2NmFkNjJhZTUuYmluZFBvcHVwKHBvcHVwXzY2ZjU2NDExZjE2YjQxZTM4NWJmM2Q1OTZiYzE3MDY5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85MGFhOTM1NjE3NDM0OTQxODBiODFjMjYwM2NiZjBjNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MzIwNTcsIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzIxZDE2ZjlhZDJiNTRiN2M5OGE0ODA2MWUzYjcyNWQ0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jY2RiZGQ0NTFlZDc0YjdkODQ4OWNmNmU1ZDFjYzMyMyA9ICQoYDxkaXYgaWQ9Imh0bWxfY2NkYmRkNDUxZWQ3NGI3ZDg0ODljZjZlNWQxY2MzMjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPktlbnNpbmd0b24gTWFya2V0LCBDaGluYXRvd24sIEdyYW5nZSBQYXJrLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzIxZDE2ZjlhZDJiNTRiN2M5OGE0ODA2MWUzYjcyNWQ0LnNldENvbnRlbnQoaHRtbF9jY2RiZGQ0NTFlZDc0YjdkODQ4OWNmNmU1ZDFjYzMyMyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTBhYTkzNTYxNzQzNDk0MTgwYjgxYzI2MDNjYmYwYzQuYmluZFBvcHVwKHBvcHVwXzIxZDE2ZjlhZDJiNTRiN2M5OGE0ODA2MWUzYjcyNWQ0KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wYWU3N2FjZWNhMGQ0M2UwYmEyMzJmNDg5ZDA4NGQyOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgxNTI1MjIsIC03OS4yODQ1NzcyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzZiMTcxMjQ3NzVmNjQzZDE5NzYxYWRhM2QwN2M0ZTRhID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF80ZWVhZWZiZWM1NjY0MDQ4OGRjZWFiZDcyYTBiZGNlOSA9ICQoYDxkaXYgaWQ9Imh0bWxfNGVlYWVmYmVjNTY2NDA0ODhkY2VhYmQ3MmEwYmRjZTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1pbGxpa2VuLCBBZ2luY291cnQgTm9ydGgsIFN0ZWVsZXMgRWFzdCwgTCYjMzk7QW1vcmVhdXggRWFzdCwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNmIxNzEyNDc3NWY2NDNkMTk3NjFhZGEzZDA3YzRlNGEuc2V0Q29udGVudChodG1sXzRlZWFlZmJlYzU2NjQwNDg4ZGNlYWJkNzJhMGJkY2U5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wYWU3N2FjZWNhMGQ0M2UwYmEyMzJmNDg5ZDA4NGQyOC5iaW5kUG9wdXAocG9wdXBfNmIxNzEyNDc3NWY2NDNkMTk3NjFhZGEzZDA3YzRlNGEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzE5YWY5Yzc1YTc0OTRlYWE4NDQ3ZDI4OWRhY2Q0Mjc0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg2NDEyMjk5OTk5OTksIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzQ1MWVjNDYxNjJmZjQxMzU4MTNjYjM1MjAwMGM4NzBjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zZTBjZTMyMmU5YzI0NzNhYThjYTNkZTNjMmRmZWNkZiA9ICQoYDxkaXYgaWQ9Imh0bWxfM2UwY2UzMjJlOWMyNDczYWE4Y2EzZGUzYzJkZmVjZGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN1bW1lcmhpbGwgV2VzdCwgUmF0aG5lbGx5LCBTb3V0aCBIaWxsLCBGb3Jlc3QgSGlsbCBTRSwgRGVlciBQYXJrLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDUxZWM0NjE2MmZmNDEzNTgxM2NiMzUyMDAwYzg3MGMuc2V0Q29udGVudChodG1sXzNlMGNlMzIyZTljMjQ3M2FhOGNhM2RlM2MyZGZlY2RmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xOWFmOWM3NWE3NDk0ZWFhODQ0N2QyODlkYWNkNDI3NC5iaW5kUG9wdXAocG9wdXBfNDUxZWM0NjE2MmZmNDEzNTgxM2NiMzUyMDAwYzg3MGMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY0YWY4MTI2ZmM2MjQ2M2Y5YTdmZTE0NGY3N2M2MTQwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4OTQ2NywgLTc5LjM5NDQxOTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYWIxOTA0ZGE3YjQ0NDlmNTg5MTAwOGM0Y2U0NjczZDIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzBkMmIzNzM3OTZlMzQxYzI4M2ZkM2VhYjllYjgxMjFhID0gJChgPGRpdiBpZD0iaHRtbF8wZDJiMzczNzk2ZTM0MWMyODNmZDNlYWI5ZWI4MTIxYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q04gVG93ZXIsIEtpbmcgYW5kIFNwYWRpbmEsIFJhaWx3YXkgTGFuZHMsIEhhcmJvdXJmcm9udCBXZXN0LCBCYXRodXJzdCBRdWF5LCBTb3V0aCBOaWFnYXJhLCBJc2xhbmQgYWlycG9ydCwgRG93bnRvd24gVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9hYjE5MDRkYTdiNDQ0OWY1ODkxMDA4YzRjZTQ2NzNkMi5zZXRDb250ZW50KGh0bWxfMGQyYjM3Mzc5NmUzNDFjMjgzZmQzZWFiOWViODEyMWEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzY0YWY4MTI2ZmM2MjQ2M2Y5YTdmZTE0NGY3N2M2MTQwLmJpbmRQb3B1cChwb3B1cF9hYjE5MDRkYTdiNDQ0OWY1ODkxMDA4YzRjZTQ2NzNkMikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGUzYmEzOWZhYmRkNDI0NDlhNGFkYTFlMmI1NWRhZjEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MDU2NDY2LCAtNzkuNTAxMzIwNzAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNzI3NmI0YjMxMzY5NGM5ZTgyNWE4MDE4OTY1MDE0YjMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2IzOWZjN2RkNDgxNzQyMmU5YTM5YjYyODgyZDYxMzNlID0gJChgPGRpdiBpZD0iaHRtbF9iMzlmYzdkZDQ4MTc0MjJlOWEzOWI2Mjg4MmQ2MTMzZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TmV3IFRvcm9udG8sIE1pbWljbyBTb3V0aCwgSHVtYmVyIEJheSBTaG9yZXMsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83Mjc2YjRiMzEzNjk0YzllODI1YTgwMTg5NjUwMTRiMy5zZXRDb250ZW50KGh0bWxfYjM5ZmM3ZGQ0ODE3NDIyZTlhMzliNjI4ODJkNjEzM2UpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2RlM2JhMzlmYWJkZDQyNDQ5YTRhZGExZTJiNTVkYWYxLmJpbmRQb3B1cChwb3B1cF83Mjc2YjRiMzEzNjk0YzllODI1YTgwMTg5NjUwMTRiMykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWEwZTMzNzM5YTcwNDljNjkxMjZjMDg1NTRmMGM0MGIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mzk0MTYzOTk5OTk5OTYsIC03OS41ODg0MzY5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzRkNGVhMzYyNmRmNDQ1OWZhOWZkNGI0M2RlNDIzNzVkID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF80ZWVmN2I0ZDU2YzU0Y2IxYWRiZGJjZDMwYmZkMTczMiA9ICQoYDxkaXYgaWQ9Imh0bWxfNGVlZjdiNGQ1NmM1NGNiMWFkYmRiY2QzMGJmZDE3MzIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlNvdXRoIFN0ZWVsZXMsIFNpbHZlcnN0b25lLCBIdW1iZXJnYXRlLCBKYW1lc3Rvd24sIE1vdW50IE9saXZlLCBCZWF1bW9uZCBIZWlnaHRzLCBUaGlzdGxldG93biwgQWxiaW9uIEdhcmRlbnMsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF80ZDRlYTM2MjZkZjQ0NTlmYTlmZDRiNDNkZTQyMzc1ZC5zZXRDb250ZW50KGh0bWxfNGVlZjdiNGQ1NmM1NGNiMWFkYmRiY2QzMGJmZDE3MzIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2FhMGUzMzczOWE3MDQ5YzY5MTI2YzA4NTU0ZjBjNDBiLmJpbmRQb3B1cChwb3B1cF80ZDRlYTM2MjZkZjQ0NTlmYTlmZDRiNDNkZTQyMzc1ZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWE2OTBlMWIzYzQ2NGQ4M2E5NGNmNzA4YTZlN2RhMmIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43OTk1MjUyMDAwMDAwMDUsIC03OS4zMTgzODg3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2EwZmJhNWM1YTQ0NjQ1NWE5OWMyNGU2MDI1MzRhNGNmID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83ODdkODRlOTgxODA0Y2I0YTBlM2E0YWY2NmZmM2MxOCA9ICQoYDxkaXYgaWQ9Imh0bWxfNzg3ZDg0ZTk4MTgwNGNiNGEwZTNhNGFmNjZmZjNjMTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0ZWVsZXMgV2VzdCwgTCYjMzk7QW1vcmVhdXggV2VzdCwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYTBmYmE1YzVhNDQ2NDU1YTk5YzI0ZTYwMjUzNGE0Y2Yuc2V0Q29udGVudChodG1sXzc4N2Q4NGU5ODE4MDRjYjRhMGUzYTRhZjY2ZmYzYzE4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xYTY5MGUxYjNjNDY0ZDgzYTk0Y2Y3MDhhNmU3ZGEyYi5iaW5kUG9wdXAocG9wdXBfYTBmYmE1YzVhNDQ2NDU1YTk5YzI0ZTYwMjUzNGE0Y2YpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzhlMTFiNWNmN2M1YjRmMjM4MGNiMTRkNzkxZjdiMjg3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjc5NTYyNiwgLTc5LjM3NzUyOTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzFkZGRiNmQ5Y2I5ODQ2OTE4NzZmODgwY2EwODg3MjU4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83ZDc0NzBmODUwMTU0NjU4OTc5ZGIzYmI0MjIzY2IzYSA9ICQoYDxkaXYgaWQ9Imh0bWxfN2Q3NDcwZjg1MDE1NDY1ODk3OWRiM2JiNDIyM2NiM2EiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJvc2VkYWxlLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzFkZGRiNmQ5Y2I5ODQ2OTE4NzZmODgwY2EwODg3MjU4LnNldENvbnRlbnQoaHRtbF83ZDc0NzBmODUwMTU0NjU4OTc5ZGIzYmI0MjIzY2IzYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOGUxMWI1Y2Y3YzViNGYyMzgwY2IxNGQ3OTFmN2IyODcuYmluZFBvcHVwKHBvcHVwXzFkZGRiNmQ5Y2I5ODQ2OTE4NzZmODgwY2EwODg3MjU4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81OTc5YjBjY2UxMjk0MWJmYTNmOTg0NWQzMTdkOWQxMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NjQzNTIsIC03OS4zNzQ4NDU5OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iYzQ1MTViN2U0MmM0MmYwODIwOTUzMWU1YjBiZTQ5YyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMmZiYzczMjkxYjMxNDk5OTgzNTVmZTVkZGIzMTc2ZTMgPSAkKGA8ZGl2IGlkPSJodG1sXzJmYmM3MzI5MWIzMTQ5OTk4MzU1ZmU1ZGRiMzE3NmUzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdG4gQSBQTyBCb3hlcywgRG93bnRvd24gVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iYzQ1MTViN2U0MmM0MmYwODIwOTUzMWU1YjBiZTQ5Yy5zZXRDb250ZW50KGh0bWxfMmZiYzczMjkxYjMxNDk5OTgzNTVmZTVkZGIzMTc2ZTMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzU5NzliMGNjZTEyOTQxYmZhM2Y5ODQ1ZDMxN2Q5ZDExLmJpbmRQb3B1cChwb3B1cF9iYzQ1MTViN2U0MmM0MmYwODIwOTUzMWU1YjBiZTQ5YykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOWZkNGE2NDM0NTlmNGUxNGIyYTY0ZDU1MmM4ZTM3ZDcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MDI0MTM3MDAwMDAwMSwgLTc5LjU0MzQ4NDA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzc4NzI2MjI4MjZjYTQ0MjJiYjFjNTViMGE5NmExZjdkID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82ZjA4ODlmYmZmZjc0YmY1YmY1MmNkOGJkOTMwMWY5OSA9ICQoYDxkaXYgaWQ9Imh0bWxfNmYwODg5ZmJmZmY3NGJmNWJmNTJjZDhiZDkzMDFmOTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFsZGVyd29vZCwgTG9uZyBCcmFuY2gsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83ODcyNjIyODI2Y2E0NDIyYmIxYzU1YjBhOTZhMWY3ZC5zZXRDb250ZW50KGh0bWxfNmYwODg5ZmJmZmY3NGJmNWJmNTJjZDhiZDkzMDFmOTkpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzlmZDRhNjQzNDU5ZjRlMTRiMmE2NGQ1NTJjOGUzN2Q3LmJpbmRQb3B1cChwb3B1cF83ODcyNjIyODI2Y2E0NDIyYmIxYzU1YjBhOTZhMWY3ZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTc1YTUwZTEyYWRmNDQ4YmExNGEyYjQ2MWRhMzMwMTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY3NDgyOTk5OTk5OTQsIC03OS41OTQwNTQ0XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2ZkYjg3YmI3NmU1NjRmOWQ4ZWZhYjczZjEyZjgwZTcxID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lMzU4ZTFkYzc3NDc0N2I5OWU2Mzg5ZDQ2OGY3YzA5YiA9ICQoYDxkaXYgaWQ9Imh0bWxfZTM1OGUxZGM3NzQ3NDdiOTllNjM4OWQ0NjhmN2MwOWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk5vcnRod2VzdCwgV2VzdCBIdW1iZXIgLSBDbGFpcnZpbGxlLCBFdG9iaWNva2U8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZmRiODdiYjc2ZTU2NGY5ZDhlZmFiNzNmMTJmODBlNzEuc2V0Q29udGVudChodG1sX2UzNThlMWRjNzc0NzQ3Yjk5ZTYzODlkNDY4ZjdjMDliKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNzVhNTBlMTJhZGY0NDhiYTE0YTJiNDYxZGEzMzAxNS5iaW5kUG9wdXAocG9wdXBfZmRiODdiYjc2ZTU2NGY5ZDhlZmFiNzNmMTJmODBlNzEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ4ZWQxMWRjODNjOTRkY2VhMGQyMGJiMzI4MWZhMjNlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuODM2MTI0NzAwMDAwMDA2LCAtNzkuMjA1NjM2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNTQ2MmUyZGUwYWU2NDBmYThhMzY3YzI2OGMwMWM2ZGIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2NkNTRiNDhmNDE4MzRjYjQ4ZTBmNmRlZTgzYzg3OTdiID0gJChgPGRpdiBpZD0iaHRtbF9jZDU0YjQ4ZjQxODM0Y2I0OGUwZjZkZWU4M2M4Nzk3YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VXBwZXIgUm91Z2UsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzU0NjJlMmRlMGFlNjQwZmE4YTM2N2MyNjhjMDFjNmRiLnNldENvbnRlbnQoaHRtbF9jZDU0YjQ4ZjQxODM0Y2I0OGUwZjZkZWU4M2M4Nzk3Yik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNDhlZDExZGM4M2M5NGRjZWEwZDIwYmIzMjgxZmEyM2UuYmluZFBvcHVwKHBvcHVwXzU0NjJlMmRlMGFlNjQwZmE4YTM2N2MyNjhjMDFjNmRiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kZjE4MDgwMTJiYTA0ZGNiOGQyOGE3NTdhNmUyOWQxNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Nzk2NywgLTc5LjM2NzY3NTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOThmZjkzMDMzNDNhNDkzNTg3YzRhYzA3ZGY3ODBlYTUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2Y2YzNmOWFiNmFkZDQ5NmM5MDk0NDllODUxYTUxZWJmID0gJChgPGRpdiBpZD0iaHRtbF9mNmMzZjlhYjZhZGQ0OTZjOTA5NDQ5ZTg1MWE1MWViZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3QuIEphbWVzIFRvd24sIENhYmJhZ2V0b3duLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzk4ZmY5MzAzMzQzYTQ5MzU4N2M0YWMwN2RmNzgwZWE1LnNldENvbnRlbnQoaHRtbF9mNmMzZjlhYjZhZGQ0OTZjOTA5NDQ5ZTg1MWE1MWViZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZGYxODA4MDEyYmEwNGRjYjhkMjhhNzU3YTZlMjlkMTcuYmluZFBvcHVwKHBvcHVwXzk4ZmY5MzAzMzQzYTQ5MzU4N2M0YWMwN2RmNzgwZWE1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85NTExYjlhN2I3Mzc0OGJhODg0NDQ0YWM3Mzc4ODg3MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0ODQyOTIsIC03OS4zODIyODAyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzhhYzFmYTVkODM1NDRiOTliMDkzNTcyNDMyMTNmNWM2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83NzU2Y2FkMWY5Yjk0Mzk1YmI0ODFkNzkyYWI1YzZlOCA9ICQoYDxkaXYgaWQ9Imh0bWxfNzc1NmNhZDFmOWI5NDM5NWJiNDgxZDc5MmFiNWM2ZTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZpcnN0IENhbmFkaWFuIFBsYWNlLCBVbmRlcmdyb3VuZCBjaXR5LCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzhhYzFmYTVkODM1NDRiOTliMDkzNTcyNDMyMTNmNWM2LnNldENvbnRlbnQoaHRtbF83NzU2Y2FkMWY5Yjk0Mzk1YmI0ODFkNzkyYWI1YzZlOCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTUxMWI5YTdiNzM3NDhiYTg4NDQ0NGFjNzM3ODg4NzMuYmluZFBvcHVwKHBvcHVwXzhhYzFmYTVkODM1NDRiOTliMDkzNTcyNDMyMTNmNWM2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82YWFhN2ZhOGQ3MzQ0MTMxODQ1NjE2OWM5N2E0N2I5ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MzY1MzYwMDAwMDAwNSwgLTc5LjUwNjk0MzZdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZDcyNDUxOGVkMGY1NGMzMmI1MjdkNjczZDk2MGFmZjEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2M2ODViN2NkODQ3MDQ2OWY4ODM2OTlhNmQ2OTdlNTJhID0gJChgPGRpdiBpZD0iaHRtbF9jNjg1YjdjZDg0NzA0NjlmODgzNjk5YTZkNjk3ZTUyYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEtpbmdzd2F5LCBNb250Z29tZXJ5IFJvYWQsIE9sZCBNaWxsIE5vcnRoLCBFdG9iaWNva2U8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZDcyNDUxOGVkMGY1NGMzMmI1MjdkNjczZDk2MGFmZjEuc2V0Q29udGVudChodG1sX2M2ODViN2NkODQ3MDQ2OWY4ODM2OTlhNmQ2OTdlNTJhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82YWFhN2ZhOGQ3MzQ0MTMxODQ1NjE2OWM5N2E0N2I5ZS5iaW5kUG9wdXAocG9wdXBfZDcyNDUxOGVkMGY1NGMzMmI1MjdkNjczZDk2MGFmZjEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA1ZGY0ZDQyYThiYjQ0ODhiMzk4YzZhYTU4MDMxZGQ4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY1ODU5OSwgLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2Q3MmI2M2UyYjQzMzQ4NjFiYjdlOGIzZTgzY2ZjNzZlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83ZWY2YzAyZTg2ZDc0NmZjOTQzNDYzYjIxNmYyODQ5YSA9ICQoYDxkaXYgaWQ9Imh0bWxfN2VmNmMwMmU4NmQ3NDZmYzk0MzQ2M2IyMTZmMjg0OWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNodXJjaCBhbmQgV2VsbGVzbGV5LCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Q3MmI2M2UyYjQzMzQ4NjFiYjdlOGIzZTgzY2ZjNzZlLnNldENvbnRlbnQoaHRtbF83ZWY2YzAyZTg2ZDc0NmZjOTQzNDYzYjIxNmYyODQ5YSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMDVkZjRkNDJhOGJiNDQ4OGIzOThjNmFhNTgwMzFkZDguYmluZFBvcHVwKHBvcHVwX2Q3MmI2M2UyYjQzMzQ4NjFiYjdlOGIzZTgzY2ZjNzZlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xNjQwYmVmOGE0YWI0MWIwYWQxMWI3ZmE1YWI2YmEzYyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Mjc0MzksIC03OS4zMjE1NThdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYWQ5YzQwZDdhMDViNGVhYmE1OTRlNzIxY2NmYWJkMGYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzFhZjdhMTlhMTdhMjQ1NGZiMmRmYTBmZWFkYzI0MjI3ID0gJChgPGRpdiBpZD0iaHRtbF8xYWY3YTE5YTE3YTI0NTRmYjJkZmEwZmVhZGMyNDIyNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnVzaW5lc3MgcmVwbHkgbWFpbCBQcm9jZXNzaW5nIENlbnRyZSwgU291dGggQ2VudHJhbCBMZXR0ZXIgUHJvY2Vzc2luZyBQbGFudCBUb3JvbnRvLCBFYXN0IFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYWQ5YzQwZDdhMDViNGVhYmE1OTRlNzIxY2NmYWJkMGYuc2V0Q29udGVudChodG1sXzFhZjdhMTlhMTdhMjQ1NGZiMmRmYTBmZWFkYzI0MjI3KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNjQwYmVmOGE0YWI0MWIwYWQxMWI3ZmE1YWI2YmEzYy5iaW5kUG9wdXAocG9wdXBfYWQ5YzQwZDdhMDViNGVhYmE1OTRlNzIxY2NmYWJkMGYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y4ODYzYjllZDI5ZTQ2OGQ4ODg4ODM2M2RmOTczZWM1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjM2MjU3OSwgLTc5LjQ5ODUwOTA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2M2MjVkOWNhODc5MzQ3OTM5NWFkYTIwYmRlMTdjMzE2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mMWJiZjBhMGNlZDY0ZDA3YjI3NTBjNTI0YTIzYTIwZiA9ICQoYDxkaXYgaWQ9Imh0bWxfZjFiYmYwYTBjZWQ2NGQwN2IyNzUwYzUyNGEyM2EyMGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk9sZCBNaWxsIFNvdXRoLCBLaW5nJiMzOTtzIE1pbGwgUGFyaywgU3VubnlsZWEsIEh1bWJlciBCYXksIE1pbWljbyBORSwgVGhlIFF1ZWVuc3dheSBFYXN0LCBSb3lhbCBZb3JrIFNvdXRoIEVhc3QsIEtpbmdzd2F5IFBhcmsgU291dGggRWFzdCwgRXRvYmljb2tlPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2M2MjVkOWNhODc5MzQ3OTM5NWFkYTIwYmRlMTdjMzE2LnNldENvbnRlbnQoaHRtbF9mMWJiZjBhMGNlZDY0ZDA3YjI3NTBjNTI0YTIzYTIwZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZjg4NjNiOWVkMjllNDY4ZDg4ODg4MzYzZGY5NzNlYzUuYmluZFBvcHVwKHBvcHVwX2M2MjVkOWNhODc5MzQ3OTM5NWFkYTIwYmRlMTdjMzE2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YzBhYzI0MzkyMWM0ODk1ODlhM2FiZmMxOTU0NWQ2OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYyODg0MDgsIC03OS41MjA5OTk0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8wMzkzNjZmMjM0ZGY0ODA2YjhjNzBlNDkzMmI4YjQzOCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMmY5MDZjOTIxOTE4NDlhZDgzNDEwZGMxYjllOWU2ZTUgPSAkKGA8ZGl2IGlkPSJodG1sXzJmOTA2YzkyMTkxODQ5YWQ4MzQxMGRjMWI5ZTllNmU1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5NaW1pY28gTlcsIFRoZSBRdWVlbnN3YXkgV2VzdCwgU291dGggb2YgQmxvb3IsIEtpbmdzd2F5IFBhcmsgU291dGggV2VzdCwgUm95YWwgWW9yayBTb3V0aCBXZXN0LCBFdG9iaWNva2U8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMDM5MzY2ZjIzNGRmNDgwNmI4YzcwZTQ5MzJiOGI0Mzguc2V0Q29udGVudChodG1sXzJmOTA2YzkyMTkxODQ5YWQ4MzQxMGRjMWI5ZTllNmU1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85YzBhYzI0MzkyMWM0ODk1ODlhM2FiZmMxOTU0NWQ2OC5iaW5kUG9wdXAocG9wdXBfMDM5MzY2ZjIzNGRmNDgwNmI4YzcwZTQ5MzJiOGI0MzgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAo8L3NjcmlwdD4= onload=\"this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>" + ], + "text/plain": [ + "<folium.folium.Map at 0x1a0657a4808>" + ] + }, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import folium\n", + "\n", + "# create map of Toronto using latitude and longitude values\n", + "map_Toronto = folium.Map(location=[latitude, longitude], zoom_start=10)\n", + "\n", + "# add markers to map\n", + "for lat, lng, borough, neighborhood in zip(df['Latitude'], df['Longitude'], df['Borough'], df['Neighbourhood']):\n", + " label = '{}, {}'.format(neighborhood, borough)\n", + " label = folium.Popup(label, parse_html=True)\n", + " folium.CircleMarker(\n", + " [lat, lng],\n", + " radius=5,\n", + " popup=label,\n", + " color='blue',\n", + " fill=True,\n", + " fill_color='#3186cc',\n", + " fill_opacity=0.7,\n", + " ).add_to(map_Toronto) \n", + " \n", + "map_Toronto" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define Foursquare parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": {}, + "outputs": [], + "source": [ + "CLIENT_ID = 'MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN'\n", + "CLIENT_SECRET = 'YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ'" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Your credentails:\n", + "CLIENT_ID: MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN\n", + "CLIENT_SECRET:YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ\n" + ] + } + ], + "source": [ + "VERSION = '20180604' # Foursquare API version\n", + "\n", + "print('Your credentails:')\n", + "print('CLIENT_ID: ' + CLIENT_ID)\n", + "print('CLIENT_SECRET:' + CLIENT_SECRET)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Explore the data, and get the venues in 500 meters range from our first entry" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Latitude and longitude values of Parkwoods are 43.7532586, -79.3296565.\n" + ] + } + ], + "source": [ + "neighborhood_latitude = df.loc[0, 'Latitude'] # neighborhood latitude value\n", + "neighborhood_longitude = df.loc[0, 'Longitude'] # neighborhood longitude value\n", + "\n", + "neighborhood_name = df.loc[0, 'Neighbourhood'] # neighborhood name\n", + "\n", + "print('Latitude and longitude values of {} are {}, {}.'.format(neighborhood_name, \n", + " neighborhood_latitude, \n", + " neighborhood_longitude))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create the GET request URL" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://api.foursquare.com/v2/venues/explore?&client_id=MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN&client_secret=YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ&v=20180604&ll=43.7532586,-79.3296565&radius=500&limit=100'" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "LIMIT = 100\n", + "radius = 500\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", + " neighborhood_latitude, \n", + " neighborhood_longitude, \n", + " radius, \n", + " LIMIT)\n", + "url" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'meta': {'code': 200, 'requestId': '5f1dab2fb0d9d01cac2a7fbc'},\n", + " 'response': {'warning': {'text': \"There aren't a lot of results near you. Try something more general, reset your filters, or expand the search area.\"},\n", + " 'headerLocation': 'Parkwoods - Donalda',\n", + " 'headerFullLocation': 'Parkwoods - Donalda, Toronto',\n", + " 'headerLocationGranularity': 'neighborhood',\n", + " 'totalResults': 2,\n", + " 'suggestedBounds': {'ne': {'lat': 43.757758604500005,\n", + " 'lng': -79.32343823984928},\n", + " 'sw': {'lat': 43.7487585955, 'lng': -79.33587476015072}},\n", + " 'groups': [{'type': 'Recommended Places',\n", + " 'name': 'recommended',\n", + " 'items': [{'reasons': {'count': 0,\n", + " 'items': [{'summary': 'This spot is popular',\n", + " 'type': 'general',\n", + " 'reasonName': 'globalInteractionReason'}]},\n", + " 'venue': {'id': '4e8d9dcdd5fbbbb6b3003c7b',\n", + " 'name': 'Brookbanks Park',\n", + " 'location': {'address': 'Toronto',\n", + " 'lat': 43.751976046055574,\n", + " 'lng': -79.33214044722958,\n", + " 'labeledLatLngs': [{'label': 'display',\n", + " 'lat': 43.751976046055574,\n", + " 'lng': -79.33214044722958}],\n", + " 'distance': 245,\n", + " 'cc': 'CA',\n", + " 'city': 'Toronto',\n", + " 'state': 'ON',\n", + " 'country': 'Canada',\n", + " 'formattedAddress': ['Toronto', 'Toronto ON', 'Canada']},\n", + " 'categories': [{'id': '4bf58dd8d48988d163941735',\n", + " 'name': 'Park',\n", + " 'pluralName': 'Parks',\n", + " 'shortName': 'Park',\n", + " 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/parks_outdoors/park_',\n", + " 'suffix': '.png'},\n", + " 'primary': True}],\n", + " 'photos': {'count': 0, 'groups': []}},\n", + " 'referralId': 'e-0-4e8d9dcdd5fbbbb6b3003c7b-0'},\n", + " {'reasons': {'count': 0,\n", + " 'items': [{'summary': 'This spot is popular',\n", + " 'type': 'general',\n", + " 'reasonName': 'globalInteractionReason'}]},\n", + " 'venue': {'id': '4cb11e2075ebb60cd1c4caad',\n", + " 'name': 'Variety Store',\n", + " 'location': {'address': '29 Valley Woods Road',\n", + " 'lat': 43.75197441585782,\n", + " 'lng': -79.33311418516017,\n", + " 'labeledLatLngs': [{'label': 'display',\n", + " 'lat': 43.75197441585782,\n", + " 'lng': -79.33311418516017}],\n", + " 'distance': 312,\n", + " 'cc': 'CA',\n", + " 'city': 'Toronto',\n", + " 'state': 'ON',\n", + " 'country': 'Canada',\n", + " 'formattedAddress': ['29 Valley Woods Road', 'Toronto ON', 'Canada']},\n", + " 'categories': [{'id': '4bf58dd8d48988d1f9941735',\n", + " 'name': 'Food & Drink Shop',\n", + " 'pluralName': 'Food & Drink Shops',\n", + " 'shortName': 'Food & Drink',\n", + " 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/shops/foodanddrink_',\n", + " 'suffix': '.png'},\n", + " 'primary': True}],\n", + " 'photos': {'count': 0, 'groups': []}},\n", + " 'referralId': 'e-0-4cb11e2075ebb60cd1c4caad-1'}]}]}}" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "results = requests.get(url).json()\n", + "results" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [], + "source": [ + "# function that extracts the category of the venue\n", + "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']" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\my_user\\anaconda3\\lib\\site-packages\\ipykernel_launcher.py:6: FutureWarning: pandas.io.json.json_normalize is deprecated, use pandas.json_normalize instead\n", + " \n" + ] + }, + { + "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>name</th>\n", + " <th>categories</th>\n", + " <th>lat</th>\n", + " <th>lng</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>Brookbanks Park</td>\n", + " <td>Park</td>\n", + " <td>43.751976</td>\n", + " <td>-79.332140</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>Variety Store</td>\n", + " <td>Food & Drink Shop</td>\n", + " <td>43.751974</td>\n", + " <td>-79.333114</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " name categories lat lng\n", + "0 Brookbanks Park Park 43.751976 -79.332140\n", + "1 Variety Store Food & Drink Shop 43.751974 -79.333114" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import json\n", + "from pandas.io.json import json_normalize\n", + "\n", + "venues = results['response']['groups'][0]['items']\n", + " \n", + "nearby_venues = json_normalize(venues) # flatten JSON\n", + "\n", + "# filter columns\n", + "filtered_columns = ['venue.name', 'venue.categories', 'venue.location.lat', 'venue.location.lng']\n", + "nearby_venues =nearby_venues.loc[:, filtered_columns]\n", + "\n", + "# filter the category for each row\n", + "nearby_venues['venue.categories'] = nearby_venues.apply(get_category_type, axis=1)\n", + "\n", + "# clean columns\n", + "nearby_venues.columns = [col.split(\".\")[-1] for col in nearby_venues.columns]\n", + "\n", + "nearby_venues.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Generalize to obtain the venues from all neighbourhoods in Toronto" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [], + "source": [ + "def getNearbyVenues(names, latitudes, longitudes, radius=500):\n", + " \n", + " venues_list=[]\n", + " for name, lat, lng in zip(names, latitudes, longitudes):\n", + " print(name)\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 = ['Neighbourhood', \n", + " 'Neighborhood Latitude', \n", + " 'Neighborhood Longitude', \n", + " 'Venue', \n", + " 'Venue Latitude', \n", + " 'Venue Longitude', \n", + " 'Venue Category']\n", + " \n", + " return(nearby_venues)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Parkwoods\n", + "Victoria Village\n", + "Regent Park, Harbourfront\n", + "Lawrence Manor, Lawrence Heights\n", + "Queen's Park, Ontario Provincial Government\n", + "Islington Avenue, Humber Valley Village\n", + "Malvern, Rouge\n", + "Don Mills\n", + "Parkview Hill, Woodbine Gardens\n", + "Garden District, Ryerson\n", + "Glencairn\n", + "West Deane Park, Princess Gardens, Martin Grove, Islington, Cloverdale\n", + "Rouge Hill, Port Union, Highland Creek\n", + "Don Mills\n", + "Woodbine Heights\n", + "St. James Town\n", + "Humewood-Cedarvale\n", + "Eringate, Bloordale Gardens, Old Burnhamthorpe, Markland Wood\n", + "Guildwood, Morningside, West Hill\n", + "The Beaches\n", + "Berczy Park\n", + "Caledonia-Fairbanks\n", + "Woburn\n", + "Leaside\n", + "Central Bay Street\n", + "my_usertie\n", + "Cedarbrae\n", + "Hillcrest Village\n", + "Bathurst Manor, Wilson Heights, Downsview North\n", + "Thorncliffe Park\n", + "Richmond, Adelaide, King\n", + "Dufferin, Dovercourt Village\n", + "Scarborough Village\n", + "Fairview, Henry Farm, Oriole\n", + "Northwood Park, York University\n", + "East Toronto, Broadview North (Old East York)\n", + "Harbourfront East, Union Station, Toronto Islands\n", + "Little Portugal, Trinity\n", + "Kennedy Park, Ionview, East Birchmount Park\n", + "Bayview Village\n", + "Downsview\n", + "The Danforth West, Riverdale\n", + "Toronto Dominion Centre, Design Exchange\n", + "Brockton, Parkdale Village, Exhibition Place\n", + "Golden Mile, Clairlea, Oakridge\n", + "York Mills, Silver Hills\n", + "Downsview\n", + "India Bazaar, The Beaches West\n", + "Commerce Court, Victoria Hotel\n", + "North Park, Maple Leaf Park, Upwood Park\n", + "Humber Summit\n", + "Cliffside, Cliffcrest, Scarborough Village West\n", + "Willowdale, Newtonbrook\n", + "Downsview\n", + "Studio District\n", + "Bedford Park, Lawrence Manor East\n", + "Del Ray, Mount Dennis, Keelsdale and Silverthorn\n", + "Humberlea, Emery\n", + "Birch Cliff, Cliffside West\n", + "Willowdale, Willowdale East\n", + "Downsview\n", + "Lawrence Park\n", + "Roselawn\n", + "Runnymede, The Junction North\n", + "Weston\n", + "Dorset Park, Wexford Heights, Scarborough Town Centre\n", + "York Mills West\n", + "Davisville North\n", + "Forest Hill North & West, Forest Hill Road Park\n", + "High Park, The Junction South\n", + "Westmount\n", + "Wexford, Maryvale\n", + "Willowdale, Willowdale West\n", + "North Toronto West, Lawrence Park\n", + "The Annex, North Midtown, Yorkville\n", + "Parkdale, Roncesvalles\n", + "Canada Post Gateway Processing Centre\n", + "Kingsview Village, St. Phillips, Martin Grove Gardens, Richview Gardens\n", + "Agincourt\n", + "Davisville\n", + "University of Toronto, Harbord\n", + "Runnymede, Swansea\n", + "Clarks Corners, Tam O'Shanter, Sullivan\n", + "Moore Park, Summerhill East\n", + "Kensington Market, Chinatown, Grange Park\n", + "Milliken, Agincourt North, Steeles East, L'Amoreaux East\n", + "Summerhill West, Rathnelly, South Hill, Forest Hill SE, Deer Park\n", + "CN Tower, King and Spadina, Railway Lands, Harbourfront West, Bathurst Quay, South Niagara, Island airport\n", + "New Toronto, Mimico South, Humber Bay Shores\n", + "South Steeles, Silverstone, Humbergate, Jamestown, Mount Olive, Beaumond Heights, Thistletown, Albion Gardens\n", + "Steeles West, L'Amoreaux West\n", + "Rosedale\n", + "Stn A PO Boxes\n", + "Alderwood, Long Branch\n", + "Northwest, West Humber - Clairville\n", + "Upper Rouge\n", + "St. James Town, Cabbagetown\n", + "First Canadian Place, Underground city\n", + "The Kingsway, Montgomery Road, Old Mill North\n", + "Church and Wellesley\n", + "Business reply mail Processing Centre, South Central Letter Processing Plant Toronto\n", + "Old Mill South, King's Mill Park, Sunnylea, Humber Bay, Mimico NE, The Queensway East, Royal York South East, Kingsway Park South East\n", + "Mimico NW, The Queensway West, South of Bloor, Kingsway Park South West, Royal York South West\n" + ] + } + ], + "source": [ + "toronto_venues = getNearbyVenues(names=df['Neighbourhood'],\n", + " latitudes=df['Latitude'],\n", + " longitudes=df['Longitude']\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Checking the size of df" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2153, 7)\n" + ] + }, + { + "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>Neighbourhood</th>\n", + " <th>Neighborhood Latitude</th>\n", + " <th>Neighborhood Longitude</th>\n", + " <th>Venue</th>\n", + " <th>Venue Latitude</th>\n", + " <th>Venue Longitude</th>\n", + " <th>Venue Category</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>Parkwoods</td>\n", + " <td>43.753259</td>\n", + " <td>-79.329656</td>\n", + " <td>Brookbanks Park</td>\n", + " <td>43.751976</td>\n", + " <td>-79.332140</td>\n", + " <td>Park</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>Parkwoods</td>\n", + " <td>43.753259</td>\n", + " <td>-79.329656</td>\n", + " <td>Variety Store</td>\n", + " <td>43.751974</td>\n", + " <td>-79.333114</td>\n", + " <td>Food & Drink Shop</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>Victoria Village</td>\n", + " <td>43.725882</td>\n", + " <td>-79.315572</td>\n", + " <td>Victoria Village Arena</td>\n", + " <td>43.723481</td>\n", + " <td>-79.315635</td>\n", + " <td>Hockey Arena</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>Victoria Village</td>\n", + " <td>43.725882</td>\n", + " <td>-79.315572</td>\n", + " <td>Portugril</td>\n", + " <td>43.725819</td>\n", + " <td>-79.312785</td>\n", + " <td>Portuguese Restaurant</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>Victoria Village</td>\n", + " <td>43.725882</td>\n", + " <td>-79.315572</td>\n", + " <td>Tim Hortons</td>\n", + " <td>43.725517</td>\n", + " <td>-79.313103</td>\n", + " <td>Coffee Shop</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Neighbourhood Neighborhood Latitude Neighborhood Longitude \\\n", + "0 Parkwoods 43.753259 -79.329656 \n", + "1 Parkwoods 43.753259 -79.329656 \n", + "2 Victoria Village 43.725882 -79.315572 \n", + "3 Victoria Village 43.725882 -79.315572 \n", + "4 Victoria Village 43.725882 -79.315572 \n", + "\n", + " Venue Venue Latitude Venue Longitude \\\n", + "0 Brookbanks Park 43.751976 -79.332140 \n", + "1 Variety Store 43.751974 -79.333114 \n", + "2 Victoria Village Arena 43.723481 -79.315635 \n", + "3 Portugril 43.725819 -79.312785 \n", + "4 Tim Hortons 43.725517 -79.313103 \n", + "\n", + " Venue Category \n", + "0 Park \n", + "1 Food & Drink Shop \n", + "2 Hockey Arena \n", + "3 Portuguese Restaurant \n", + "4 Coffee Shop " + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(toronto_venues.shape)\n", + "toronto_venues.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Checking how many venues there are for each venue" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "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>Neighborhood Latitude</th>\n", + " <th>Neighborhood Longitude</th>\n", + " <th>Venue</th>\n", + " <th>Venue Latitude</th>\n", + " <th>Venue Longitude</th>\n", + " <th>Venue Category</th>\n", + " </tr>\n", + " <tr>\n", + " <th>Neighbourhood</th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " <th></th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>Agincourt</th>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " </tr>\n", + " <tr>\n", + " <th>Alderwood, Long Branch</th>\n", + " <td>8</td>\n", + " <td>8</td>\n", + " <td>8</td>\n", + " <td>8</td>\n", + " <td>8</td>\n", + " <td>8</td>\n", + " </tr>\n", + " <tr>\n", + " <th>Bathurst Manor, Wilson Heights, Downsview North</th>\n", + " <td>21</td>\n", + " <td>21</td>\n", + " <td>21</td>\n", + " <td>21</td>\n", + " <td>21</td>\n", + " <td>21</td>\n", + " </tr>\n", + " <tr>\n", + " <th>Bayview Village</th>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " </tr>\n", + " <tr>\n", + " <th>Bedford Park, Lawrence Manor East</th>\n", + " <td>25</td>\n", + " <td>25</td>\n", + " <td>25</td>\n", + " <td>25</td>\n", + " <td>25</td>\n", + " <td>25</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>Willowdale, Willowdale East</th>\n", + " <td>34</td>\n", + " <td>34</td>\n", + " <td>34</td>\n", + " <td>34</td>\n", + " <td>34</td>\n", + " <td>34</td>\n", + " </tr>\n", + " <tr>\n", + " <th>Willowdale, Willowdale West</th>\n", + " <td>6</td>\n", + " <td>6</td>\n", + " <td>6</td>\n", + " <td>6</td>\n", + " <td>6</td>\n", + " <td>6</td>\n", + " </tr>\n", + " <tr>\n", + " <th>Woburn</th>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " <td>4</td>\n", + " </tr>\n", + " <tr>\n", + " <th>Woodbine Heights</th>\n", + " <td>9</td>\n", + " <td>9</td>\n", + " <td>9</td>\n", + " <td>9</td>\n", + " <td>9</td>\n", + " <td>9</td>\n", + " </tr>\n", + " <tr>\n", + " <th>York Mills West</th>\n", + " <td>3</td>\n", + " <td>3</td>\n", + " <td>3</td>\n", + " <td>3</td>\n", + " <td>3</td>\n", + " <td>3</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>96 rows × 6 columns</p>\n", + "</div>" + ], + "text/plain": [ + " Neighborhood Latitude \\\n", + "Neighbourhood \n", + "Agincourt 4 \n", + "Alderwood, Long Branch 8 \n", + "Bathurst Manor, Wilson Heights, Downsview North 21 \n", + "Bayview Village 4 \n", + "Bedford Park, Lawrence Manor East 25 \n", + "... ... \n", + "Willowdale, Willowdale East 34 \n", + "Willowdale, Willowdale West 6 \n", + "Woburn 4 \n", + "Woodbine Heights 9 \n", + "York Mills West 3 \n", + "\n", + " Neighborhood Longitude \\\n", + "Neighbourhood \n", + "Agincourt 4 \n", + "Alderwood, Long Branch 8 \n", + "Bathurst Manor, Wilson Heights, Downsview North 21 \n", + "Bayview Village 4 \n", + "Bedford Park, Lawrence Manor East 25 \n", + "... ... \n", + "Willowdale, Willowdale East 34 \n", + "Willowdale, Willowdale West 6 \n", + "Woburn 4 \n", + "Woodbine Heights 9 \n", + "York Mills West 3 \n", + "\n", + " Venue Venue Latitude \\\n", + "Neighbourhood \n", + "Agincourt 4 4 \n", + "Alderwood, Long Branch 8 8 \n", + "Bathurst Manor, Wilson Heights, Downsview North 21 21 \n", + "Bayview Village 4 4 \n", + "Bedford Park, Lawrence Manor East 25 25 \n", + "... ... ... \n", + "Willowdale, Willowdale East 34 34 \n", + "Willowdale, Willowdale West 6 6 \n", + "Woburn 4 4 \n", + "Woodbine Heights 9 9 \n", + "York Mills West 3 3 \n", + "\n", + " Venue Longitude \\\n", + "Neighbourhood \n", + "Agincourt 4 \n", + "Alderwood, Long Branch 8 \n", + "Bathurst Manor, Wilson Heights, Downsview North 21 \n", + "Bayview Village 4 \n", + "Bedford Park, Lawrence Manor East 25 \n", + "... ... \n", + "Willowdale, Willowdale East 34 \n", + "Willowdale, Willowdale West 6 \n", + "Woburn 4 \n", + "Woodbine Heights 9 \n", + "York Mills West 3 \n", + "\n", + " Venue Category \n", + "Neighbourhood \n", + "Agincourt 4 \n", + "Alderwood, Long Branch 8 \n", + "Bathurst Manor, Wilson Heights, Downsview North 21 \n", + "Bayview Village 4 \n", + "Bedford Park, Lawrence Manor East 25 \n", + "... ... \n", + "Willowdale, Willowdale East 34 \n", + "Willowdale, Willowdale West 6 \n", + "Woburn 4 \n", + "Woodbine Heights 9 \n", + "York Mills West 3 \n", + "\n", + "[96 rows x 6 columns]" + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_venues.groupby('Neighbourhood').count()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How many categorys can we find?" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "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>Neighbourhood</th>\n", + " <th>Accessories Store</th>\n", + " <th>Afghan Restaurant</th>\n", + " <th>Airport</th>\n", + " <th>Airport Food Court</th>\n", + " <th>Airport Lounge</th>\n", + " <th>Airport Service</th>\n", + " <th>Airport Terminal</th>\n", + " <th>American Restaurant</th>\n", + " <th>Antique Shop</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>Parkwoods</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>Parkwoods</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>Victoria Village</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>Victoria Village</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>Victoria Village</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 × 270 columns</p>\n", + "</div>" + ], + "text/plain": [ + " Neighbourhood Accessories Store Afghan Restaurant Airport \\\n", + "0 Parkwoods 0 0 0 \n", + "1 Parkwoods 0 0 0 \n", + "2 Victoria Village 0 0 0 \n", + "3 Victoria Village 0 0 0 \n", + "4 Victoria Village 0 0 0 \n", + "\n", + " Airport Food Court Airport Lounge Airport Service Airport Terminal \\\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", + " American Restaurant Antique Shop ... Vegetarian / Vegan Restaurant \\\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 Game Store Video Store Vietnamese Restaurant Warehouse 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", + " Wine Bar Wine Shop Wings Joint Women's Store Yoga Studio \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", + "[5 rows x 270 columns]" + ] + }, + "execution_count": 103, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# one hot encoding\n", + "toronto_onehot = pd.get_dummies(toronto_venues[['Venue Category']], prefix=\"\", prefix_sep=\"\")\n", + "\n", + "# add neighborhood column back to dataframe\n", + "toronto_onehot['Neighbourhood'] = toronto_venues['Neighbourhood'] \n", + "\n", + "# move neighborhood column to the first column\n", + "fixed_columns = [toronto_onehot.columns[-1]] + list(toronto_onehot.columns[:-1])\n", + "toronto_onehot = toronto_onehot[fixed_columns]\n", + "\n", + "toronto_onehot.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2153, 270)" + ] + }, + "execution_count": 104, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_onehot.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "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>Neighbourhood</th>\n", + " <th>Accessories Store</th>\n", + " <th>Afghan Restaurant</th>\n", + " <th>Airport</th>\n", + " <th>Airport Food Court</th>\n", + " <th>Airport Lounge</th>\n", + " <th>Airport Service</th>\n", + " <th>Airport Terminal</th>\n", + " <th>American Restaurant</th>\n", + " <th>Antique Shop</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>Agincourt</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.00</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.00</td>\n", + " <td>0.0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>Alderwood, Long Branch</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.00</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.00</td>\n", + " <td>0.0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>Bathurst Manor, Wilson Heights, Downsview North</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.00</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.00</td>\n", + " <td>0.0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>Bayview Village</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.00</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.00</td>\n", + " <td>0.0</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>Bedford Park, Lawrence Manor East</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.04</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.04</td>\n", + " <td>0.0</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>5 rows × 270 columns</p>\n", + "</div>" + ], + "text/plain": [ + " Neighbourhood Accessories Store \\\n", + "0 Agincourt 0.0 \n", + "1 Alderwood, Long Branch 0.0 \n", + "2 Bathurst Manor, Wilson Heights, Downsview North 0.0 \n", + "3 Bayview Village 0.0 \n", + "4 Bedford Park, Lawrence Manor East 0.0 \n", + "\n", + " Afghan Restaurant Airport Airport Food Court Airport Lounge \\\n", + "0 0.0 0.0 0.0 0.0 \n", + "1 0.0 0.0 0.0 0.0 \n", + "2 0.0 0.0 0.0 0.0 \n", + "3 0.0 0.0 0.0 0.0 \n", + "4 0.0 0.0 0.0 0.0 \n", + "\n", + " Airport Service Airport Terminal American Restaurant Antique Shop ... \\\n", + "0 0.0 0.0 0.00 0.0 ... \n", + "1 0.0 0.0 0.00 0.0 ... \n", + "2 0.0 0.0 0.00 0.0 ... \n", + "3 0.0 0.0 0.00 0.0 ... \n", + "4 0.0 0.0 0.04 0.0 ... \n", + "\n", + " Vegetarian / Vegan Restaurant Video Game Store Video Store \\\n", + "0 0.0 0.0 0.0 \n", + "1 0.0 0.0 0.0 \n", + "2 0.0 0.0 0.0 \n", + "3 0.0 0.0 0.0 \n", + "4 0.0 0.0 0.0 \n", + "\n", + " Vietnamese Restaurant Warehouse Store Wine Bar Wine Shop Wings Joint \\\n", + "0 0.0 0.0 0.0 0.0 0.0 \n", + "1 0.0 0.0 0.0 0.0 0.0 \n", + "2 0.0 0.0 0.0 0.0 0.0 \n", + "3 0.0 0.0 0.0 0.0 0.0 \n", + "4 0.0 0.0 0.0 0.0 0.0 \n", + "\n", + " Women's Store Yoga Studio \n", + "0 0.00 0.0 \n", + "1 0.00 0.0 \n", + "2 0.00 0.0 \n", + "3 0.00 0.0 \n", + "4 0.04 0.0 \n", + "\n", + "[5 rows x 270 columns]" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_grouped = toronto_onehot.groupby('Neighbourhood').mean().reset_index()\n", + "toronto_grouped.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(96, 270)" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_grouped.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Getting the top 10 for each neighbourhood" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [], + "source": [ + "def return_most_common_venues(row, num_top_venues):\n", + " row_categories = row.iloc[1:]\n", + " row_categories_sorted = row_categories.sort_values(ascending=False)\n", + " \n", + " return row_categories_sorted.index.values[0:num_top_venues]" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "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>Neighbourhood</th>\n", + " <th>1st Most Common Venue</th>\n", + " <th>2nd Most Common Venue</th>\n", + " <th>3rd Most Common Venue</th>\n", + " <th>4th Most Common Venue</th>\n", + " <th>5th Most Common Venue</th>\n", + " <th>6th Most Common Venue</th>\n", + " <th>7th Most Common Venue</th>\n", + " <th>8th Most Common Venue</th>\n", + " <th>9th Most Common Venue</th>\n", + " <th>10th Most Common Venue</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>Agincourt</td>\n", + " <td>Lounge</td>\n", + " <td>Latin American Restaurant</td>\n", + " <td>Skating Rink</td>\n", + " <td>Breakfast Spot</td>\n", + " <td>Donut Shop</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>Alderwood, Long Branch</td>\n", + " <td>Pizza Place</td>\n", + " <td>Pharmacy</td>\n", + " <td>Sandwich Place</td>\n", + " <td>Dance Studio</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Pub</td>\n", + " <td>Gym</td>\n", + " <td>Airport Terminal</td>\n", + " <td>Falafel Restaurant</td>\n", + " <td>Event Space</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>Bathurst Manor, Wilson Heights, Downsview North</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Bank</td>\n", + " <td>Frozen Yogurt Shop</td>\n", + " <td>Bridal Shop</td>\n", + " <td>Sandwich Place</td>\n", + " <td>Diner</td>\n", + " <td>Restaurant</td>\n", + " <td>Deli / Bodega</td>\n", + " <td>Middle Eastern Restaurant</td>\n", + " <td>Supermarket</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>Bayview Village</td>\n", + " <td>Café</td>\n", + " <td>Bank</td>\n", + " <td>Chinese Restaurant</td>\n", + " <td>Japanese Restaurant</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>Bedford Park, Lawrence Manor East</td>\n", + " <td>Sandwich Place</td>\n", + " <td>Restaurant</td>\n", + " <td>Italian Restaurant</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Liquor Store</td>\n", + " <td>Thai Restaurant</td>\n", + " <td>Café</td>\n", + " <td>Pub</td>\n", + " <td>Butcher</td>\n", + " <td>Sushi Restaurant</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Neighbourhood 1st Most Common Venue \\\n", + "0 Agincourt Lounge \n", + "1 Alderwood, Long Branch Pizza Place \n", + "2 Bathurst Manor, Wilson Heights, Downsview North Coffee Shop \n", + "3 Bayview Village Café \n", + "4 Bedford Park, Lawrence Manor East Sandwich Place \n", + "\n", + " 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n", + "0 Latin American Restaurant Skating Rink Breakfast Spot \n", + "1 Pharmacy Sandwich Place Dance Studio \n", + "2 Bank Frozen Yogurt Shop Bridal Shop \n", + "3 Bank Chinese Restaurant Japanese Restaurant \n", + "4 Restaurant Italian Restaurant Coffee Shop \n", + "\n", + " 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n", + "0 Donut Shop Diner Discount Store \n", + "1 Coffee Shop Pub Gym \n", + "2 Sandwich Place Diner Restaurant \n", + "3 Yoga Studio Diner Discount Store \n", + "4 Liquor Store Thai Restaurant Café \n", + "\n", + " 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n", + "0 Distribution Center Dog Run Doner Restaurant \n", + "1 Airport Terminal Falafel Restaurant Event Space \n", + "2 Deli / Bodega Middle Eastern Restaurant Supermarket \n", + "3 Distribution Center Dog Run Doner Restaurant \n", + "4 Pub Butcher Sushi Restaurant " + ] + }, + "execution_count": 108, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "num_top_venues = 10\n", + "\n", + "indicators = ['st', 'nd', 'rd']\n", + "\n", + "# create columns according to number of top venues\n", + "columns = ['Neighbourhood']\n", + "for ind in np.arange(num_top_venues):\n", + " try:\n", + " columns.append('{}{} Most Common Venue'.format(ind+1, indicators[ind]))\n", + " except:\n", + " columns.append('{}th Most Common Venue'.format(ind+1))\n", + "\n", + "# create a new dataframe\n", + "neighborhoods_venues_sorted = pd.DataFrame(columns=columns)\n", + "neighborhoods_venues_sorted['Neighbourhood'] = toronto_grouped['Neighbourhood']\n", + "\n", + "for ind in np.arange(toronto_grouped.shape[0]):\n", + " neighborhoods_venues_sorted.iloc[ind, 1:] = return_most_common_venues(toronto_grouped.iloc[ind, :], num_top_venues)\n", + "\n", + "neighborhoods_venues_sorted.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Clustering Neighborhoods" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])" + ] + }, + "execution_count": 109, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# import k-means from clustering stage\n", + "from sklearn.cluster import KMeans\n", + "\n", + "# set number of clusters\n", + "kclusters = 5\n", + "\n", + "toronto_grouped_clustering = toronto_grouped.drop('Neighbourhood', 1)\n", + "\n", + "# run k-means clustering\n", + "kmeans = KMeans(n_clusters=kclusters, random_state=0).fit(toronto_grouped_clustering)\n", + "\n", + "# check cluster labels generated for each row in the dataframe\n", + "kmeans.labels_[0:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Merge the dataframe with the top 10 and the cluster for each neighbourhood" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "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>Postal Code</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>M3A</td>\n", + " <td>North York</td>\n", + " <td>Parkwoods</td>\n", + " <td>43.753259</td>\n", + " <td>-79.329656</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>M4A</td>\n", + " <td>North York</td>\n", + " <td>Victoria Village</td>\n", + " <td>43.725882</td>\n", + " <td>-79.315572</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>M5A</td>\n", + " <td>Downtown Toronto</td>\n", + " <td>Regent Park, Harbourfront</td>\n", + " <td>43.654260</td>\n", + " <td>-79.360636</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>M6A</td>\n", + " <td>North York</td>\n", + " <td>Lawrence Manor, Lawrence Heights</td>\n", + " <td>43.718518</td>\n", + " <td>-79.464763</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>M7A</td>\n", + " <td>Downtown Toronto</td>\n", + " <td>Queen's Park, Ontario Provincial Government</td>\n", + " <td>43.662301</td>\n", + " <td>-79.389494</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>98</th>\n", + " <td>M8X</td>\n", + " <td>Etobicoke</td>\n", + " <td>The Kingsway, Montgomery Road, Old Mill North</td>\n", + " <td>43.653654</td>\n", + " <td>-79.506944</td>\n", + " </tr>\n", + " <tr>\n", + " <th>99</th>\n", + " <td>M4Y</td>\n", + " <td>Downtown Toronto</td>\n", + " <td>Church and Wellesley</td>\n", + " <td>43.665860</td>\n", + " <td>-79.383160</td>\n", + " </tr>\n", + " <tr>\n", + " <th>100</th>\n", + " <td>M7Y</td>\n", + " <td>East Toronto</td>\n", + " <td>Business reply mail Processing Centre, South C...</td>\n", + " <td>43.662744</td>\n", + " <td>-79.321558</td>\n", + " </tr>\n", + " <tr>\n", + " <th>101</th>\n", + " <td>M8Y</td>\n", + " <td>Etobicoke</td>\n", + " <td>Old Mill South, King's Mill Park, Sunnylea, Hu...</td>\n", + " <td>43.636258</td>\n", + " <td>-79.498509</td>\n", + " </tr>\n", + " <tr>\n", + " <th>102</th>\n", + " <td>M8Z</td>\n", + " <td>Etobicoke</td>\n", + " <td>Mimico NW, The Queensway West, South of Bloor,...</td>\n", + " <td>43.628841</td>\n", + " <td>-79.520999</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>103 rows × 5 columns</p>\n", + "</div>" + ], + "text/plain": [ + " Postal Code Borough \\\n", + "0 M3A North York \n", + "1 M4A North York \n", + "2 M5A Downtown Toronto \n", + "3 M6A North York \n", + "4 M7A Downtown Toronto \n", + ".. ... ... \n", + "98 M8X Etobicoke \n", + "99 M4Y Downtown Toronto \n", + "100 M7Y East Toronto \n", + "101 M8Y Etobicoke \n", + "102 M8Z Etobicoke \n", + "\n", + " Neighbourhood Latitude Longitude \n", + "0 Parkwoods 43.753259 -79.329656 \n", + "1 Victoria Village 43.725882 -79.315572 \n", + "2 Regent Park, Harbourfront 43.654260 -79.360636 \n", + "3 Lawrence Manor, Lawrence Heights 43.718518 -79.464763 \n", + "4 Queen's Park, Ontario Provincial Government 43.662301 -79.389494 \n", + ".. ... ... ... \n", + "98 The Kingsway, Montgomery Road, Old Mill North 43.653654 -79.506944 \n", + "99 Church and Wellesley 43.665860 -79.383160 \n", + "100 Business reply mail Processing Centre, South C... 43.662744 -79.321558 \n", + "101 Old Mill South, King's Mill Park, Sunnylea, Hu... 43.636258 -79.498509 \n", + "102 Mimico NW, The Queensway West, South of Bloor,... 43.628841 -79.520999 \n", + "\n", + "[103 rows x 5 columns]" + ] + }, + "execution_count": 121, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "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>Postal Code</th>\n", + " <th>Borough</th>\n", + " <th>Neighbourhood</th>\n", + " <th>Latitude</th>\n", + " <th>Longitude</th>\n", + " <th>Cluster Labels</th>\n", + " <th>1st Most Common Venue</th>\n", + " <th>2nd Most Common Venue</th>\n", + " <th>3rd Most Common Venue</th>\n", + " <th>4th Most Common Venue</th>\n", + " <th>5th Most Common Venue</th>\n", + " <th>6th Most Common Venue</th>\n", + " <th>7th Most Common Venue</th>\n", + " <th>8th Most Common Venue</th>\n", + " <th>9th Most Common Venue</th>\n", + " <th>10th Most Common Venue</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>5</th>\n", + " <td>M9A</td>\n", + " <td>Etobicoke</td>\n", + " <td>Islington Avenue, Humber Valley Village</td>\n", + " <td>43.667856</td>\n", + " <td>-79.532242</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " </tr>\n", + " <tr>\n", + " <th>45</th>\n", + " <td>M2L</td>\n", + " <td>North York</td>\n", + " <td>York Mills, Silver Hills</td>\n", + " <td>43.757490</td>\n", + " <td>-79.374714</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " </tr>\n", + " <tr>\n", + " <th>95</th>\n", + " <td>M1X</td>\n", + " <td>Scarborough</td>\n", + " <td>Upper Rouge</td>\n", + " <td>43.836125</td>\n", + " <td>-79.205636</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " <td>NaN</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Postal Code Borough Neighbourhood \\\n", + "5 M9A Etobicoke Islington Avenue, Humber Valley Village \n", + "45 M2L North York York Mills, Silver Hills \n", + "95 M1X Scarborough Upper Rouge \n", + "\n", + " Latitude Longitude Cluster Labels 1st Most Common Venue \\\n", + "5 43.667856 -79.532242 NaN NaN \n", + "45 43.757490 -79.374714 NaN NaN \n", + "95 43.836125 -79.205636 NaN NaN \n", + "\n", + " 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n", + "5 NaN NaN NaN \n", + "45 NaN NaN NaN \n", + "95 NaN NaN NaN \n", + "\n", + " 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n", + "5 NaN NaN NaN \n", + "45 NaN NaN NaN \n", + "95 NaN NaN NaN \n", + "\n", + " 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n", + "5 NaN NaN NaN \n", + "45 NaN NaN NaN \n", + "95 NaN NaN NaN " + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_merged[toronto_merged['Cluster Labels'].isnull()]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot the clusters in the map" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgCiAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICAgTF9OT19UT1VDSCA9IGZhbHNlOwogICAgICAgICAgICBMX0RJU0FCTEVfM0QgPSBmYWxzZTsKICAgICAgICA8L3NjcmlwdD4KICAgIAogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY29kZS5qcXVlcnkuY29tL2pxdWVyeS0xLjEyLjQubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9qcy9ib290c3RyYXAubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5qcyI+PC9zY3JpcHQ+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vYm9vdHN0cmFwLzMuMi4wL2Nzcy9ib290c3RyYXAubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLXRoZW1lLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9mb250LWF3ZXNvbWUvNC42LjMvY3NzL2ZvbnQtYXdlc29tZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL0xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLzIuMC4yL2xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3Jhd2Nkbi5naXRoYWNrLmNvbS9weXRob24tdmlzdWFsaXphdGlvbi9mb2xpdW0vbWFzdGVyL2ZvbGl1bS90ZW1wbGF0ZXMvbGVhZmxldC5hd2Vzb21lLnJvdGF0ZS5jc3MiLz4KICAgIDxzdHlsZT5odG1sLCBib2R5IHt3aWR0aDogMTAwJTtoZWlnaHQ6IDEwMCU7bWFyZ2luOiAwO3BhZGRpbmc6IDA7fTwvc3R5bGU+CiAgICA8c3R5bGU+I21hcCB7cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7Ym90dG9tOjA7cmlnaHQ6MDtsZWZ0OjA7fTwvc3R5bGU+CiAgICAKICAgICAgICAgICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwKICAgICAgICAgICAgICAgIGluaXRpYWwtc2NhbGU9MS4wLCBtYXhpbXVtLXNjYWxlPTEuMCwgdXNlci1zY2FsYWJsZT1ubyIgLz4KICAgICAgICAgICAgPHN0eWxlPgogICAgICAgICAgICAgICAgI21hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSB7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlOwogICAgICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAuMCU7CiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICAgICAgbGVmdDogMC4wJTsKICAgICAgICAgICAgICAgICAgICB0b3A6IDAuMCU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIDwvc3R5bGU+CiAgICAgICAgCjwvaGVhZD4KPGJvZHk+ICAgIAogICAgCiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImZvbGl1bS1tYXAiIGlkPSJtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUiID48L2Rpdj4KICAgICAgICAKPC9ib2R5Pgo8c2NyaXB0PiAgICAKICAgIAogICAgICAgICAgICB2YXIgbWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1ID0gTC5tYXAoCiAgICAgICAgICAgICAgICAibWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1IiwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjZW50ZXI6IFs0My42NTM0ODE3LCAtNzkuMzgzOTM0N10sCiAgICAgICAgICAgICAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICAgICAgICAgICAgICB6b29tOiAxMSwKICAgICAgICAgICAgICAgICAgICB6b29tQ29udHJvbDogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBwcmVmZXJDYW52YXM6IGZhbHNlLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApOwoKICAgICAgICAgICAgCgogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyX2I0NTFjODgyYmM3YzQ5YWI5ZmJhOTdhMmFkMzE5OGJhID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAiaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmciLAogICAgICAgICAgICAgICAgeyJhdHRyaWJ1dGlvbiI6ICJEYXRhIGJ5IFx1MDAyNmNvcHk7IFx1MDAzY2EgaHJlZj1cImh0dHA6Ly9vcGVuc3RyZWV0bWFwLm9yZ1wiXHUwMDNlT3BlblN0cmVldE1hcFx1MDAzYy9hXHUwMDNlLCB1bmRlciBcdTAwM2NhIGhyZWY9XCJodHRwOi8vd3d3Lm9wZW5zdHJlZXRtYXAub3JnL2NvcHlyaWdodFwiXHUwMDNlT0RiTFx1MDAzYy9hXHUwMDNlLiIsICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwgIm1heE5hdGl2ZVpvb20iOiAxOCwgIm1heFpvb20iOiAxOCwgIm1pblpvb20iOiAwLCAibm9XcmFwIjogZmFsc2UsICJvcGFjaXR5IjogMSwgInN1YmRvbWFpbnMiOiAiYWJjIiwgInRtcyI6IGZhbHNlfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTEyOTY4MDgzYzc2NDZhYWJmZWJjNTRlNzhmNjc1YTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTMyNTg2LCAtNzkuMzI5NjU2NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiI2ZmMDAwMCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82YzRhMTk2ZGFhZjk0NTgzOWUxZDVkZTI1MjNmNmNmYyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNmE4MDNhOWE0YzI4NDZlYmFmYzg4MjQ0MmFlNTQyZmQgPSAkKGA8ZGl2IGlkPSJodG1sXzZhODAzYTlhNGMyODQ2ZWJhZmM4ODI0NDJhZTU0MmZkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrd29vZHMgQ2x1c3RlciAwLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNmM0YTE5NmRhYWY5NDU4MzllMWQ1ZGUyNTIzZjZjZmMuc2V0Q29udGVudChodG1sXzZhODAzYTlhNGMyODQ2ZWJhZmM4ODI0NDJhZTU0MmZkKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81MTI5NjgwODNjNzY0NmFhYmZlYmM1NGU3OGY2NzVhNS5iaW5kUG9wdXAocG9wdXBfNmM0YTE5NmRhYWY5NDU4MzllMWQ1ZGUyNTIzZjZjZmMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2UzNGMyNjFjNjM5ZTQ4NjBiYjQ2Mzg3MTRmZmFmOGMyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI1ODgyMjk5OTk5OTk1LCAtNzkuMzE1NTcxNTk5OTk5OThdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZWM0OWQ4YTMxOWQ1NDg3NGE5MTcxZTI1MjUwMjc3NWIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzY5Y2ViY2JkY2FhYTQyNTFiNzg3ZjMxMzc5NzhmZjdlID0gJChgPGRpdiBpZD0iaHRtbF82OWNlYmNiZGNhYWE0MjUxYjc4N2YzMTM3OTc4ZmY3ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VmljdG9yaWEgVmlsbGFnZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9lYzQ5ZDhhMzE5ZDU0ODc0YTkxNzFlMjUyNTAyNzc1Yi5zZXRDb250ZW50KGh0bWxfNjljZWJjYmRjYWFhNDI1MWI3ODdmMzEzNzk3OGZmN2UpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2UzNGMyNjFjNjM5ZTQ4NjBiYjQ2Mzg3MTRmZmFmOGMyLmJpbmRQb3B1cChwb3B1cF9lYzQ5ZDhhMzE5ZDU0ODc0YTkxNzFlMjUyNTAyNzc1YikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMzU0ZmZkNGZhMzQ4NDBhMDlmODM3N2E0NzEzYjU4YjEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTQyNTk5LCAtNzkuMzYwNjM1OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zMDVkOTM1ZjE2YzI0MjI3YmE0MmFhNDdmN2Y1ZWU4YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMzU5MWE2ZjBlOWU3NGU5MDgyODBiYTIwYWQ0YTNiOGQgPSAkKGA8ZGl2IGlkPSJodG1sXzM1OTFhNmYwZTllNzRlOTA4MjgwYmEyMGFkNGEzYjhkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SZWdlbnQgUGFyaywgSGFyYm91cmZyb250IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzMwNWQ5MzVmMTZjMjQyMjdiYTQyYWE0N2Y3ZjVlZThiLnNldENvbnRlbnQoaHRtbF8zNTkxYTZmMGU5ZTc0ZTkwODI4MGJhMjBhZDRhM2I4ZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMzU0ZmZkNGZhMzQ4NDBhMDlmODM3N2E0NzEzYjU4YjEuYmluZFBvcHVwKHBvcHVwXzMwNWQ5MzVmMTZjMjQyMjdiYTQyYWE0N2Y3ZjVlZThiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zMjU2MmMyOGI4NTc0OTdhOGNlYjViNTEwYzZmOTZkNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxODUxNzk5OTk5OTk5NiwgLTc5LjQ2NDc2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzhkNDRjNTA2NWEyMzRkMDJhMGIyZWNiNjMxMDI2NWI4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9iMWEwMzZkYWE1YjY0ZDQwYWI0NWFmZmY3ZTVlOTZmYiA9ICQoYDxkaXYgaWQ9Imh0bWxfYjFhMDM2ZGFhNWI2NGQ0MGFiNDVhZmZmN2U1ZTk2ZmIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxhd3JlbmNlIE1hbm9yLCBMYXdyZW5jZSBIZWlnaHRzIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzhkNDRjNTA2NWEyMzRkMDJhMGIyZWNiNjMxMDI2NWI4LnNldENvbnRlbnQoaHRtbF9iMWEwMzZkYWE1YjY0ZDQwYWI0NWFmZmY3ZTVlOTZmYik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMzI1NjJjMjhiODU3NDk3YThjZWI1YjUxMGM2Zjk2ZDYuYmluZFBvcHVwKHBvcHVwXzhkNDRjNTA2NWEyMzRkMDJhMGIyZWNiNjMxMDI2NWI4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hNjUzNTNjMGEzYWY0NGUwYTNmZThhYjU0M2U4ZDBiMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MjMwMTUsIC03OS4zODk0OTM4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzg5MjRiM2I5MDI4YzQzMTFhMzdlYjVhYzk0ZjljMjc4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82MjlhMTM4MDQyZTI0MzgyODAyYzBhY2ZhOGZhZGY2OSA9ICQoYDxkaXYgaWQ9Imh0bWxfNjI5YTEzODA0MmUyNDM4MjgwMmMwYWNmYThmYWRmNjkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlF1ZWVuJiMzOTtzIFBhcmssIE9udGFyaW8gUHJvdmluY2lhbCBHb3Zlcm5tZW50IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzg5MjRiM2I5MDI4YzQzMTFhMzdlYjVhYzk0ZjljMjc4LnNldENvbnRlbnQoaHRtbF82MjlhMTM4MDQyZTI0MzgyODAyYzBhY2ZhOGZhZGY2OSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTY1MzUzYzBhM2FmNDRlMGEzZmU4YWI1NDNlOGQwYjMuYmluZFBvcHVwKHBvcHVwXzg5MjRiM2I5MDI4YzQzMTFhMzdlYjVhYzk0ZjljMjc4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84ZjE3NTE5MzYyMzU0M2ZmOTdlNzI2NThkZjNhYTM3NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwNjY4NjI5OTk5OTk5NiwgLTc5LjE5NDM1MzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2MxMDI1YWViNTdkYjQ0NGJiMDg2MzJlNDg4YmQwNGU3ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9kYzc3N2E1Mjg1YWM0ZjRjODg1NzFjYTM3YzA2NThiMSA9ICQoYDxkaXYgaWQ9Imh0bWxfZGM3NzdhNTI4NWFjNGY0Yzg4NTcxY2EzN2MwNjU4YjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1hbHZlcm4sIFJvdWdlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2MxMDI1YWViNTdkYjQ0NGJiMDg2MzJlNDg4YmQwNGU3LnNldENvbnRlbnQoaHRtbF9kYzc3N2E1Mjg1YWM0ZjRjODg1NzFjYTM3YzA2NThiMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOGYxNzUxOTM2MjM1NDNmZjk3ZTcyNjU4ZGYzYWEzNzYuYmluZFBvcHVwKHBvcHVwX2MxMDI1YWViNTdkYjQ0NGJiMDg2MzJlNDg4YmQwNGU3KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lNmM0ZDYxZDhjNDU0M2NiYjYyMDlkZGQwZWEwNWFiNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc0NTkwNTc5OTk5OTk5NiwgLTc5LjM1MjE4OF0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80MWFlMjI0ZmJkYzA0YjgxOGU5YTBhZWVmN2JmNmQyZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZjNhZDNjMTQ3YTQwNDlkYTg0M2QzY2UwZTkyMmI0NzggPSAkKGA8ZGl2IGlkPSJodG1sX2YzYWQzYzE0N2E0MDQ5ZGE4NDNkM2NlMGU5MjJiNDc4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb24gTWlsbHMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDFhZTIyNGZiZGMwNGI4MThlOWEwYWVlZjdiZjZkMmQuc2V0Q29udGVudChodG1sX2YzYWQzYzE0N2E0MDQ5ZGE4NDNkM2NlMGU5MjJiNDc4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9lNmM0ZDYxZDhjNDU0M2NiYjYyMDlkZGQwZWEwNWFiNy5iaW5kUG9wdXAocG9wdXBfNDFhZTIyNGZiZGMwNGI4MThlOWEwYWVlZjdiZjZkMmQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q1OTRlNTA1ZmU2YTQ3YTY4MTU4ZWJhMjYyNGY5MmZkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA2Mzk3MiwgLTc5LjMwOTkzN10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iYTRhNTYwOTc3Yjc0YmY5OWEyZDNlMTRjOTQ0MjFjYyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYmZmNWY5ZDUwYjYyNGVjNjlhZmNlNTIwNDdiMzFjNjUgPSAkKGA8ZGl2IGlkPSJodG1sX2JmZjVmOWQ1MGI2MjRlYzY5YWZjZTUyMDQ3YjMxYzY1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrdmlldyBIaWxsLCBXb29kYmluZSBHYXJkZW5zIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2JhNGE1NjA5NzdiNzRiZjk5YTJkM2UxNGM5NDQyMWNjLnNldENvbnRlbnQoaHRtbF9iZmY1ZjlkNTBiNjI0ZWM2OWFmY2U1MjA0N2IzMWM2NSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDU5NGU1MDVmZTZhNDdhNjgxNThlYmEyNjI0ZjkyZmQuYmluZFBvcHVwKHBvcHVwX2JhNGE1NjA5NzdiNzRiZjk5YTJkM2UxNGM5NDQyMWNjKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80OTU0ZWJkNmFhNTI0ZTI3YjQxZDY2Mzk0YjJhYTIxOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1NzE2MTgsIC03OS4zNzg5MzcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85ZTIzZjZmNGU2YmU0OTY1OGMzNjBkZTAwNTAzNDcxOSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDliNjliYzdkMzZhNGEyMzhiMTFjYzE1NmY2YTIwY2EgPSAkKGA8ZGl2IGlkPSJodG1sXzQ5YjY5YmM3ZDM2YTRhMjM4YjExY2MxNTZmNmEyMGNhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HYXJkZW4gRGlzdHJpY3QsIFJ5ZXJzb24gQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOWUyM2Y2ZjRlNmJlNDk2NThjMzYwZGUwMDUwMzQ3MTkuc2V0Q29udGVudChodG1sXzQ5YjY5YmM3ZDM2YTRhMjM4YjExY2MxNTZmNmEyMGNhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl80OTU0ZWJkNmFhNTI0ZTI3YjQxZDY2Mzk0YjJhYTIxOC5iaW5kUG9wdXAocG9wdXBfOWUyM2Y2ZjRlNmJlNDk2NThjMzYwZGUwMDUwMzQ3MTkpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA4OTNhZTQzODUwMTQ1ZmQ4MjE3Zjk1YzQ0MzIzYWJkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA5NTc3LCAtNzkuNDQ1MDcyNTk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNjRjMDI5OTRhZmY5NDU0MmE0NmY0NzFkMmFlMDRhYWYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzA0OGZkNjVlZDEzMzRkOThhY2FkOTU5ODI0ODUyMTUzID0gJChgPGRpdiBpZD0iaHRtbF8wNDhmZDY1ZWQxMzM0ZDk4YWNhZDk1OTgyNDg1MjE1MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R2xlbmNhaXJuIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzY0YzAyOTk0YWZmOTQ1NDJhNDZmNDcxZDJhZTA0YWFmLnNldENvbnRlbnQoaHRtbF8wNDhmZDY1ZWQxMzM0ZDk4YWNhZDk1OTgyNDg1MjE1Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMDg5M2FlNDM4NTAxNDVmZDgyMTdmOTVjNDQzMjNhYmQuYmluZFBvcHVwKHBvcHVwXzY0YzAyOTk0YWZmOTQ1NDJhNDZmNDcxZDJhZTA0YWFmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80NmQ3MDZmN2ZlODg0OGFmYWE1MmY1OGUyNzJhYTc4MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MDk0MzIsIC03OS41NTQ3MjQ0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiI2ZmYjM2MCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjZmZiMzYwIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82YWRlNWY2YmEwZTk0NzZkODE3ODhiYjNmMzVhOGExMCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjcyNjZhOTc2NTk2NDhmMjhmMzM5NzNkZmQ0YTEyY2UgPSAkKGA8ZGl2IGlkPSJodG1sX2I3MjY2YTk3NjU5NjQ4ZjI4ZjMzOTczZGZkNGExMmNlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XZXN0IERlYW5lIFBhcmssIFByaW5jZXNzIEdhcmRlbnMsIE1hcnRpbiBHcm92ZSwgSXNsaW5ndG9uLCBDbG92ZXJkYWxlIENsdXN0ZXIgNC4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzZhZGU1ZjZiYTBlOTQ3NmQ4MTc4OGJiM2YzNWE4YTEwLnNldENvbnRlbnQoaHRtbF9iNzI2NmE5NzY1OTY0OGYyOGYzMzk3M2RmZDRhMTJjZSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNDZkNzA2ZjdmZTg4NDhhZmFhNTJmNThlMjcyYWE3ODEuYmluZFBvcHVwKHBvcHVwXzZhZGU1ZjZiYTBlOTQ3NmQ4MTc4OGJiM2YzNWE4YTEwKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82NjA5ZTQxMTQ1YmU0NDQ3ODNkYTNlYjUzNGZlZDAyNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4NDUzNTEsIC03OS4xNjA0OTcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83ZDhjMmUzYjI2M2Q0NmE3ODI2OWE1ZmY5NjZkMzJlNSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMWJiODAyYWMxMjYyNGM3OWJmMmViYmVkNGJiNDM3ODMgPSAkKGA8ZGl2IGlkPSJodG1sXzFiYjgwMmFjMTI2MjRjNzliZjJlYmJlZDRiYjQzNzgzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3VnZSBIaWxsLCBQb3J0IFVuaW9uLCBIaWdobGFuZCBDcmVlayBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83ZDhjMmUzYjI2M2Q0NmE3ODI2OWE1ZmY5NjZkMzJlNS5zZXRDb250ZW50KGh0bWxfMWJiODAyYWMxMjYyNGM3OWJmMmViYmVkNGJiNDM3ODMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzY2MDllNDExNDViZTQ0NDc4M2RhM2ViNTM0ZmVkMDI1LmJpbmRQb3B1cChwb3B1cF83ZDhjMmUzYjI2M2Q0NmE3ODI2OWE1ZmY5NjZkMzJlNSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDQ2NGY0NzdlMTY0NDY0M2JlNWJmMzNkYmE3ZjQ1MTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjU4OTk3MDAwMDAwMSwgLTc5LjM0MDkyM10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zMjY4MDBjMjE4YTI0OWQ3YmNhZWQwMTc3OGU3OTI5NCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfOTAzNzk5ZmRjNmQyNGUwYzg5Y2E3Yzc2ODVkMjJiM2YgPSAkKGA8ZGl2IGlkPSJodG1sXzkwMzc5OWZkYzZkMjRlMGM4OWNhN2M3Njg1ZDIyYjNmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb24gTWlsbHMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzI2ODAwYzIxOGEyNDlkN2JjYWVkMDE3NzhlNzkyOTQuc2V0Q29udGVudChodG1sXzkwMzc5OWZkYzZkMjRlMGM4OWNhN2M3Njg1ZDIyYjNmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl80NDY0ZjQ3N2UxNjQ0NjQzYmU1YmYzM2RiYTdmNDUxNC5iaW5kUG9wdXAocG9wdXBfMzI2ODAwYzIxOGEyNDlkN2JjYWVkMDE3NzhlNzkyOTQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2QwNDY1MDc1MWQwZjQwNjY5YjFkZTQwYjA5OGYyODI4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk1MzQzOTAwMDAwMDA1LCAtNzkuMzE4Mzg4N10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lM2NjYTI4YjdjZTI0NjliOTM2ZDQzNDEzMGFlY2I5MSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYmQxMmVlYTEwZjFkNDg3YTljNDBmZGQ5ZjQ0NjAzMmQgPSAkKGA8ZGl2IGlkPSJodG1sX2JkMTJlZWExMGYxZDQ4N2E5YzQwZmRkOWY0NDYwMzJkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb29kYmluZSBIZWlnaHRzIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2UzY2NhMjhiN2NlMjQ2OWI5MzZkNDM0MTMwYWVjYjkxLnNldENvbnRlbnQoaHRtbF9iZDEyZWVhMTBmMWQ0ODdhOWM0MGZkZDlmNDQ2MDMyZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDA0NjUwNzUxZDBmNDA2NjliMWRlNDBiMDk4ZjI4MjguYmluZFBvcHVwKHBvcHVwX2UzY2NhMjhiN2NlMjQ2OWI5MzZkNDM0MTMwYWVjYjkxKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84NDFiMWMzZTgwNjI0MTU3OWU1OGNiYzlmNmZiMDQzOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MTQ5MzksIC03OS4zNzU0MTc5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzUxMzJhM2I4NjczZDQwMjNhNzQ3MjE3MmVhZTE0YWY4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82MTgyYWI5MmY2Y2M0NzY2OWU1YmVhMDYxYjdjZGEyOSA9ICQoYDxkaXYgaWQ9Imh0bWxfNjE4MmFiOTJmNmNjNDc2NjllNWJlYTA2MWI3Y2RhMjkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0LiBKYW1lcyBUb3duIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzUxMzJhM2I4NjczZDQwMjNhNzQ3MjE3MmVhZTE0YWY4LnNldENvbnRlbnQoaHRtbF82MTgyYWI5MmY2Y2M0NzY2OWU1YmVhMDYxYjdjZGEyOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfODQxYjFjM2U4MDYyNDE1NzllNThjYmM5ZjZmYjA0MzguYmluZFBvcHVwKHBvcHVwXzUxMzJhM2I4NjczZDQwMjNhNzQ3MjE3MmVhZTE0YWY4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mNWEwNDQ4NTk2ZTc0NzM1YmQwMjMxZTRkOTM0MGU2OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5Mzc4MTMsIC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82NTc1NjhhMjkyMGM0NThmYWU4NGYxYjE2MTEyNTA3ZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNjUyOGEyZGIwMjFjNDg2MWIxNTQzNzc2YjU1OTQ2NjAgPSAkKGA8ZGl2IGlkPSJodG1sXzY1MjhhMmRiMDIxYzQ4NjFiMTU0Mzc3NmI1NTk0NjYwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IdW1ld29vZC1DZWRhcnZhbGUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNjU3NTY4YTI5MjBjNDU4ZmFlODRmMWIxNjExMjUwN2Quc2V0Q29udGVudChodG1sXzY1MjhhMmRiMDIxYzQ4NjFiMTU0Mzc3NmI1NTk0NjYwKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9mNWEwNDQ4NTk2ZTc0NzM1YmQwMjMxZTRkOTM0MGU2OC5iaW5kUG9wdXAocG9wdXBfNjU3NTY4YTI5MjBjNDU4ZmFlODRmMWIxNjExMjUwN2QpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzE1NDIwNGQ3NGEzZDQ0OWM5Njk0ZjFkYWYxNWFjNzJmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQzNTE1MiwgLTc5LjU3NzIwMDc5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzBhNGY1NGZjMzQ3MTQ2NDM4YzcyYTJhMDFkM2I1MGI3ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zOWZkMWRlNDJlY2M0NjQxOTZhOWZmMTFkOGM3MWE2ZiA9ICQoYDxkaXYgaWQ9Imh0bWxfMzlmZDFkZTQyZWNjNDY0MTk2YTlmZjExZDhjNzFhNmYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVyaW5nYXRlLCBCbG9vcmRhbGUgR2FyZGVucywgT2xkIEJ1cm5oYW10aG9ycGUsIE1hcmtsYW5kIFdvb2QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMGE0ZjU0ZmMzNDcxNDY0MzhjNzJhMmEwMWQzYjUwYjcuc2V0Q29udGVudChodG1sXzM5ZmQxZGU0MmVjYzQ2NDE5NmE5ZmYxMWQ4YzcxYTZmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNTQyMDRkNzRhM2Q0NDljOTY5NGYxZGFmMTVhYzcyZi5iaW5kUG9wdXAocG9wdXBfMGE0ZjU0ZmMzNDcxNDY0MzhjNzJhMmEwMWQzYjUwYjcpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzFiYmRjZjg1NzI0NDRjZGU5OWVjMzUxOTM4Y2UyMmQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzYzNTcyNiwgLTc5LjE4ODcxMTVdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfY2MxMGU2NDE5ZjBhNGY1N2I2ZTI1MTQ4YzVkZmU5MjQgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2VjYmJiMzQxMjYyODQ2OTQ4NGFhMTIwYTZlZjFhMTdiID0gJChgPGRpdiBpZD0iaHRtbF9lY2JiYjM0MTI2Mjg0Njk0ODRhYTEyMGE2ZWYxYTE3YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R3VpbGR3b29kLCBNb3JuaW5nc2lkZSwgV2VzdCBIaWxsIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2NjMTBlNjQxOWYwYTRmNTdiNmUyNTE0OGM1ZGZlOTI0LnNldENvbnRlbnQoaHRtbF9lY2JiYjM0MTI2Mjg0Njk0ODRhYTEyMGE2ZWYxYTE3Yik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMWJiZGNmODU3MjQ0NGNkZTk5ZWMzNTE5MzhjZTIyZDUuYmluZFBvcHVwKHBvcHVwX2NjMTBlNjQxOWYwYTRmNTdiNmUyNTE0OGM1ZGZlOTI0KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yMTE1NjMzNmNjOWY0NjY3OGMyMTlkYjZlMDY3YTg4MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3NjM1NzM5OTk5OTk5LCAtNzkuMjkzMDMxMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lMGFiOTBiNDFjZDA0NmI5OTFiMjI1NzA0MjJjODg4ZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZDE1ZmUwMjJiNmQzNDU0NjgzZDQwNWU2ZGYwYjE4NDEgPSAkKGA8ZGl2IGlkPSJodG1sX2QxNWZlMDIyYjZkMzQ1NDY4M2Q0MDVlNmRmMGIxODQxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgQmVhY2hlcyBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9lMGFiOTBiNDFjZDA0NmI5OTFiMjI1NzA0MjJjODg4ZC5zZXRDb250ZW50KGh0bWxfZDE1ZmUwMjJiNmQzNDU0NjgzZDQwNWU2ZGYwYjE4NDEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzIxMTU2MzM2Y2M5ZjQ2Njc4YzIxOWRiNmUwNjdhODgyLmJpbmRQb3B1cChwb3B1cF9lMGFiOTBiNDFjZDA0NmI5OTFiMjI1NzA0MjJjODg4ZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMzFjMTE3YWQyMWI0NDQwZjgxNWNhNmZhYzkxMzMzYWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDQ3NzA3OTk5OTk5OTYsIC03OS4zNzMzMDY0XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzc1ZWYxMWJjMTVhMjRhYzk4ZWYxZjI3MzAzN2MzZTQzID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mYzg0Yjg5ZGEyYjM0OWIxOGNhZDUwNGFiYjgzMDc3MiA9ICQoYDxkaXYgaWQ9Imh0bWxfZmM4NGI4OWRhMmIzNDliMThjYWQ1MDRhYmI4MzA3NzIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJlcmN6eSBQYXJrIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzc1ZWYxMWJjMTVhMjRhYzk4ZWYxZjI3MzAzN2MzZTQzLnNldENvbnRlbnQoaHRtbF9mYzg0Yjg5ZGEyYjM0OWIxOGNhZDUwNGFiYjgzMDc3Mik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMzFjMTE3YWQyMWI0NDQwZjgxNWNhNmZhYzkxMzMzYWIuYmluZFBvcHVwKHBvcHVwXzc1ZWYxMWJjMTVhMjRhYzk4ZWYxZjI3MzAzN2MzZTQzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85ZDE5MGYzNDc2MzQ0ODZhYTQ0ZTQ2ODA0OTU5YTZkMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4OTAyNTYsIC03OS40NTM1MTJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiNmZjAwMDAiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZjZmZjU4OTc3OTA3NDZhYzk1ZWFhNDYzYjdjMzNmNmQgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzA4Njg2ZGU2OWNmNjQwY2ViYTYwMzllNDRhOTQ2ZTZlID0gJChgPGRpdiBpZD0iaHRtbF8wODY4NmRlNjljZjY0MGNlYmE2MDM5ZTQ0YTk0NmU2ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2FsZWRvbmlhLUZhaXJiYW5rcyBDbHVzdGVyIDAuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9mNmZmNTg5Nzc5MDc0NmFjOTVlYWE0NjNiN2MzM2Y2ZC5zZXRDb250ZW50KGh0bWxfMDg2ODZkZTY5Y2Y2NDBjZWJhNjAzOWU0NGE5NDZlNmUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzlkMTkwZjM0NzYzNDQ4NmFhNDRlNDY4MDQ5NTlhNmQzLmJpbmRQb3B1cChwb3B1cF9mNmZmNTg5Nzc5MDc0NmFjOTVlYWE0NjNiN2MzM2Y2ZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOGYzZGI5NDM3N2NiNGVhN2JlOWJhZDcyZWNkOGFkMmYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzA5OTIxLCAtNzkuMjE2OTE3NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNTI5OGFlZGFjODZhNDg4YmJmNjYwNjFlYWIzMjdkMTMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzU5NTQ3YjFhMjY0MjRlMzU5ODdhNTA5MDYwZTkwN2FjID0gJChgPGRpdiBpZD0iaHRtbF81OTU0N2IxYTI2NDI0ZTM1OTg3YTUwOTA2MGU5MDdhYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V29idXJuIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzUyOThhZWRhYzg2YTQ4OGJiZjY2MDYxZWFiMzI3ZDEzLnNldENvbnRlbnQoaHRtbF81OTU0N2IxYTI2NDI0ZTM1OTg3YTUwOTA2MGU5MDdhYyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOGYzZGI5NDM3N2NiNGVhN2JlOWJhZDcyZWNkOGFkMmYuYmluZFBvcHVwKHBvcHVwXzUyOThhZWRhYzg2YTQ4OGJiZjY2MDYxZWFiMzI3ZDEzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83NWExMTI4NGJkMjg0NzI4YjcyMmQ0NjAzMDJiNzcwNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTA2MDQsIC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzUzYzYwYmU0Y2FlNDQwMzE5ODg5Y2Q3NmY1MDJhM2M2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF84MDg3NTNhNjMwMjE0MTI1YjJjYWYyOTdkNmJlZThjNCA9ICQoYDxkaXYgaWQ9Imh0bWxfODA4NzUzYTYzMDIxNDEyNWIyY2FmMjk3ZDZiZWU4YzQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxlYXNpZGUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNTNjNjBiZTRjYWU0NDAzMTk4ODljZDc2ZjUwMmEzYzYuc2V0Q29udGVudChodG1sXzgwODc1M2E2MzAyMTQxMjViMmNhZjI5N2Q2YmVlOGM0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl83NWExMTI4NGJkMjg0NzI4YjcyMmQ0NjAzMDJiNzcwNy5iaW5kUG9wdXAocG9wdXBfNTNjNjBiZTRjYWU0NDAzMTk4ODljZDc2ZjUwMmEzYzYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBlMDg4ZjUyY2RhODQ0ZmNhNDQzY2Q1MWIzNzc1Zjg4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjU3OTUyNCwgLTc5LjM4NzM4MjZdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfODQ5ZTM4ZDRlMTU1NDI4NWI5NzhiMWJiNThiNmVlM2YgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRhZTg3NWIwNWVmZjQ2ZDg4OTkxMDMwYjVmNDk1ZWQ2ID0gJChgPGRpdiBpZD0iaHRtbF80YWU4NzViMDVlZmY0NmQ4ODk5MTAzMGI1ZjQ5NWVkNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2VudHJhbCBCYXkgU3RyZWV0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzg0OWUzOGQ0ZTE1NTQyODViOTc4YjFiYjU4YjZlZTNmLnNldENvbnRlbnQoaHRtbF80YWU4NzViMDVlZmY0NmQ4ODk5MTAzMGI1ZjQ5NWVkNik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMGUwODhmNTJjZGE4NDRmY2E0NDNjZDUxYjM3NzVmODguYmluZFBvcHVwKHBvcHVwXzg0OWUzOGQ0ZTE1NTQyODViOTc4YjFiYjU4YjZlZTNmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MzQ5ZDRhZDNkNGQ0YjAyODAyNjA4Y2NiYWU3YjQ5YyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2OTU0MiwgLTc5LjQyMjU2MzddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMGJjNDk5MDNmOGNjNGQ4NDg3ODE5ZGZmMGE4NTk2MjIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2UyZGRjYjE5YTYwODQ0OTViYTE3YTgyMWJjNThhZGQ3ID0gJChgPGRpdiBpZD0iaHRtbF9lMmRkY2IxOWE2MDg0NDk1YmExN2E4MjFiYzU4YWRkNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2hyaXN0aWUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMGJjNDk5MDNmOGNjNGQ4NDg3ODE5ZGZmMGE4NTk2MjIuc2V0Q29udGVudChodG1sX2UyZGRjYjE5YTYwODQ0OTViYTE3YTgyMWJjNThhZGQ3KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81MzQ5ZDRhZDNkNGQ0YjAyODAyNjA4Y2NiYWU3YjQ5Yy5iaW5kUG9wdXAocG9wdXBfMGJjNDk5MDNmOGNjNGQ4NDg3ODE5ZGZmMGE4NTk2MjIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2EwNzFkNDdlOGRmYTQ2Yjc4YjM2NWMzNzdiZTFmM2M1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzczMTM2LCAtNzkuMjM5NDc2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTc1MzRkMzgzYjM1NGU5N2IwNGI4ZDQ5NzhmOWRhZDMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzIwY2ZmYWRiYzQzOTQ5ZGViYTE2ZTJlNmQ5YjJmZDY5ID0gJChgPGRpdiBpZD0iaHRtbF8yMGNmZmFkYmM0Mzk0OWRlYmExNmUyZTZkOWIyZmQ2OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2VkYXJicmFlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2U3NTM0ZDM4M2IzNTRlOTdiMDRiOGQ0OTc4ZjlkYWQzLnNldENvbnRlbnQoaHRtbF8yMGNmZmFkYmM0Mzk0OWRlYmExNmUyZTZkOWIyZmQ2OSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTA3MWQ0N2U4ZGZhNDZiNzhiMzY1YzM3N2JlMWYzYzUuYmluZFBvcHVwKHBvcHVwX2U3NTM0ZDM4M2IzNTRlOTdiMDRiOGQ0OTc4ZjlkYWQzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wZTUyNzZmZGJkNmM0YmZmYTBiMzU5YTc0MTM4YzFiMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwMzc2MjIsIC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzExNDdmNWE0ZmE3ZDQ2MmQ4ZTBlYTQ2YWU4NGIzNjFlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81NjRlYjllYTM1YTY0N2ZiODUzODQzMWQzMzJkYjg1OCA9ICQoYDxkaXYgaWQ9Imh0bWxfNTY0ZWI5ZWEzNWE2NDdmYjg1Mzg0MzFkMzMyZGI4NTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhpbGxjcmVzdCBWaWxsYWdlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzExNDdmNWE0ZmE3ZDQ2MmQ4ZTBlYTQ2YWU4NGIzNjFlLnNldENvbnRlbnQoaHRtbF81NjRlYjllYTM1YTY0N2ZiODUzODQzMWQzMzJkYjg1OCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMGU1Mjc2ZmRiZDZjNGJmZmEwYjM1OWE3NDEzOGMxYjEuYmluZFBvcHVwKHBvcHVwXzExNDdmNWE0ZmE3ZDQ2MmQ4ZTBlYTQ2YWU4NGIzNjFlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jNWFhZTZjZDdkOTI0OTAzOWQyZTRhODFiNjZlZTcyNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NDMyODMsIC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzM4MGQ4ZGEyNTgxODQ0ODk4OTg0NTc3MDRlNzM2YmVlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85ODFjNzRmZjI5MWI0MDgwYjZiODMzY2IzZmIwYzNhOCA9ICQoYDxkaXYgaWQ9Imh0bWxfOTgxYzc0ZmYyOTFiNDA4MGI2YjgzM2NiM2ZiMGMzYTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJhdGh1cnN0IE1hbm9yLCBXaWxzb24gSGVpZ2h0cywgRG93bnN2aWV3IE5vcnRoIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzM4MGQ4ZGEyNTgxODQ0ODk4OTg0NTc3MDRlNzM2YmVlLnNldENvbnRlbnQoaHRtbF85ODFjNzRmZjI5MWI0MDgwYjZiODMzY2IzZmIwYzNhOCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYzVhYWU2Y2Q3ZDkyNDkwMzlkMmU0YTgxYjY2ZWU3MjYuYmluZFBvcHVwKHBvcHVwXzM4MGQ4ZGEyNTgxODQ0ODk4OTg0NTc3MDRlNzM2YmVlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMTY3YWE5YWZjNTQ0Mjc0OGE5YWE5ZTcxZGNmOWQ4MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNTM2ODksIC03OS4zNDkzNzE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82ZTUxZTBkMWZiNTA0ZDM0YTA0NzAyMzMzNzU1YzRjNSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZDVhM2YyODM4OTM3NDk4NWJlZjNkMWU5NTM5ZGI1NWMgPSAkKGA8ZGl2IGlkPSJodG1sX2Q1YTNmMjgzODkzNzQ5ODViZWYzZDFlOTUzOWRiNTVjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaG9ybmNsaWZmZSBQYXJrIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzZlNTFlMGQxZmI1MDRkMzRhMDQ3MDIzMzM3NTVjNGM1LnNldENvbnRlbnQoaHRtbF9kNWEzZjI4Mzg5Mzc0OTg1YmVmM2QxZTk1MzlkYjU1Yyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYjE2N2FhOWFmYzU0NDI3NDhhOWFhOWU3MWRjZjlkODMuYmluZFBvcHVwKHBvcHVwXzZlNTFlMGQxZmI1MDRkMzRhMDQ3MDIzMzM3NTVjNGM1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wODllZTFiYzY4NmY0MTI1YjcyZjQ1MTU0MmZkNDJhYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MDU3MTIwMDAwMDAxLCAtNzkuMzg0NTY3NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82ODMxZjg3NzZiMWU0NmQ4YjZjN2JiOGMyZmUxNTUyZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZjk5MGNkNWYyMzg4NGE3NzhhYWJiOTQ4ODYxODRhNDAgPSAkKGA8ZGl2IGlkPSJodG1sX2Y5OTBjZDVmMjM4ODRhNzc4YWFiYjk0ODg2MTg0YTQwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SaWNobW9uZCwgQWRlbGFpZGUsIEtpbmcgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNjgzMWY4Nzc2YjFlNDZkOGI2YzdiYjhjMmZlMTU1MmQuc2V0Q29udGVudChodG1sX2Y5OTBjZDVmMjM4ODRhNzc4YWFiYjk0ODg2MTg0YTQwKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wODllZTFiYzY4NmY0MTI1YjcyZjQ1MTU0MmZkNDJhYi5iaW5kUG9wdXAocG9wdXBfNjgzMWY4Nzc2YjFlNDZkOGI2YzdiYjhjMmZlMTU1MmQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY2OGYxNDY3ZDRjNzRkN2M4MmYxMGM1YmYwZTdjM2QyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY5MDA1MTAwMDAwMDEsIC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2IxOWQ0Mzk0ZmIyZTRjOWQ5MzhjNGI5MTMzNjcxMWEyID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF80MWNhZDZhOTc2ZjA0MWRlOTlmYzg5OTA0ZjVhYjJhZiA9ICQoYDxkaXYgaWQ9Imh0bWxfNDFjYWQ2YTk3NmYwNDFkZTk5ZmM4OTkwNGY1YWIyYWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkR1ZmZlcmluLCBEb3ZlcmNvdXJ0IFZpbGxhZ2UgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYjE5ZDQzOTRmYjJlNGM5ZDkzOGM0YjkxMzM2NzExYTIuc2V0Q29udGVudChodG1sXzQxY2FkNmE5NzZmMDQxZGU5OWZjODk5MDRmNWFiMmFmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82NjhmMTQ2N2Q0Yzc0ZDdjODJmMTBjNWJmMGU3YzNkMi5iaW5kUG9wdXAocG9wdXBfYjE5ZDQzOTRmYjJlNGM5ZDkzOGM0YjkxMzM2NzExYTIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzlmOGI0Yzk2NmJlNTRiOWI5NTgyMzI2MjMxOTM1YzEyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzQ0NzM0MiwgLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjMDBiNWViIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMwMGI1ZWIiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzgxODRkZTliZWYxNjRmNmViNmI1YTRmOGM0NzllZDk4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82YWFjZTM0ZmVkMTA0N2ZmOTU0ODFiNzExZDhiNDE2YSA9ICQoYDxkaXYgaWQ9Imh0bWxfNmFhY2UzNGZlZDEwNDdmZjk1NDgxYjcxMWQ4YjQxNmEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlNjYXJib3JvdWdoIFZpbGxhZ2UgQ2x1c3RlciAyLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfODE4NGRlOWJlZjE2NGY2ZWI2YjVhNGY4YzQ3OWVkOTguc2V0Q29udGVudChodG1sXzZhYWNlMzRmZWQxMDQ3ZmY5NTQ4MWI3MTFkOGI0MTZhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85ZjhiNGM5NjZiZTU0YjliOTU4MjMyNjIzMTkzNWMxMi5iaW5kUG9wdXAocG9wdXBfODE4NGRlOWJlZjE2NGY2ZWI2YjVhNGY4YzQ3OWVkOTgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y0YjM2YWJkZGU2ODQ5MjVhMjZjZWU3M2NjYzRlZTBhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzc4NTE3NSwgLTc5LjM0NjU1NTddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZjFhNjI0ZDc5M2UxNDRjMThjOTFhN2FlNWEwNjRmN2UgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzVkNTc0YmU1MzRiNTQwNTZhYjk4MDdhODkwZGYzYjQwID0gJChgPGRpdiBpZD0iaHRtbF81ZDU3NGJlNTM0YjU0MDU2YWI5ODA3YTg5MGRmM2I0MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RmFpcnZpZXcsIEhlbnJ5IEZhcm0sIE9yaW9sZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9mMWE2MjRkNzkzZTE0NGMxOGM5MWE3YWU1YTA2NGY3ZS5zZXRDb250ZW50KGh0bWxfNWQ1NzRiZTUzNGI1NDA1NmFiOTgwN2E4OTBkZjNiNDApOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Y0YjM2YWJkZGU2ODQ5MjVhMjZjZWU3M2NjYzRlZTBhLmJpbmRQb3B1cChwb3B1cF9mMWE2MjRkNzkzZTE0NGMxOGM5MWE3YWU1YTA2NGY3ZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZmJkMjhiZGJjODg5NDY0MTk4NzQ5OWQ5YmU1MDM4NzQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Njc5ODAzLCAtNzkuNDg3MjYxOTAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMmMzMTM1NjdkNTk3NGVhMThlOGI3NzI1YTQ5ODhhNGIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzg5NzBmYTRlYTUxZDRlOGJhOWU3NzExZGY5YWM3YmIxID0gJChgPGRpdiBpZD0iaHRtbF84OTcwZmE0ZWE1MWQ0ZThiYTllNzcxMWRmOWFjN2JiMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGh3b29kIFBhcmssIFlvcmsgVW5pdmVyc2l0eSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8yYzMxMzU2N2Q1OTc0ZWExOGU4Yjc3MjVhNDk4OGE0Yi5zZXRDb250ZW50KGh0bWxfODk3MGZhNGVhNTFkNGU4YmE5ZTc3MTFkZjlhYzdiYjEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2ZiZDI4YmRiYzg4OTQ2NDE5ODc0OTlkOWJlNTAzODc0LmJpbmRQb3B1cChwb3B1cF8yYzMxMzU2N2Q1OTc0ZWExOGU4Yjc3MjVhNDk4OGE0YikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzk5YTJhYjI0YmMyNDk2MWIyNmEyNDNiNjZhZDZjNmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODUzNDcsIC03OS4zMzgxMDY1XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjZmYwMDAwIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiNmZjAwMDAiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzkzY2IwMTA4Zjc5MDRlYzc4YWYxZjU3MTg2YjhiNjNjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8wYzEwYTlkZjcwZDk0ZjA3OGQzYTkxNDNkZTgxNmEyMiA9ICQoYDxkaXYgaWQ9Imh0bWxfMGMxMGE5ZGY3MGQ5NGYwNzhkM2E5MTQzZGU4MTZhMjIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVhc3QgVG9yb250bywgQnJvYWR2aWV3IE5vcnRoIChPbGQgRWFzdCBZb3JrKSBDbHVzdGVyIDAuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85M2NiMDEwOGY3OTA0ZWM3OGFmMWY1NzE4NmI4YjYzYy5zZXRDb250ZW50KGh0bWxfMGMxMGE5ZGY3MGQ5NGYwNzhkM2E5MTQzZGU4MTZhMjIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2M5OWEyYWIyNGJjMjQ5NjFiMjZhMjQzYjY2YWQ2YzZkLmJpbmRQb3B1cChwb3B1cF85M2NiMDEwOGY3OTA0ZWM3OGFmMWY1NzE4NmI4YjYzYykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOTk5YWE1OWQ1YTNhNDM3ZDk4YWMyZjhhNTA5OTg2MDkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDA4MTU3LCAtNzkuMzgxNzUyMjk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMWMwYWEzYTZkODY4NGY5Yzg5YTUxYmU3MTcxMDk2ODUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzYyMjg4MjYxYmI5MTQwNjg5NDk1M2NjOGU2ZGNjOWY0ID0gJChgPGRpdiBpZD0iaHRtbF82MjI4ODI2MWJiOTE0MDY4OTQ5NTNjYzhlNmRjYzlmNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGFyYm91cmZyb250IEVhc3QsIFVuaW9uIFN0YXRpb24sIFRvcm9udG8gSXNsYW5kcyBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8xYzBhYTNhNmQ4Njg0ZjljODlhNTFiZTcxNzEwOTY4NS5zZXRDb250ZW50KGh0bWxfNjIyODgyNjFiYjkxNDA2ODk0OTUzY2M4ZTZkY2M5ZjQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzk5OWFhNTlkNWEzYTQzN2Q5OGFjMmY4YTUwOTk4NjA5LmJpbmRQb3B1cChwb3B1cF8xYzBhYTNhNmQ4Njg0ZjljODlhNTFiZTcxNzEwOTY4NSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjg4OGJkMDc1ODdlNGM4M2JjNTUzYzU3NjgwZThlMTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDc5MjY3MDAwMDAwMDYsIC03OS40MTk3NDk3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzVmYzgyN2U4MTQwZjQzZjA4ZGJkZDFmMjkxNjA0N2VlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8xYTEzNjM2ZThjZTE0Y2M2YmM0MTg5OWJiYTAzNDU5NSA9ICQoYDxkaXYgaWQ9Imh0bWxfMWExMzYzNmU4Y2UxNGNjNmJjNDE4OTliYmEwMzQ1OTUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxpdHRsZSBQb3J0dWdhbCwgVHJpbml0eSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF81ZmM4MjdlODE0MGY0M2YwOGRiZGQxZjI5MTYwNDdlZS5zZXRDb250ZW50KGh0bWxfMWExMzYzNmU4Y2UxNGNjNmJjNDE4OTliYmEwMzQ1OTUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzI4ODhiZDA3NTg3ZTRjODNiYzU1M2M1NzY4MGU4ZTE1LmJpbmRQb3B1cChwb3B1cF81ZmM4MjdlODE0MGY0M2YwOGRiZGQxZjI5MTYwNDdlZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjc1NWQ0ZWQwMjk0NGI2N2JjNGYzYzEzYTRiYTViNzUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjc5MjkyLCAtNzkuMjYyMDI5NDAwMDAwMDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZDk5Yjk0MWZlY2YxNDdiMGE0MDNlNDcwZjQxZGJjOWYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzE2Y2RiZDU3ZGFiYzQwYzZhNzY3NzVmNjg0Y2Q5MWQxID0gJChgPGRpdiBpZD0iaHRtbF8xNmNkYmQ1N2RhYmM0MGM2YTc2Nzc1ZjY4NGNkOTFkMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+S2VubmVkeSBQYXJrLCBJb252aWV3LCBFYXN0IEJpcmNobW91bnQgUGFyayBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9kOTliOTQxZmVjZjE0N2IwYTQwM2U0NzBmNDFkYmM5Zi5zZXRDb250ZW50KGh0bWxfMTZjZGJkNTdkYWJjNDBjNmE3Njc3NWY2ODRjZDkxZDEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2I3NTVkNGVkMDI5NDRiNjdiYzRmM2MxM2E0YmE1Yjc1LmJpbmRQb3B1cChwb3B1cF9kOTliOTQxZmVjZjE0N2IwYTQwM2U0NzBmNDFkYmM5ZikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfODBhYmFmMDk3M2ZiNGQzNmJkYjQ5YWY0OTg3N2Y5MmYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43ODY5NDczLCAtNzkuMzg1OTc1XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2FiMGFhYWMwNTRiYTQ3N2ViMTQ2YmU0MmZmYjllN2Y0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85ZDI2Y2Q2MzUyMTM0YzJjOWRjZGQ1Mjk4NDdjZWE2YyA9ICQoYDxkaXYgaWQ9Imh0bWxfOWQyNmNkNjM1MjEzNGMyYzlkY2RkNTI5ODQ3Y2VhNmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJheXZpZXcgVmlsbGFnZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9hYjBhYWFjMDU0YmE0NzdlYjE0NmJlNDJmZmI5ZTdmNC5zZXRDb250ZW50KGh0bWxfOWQyNmNkNjM1MjEzNGMyYzlkY2RkNTI5ODQ3Y2VhNmMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzgwYWJhZjA5NzNmYjRkMzZiZGI0OWFmNDk4NzdmOTJmLmJpbmRQb3B1cChwb3B1cF9hYjBhYWFjMDU0YmE0NzdlYjE0NmJlNDJmZmI5ZTdmNCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzQ3ZGY3M2RiMWFmNDBjM2EwYTFhOTRiY2FlMzA0MGUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mzc0NzMyMDAwMDAwMDQsIC03OS40NjQ3NjMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9kZmVhYTliNDZmOTU0N2E5YjJiNzQ0Mzc3YTc2YTBjNyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjhkODg4NTcxZGRlNGQ2Yjg3ZTg1YWVlNzM1ZGFiYWQgPSAkKGA8ZGl2IGlkPSJodG1sX2I4ZDg4ODU3MWRkZTRkNmI4N2U4NWFlZTczNWRhYmFkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3duc3ZpZXcgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZGZlYWE5YjQ2Zjk1NDdhOWIyYjc0NDM3N2E3NmEwYzcuc2V0Q29udGVudChodG1sX2I4ZDg4ODU3MWRkZTRkNmI4N2U4NWFlZTczNWRhYmFkKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jNDdkZjczZGIxYWY0MGMzYTBhMWE5NGJjYWUzMDQwZS5iaW5kUG9wdXAocG9wdXBfZGZlYWE5YjQ2Zjk1NDdhOWIyYjc0NDM3N2E3NmEwYzcpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q2OGQwYzQ2ZjgxYzQ0NDBiNjE1MWUzZjhiZTBiMjgwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjc5NTU3MSwgLTc5LjM1MjE4OF0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80NmI2Y2FjN2EyNGU0YTlmYmY2NjdlOWVmMmU5NDAwYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNjU1OWZkMTUwZTliNDMzM2EwZTg3ZjQ2ZWZkMGIxMGYgPSAkKGA8ZGl2IGlkPSJodG1sXzY1NTlmZDE1MGU5YjQzMzNhMGU4N2Y0NmVmZDBiMTBmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgRGFuZm9ydGggV2VzdCwgUml2ZXJkYWxlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzQ2YjZjYWM3YTI0ZTRhOWZiZjY2N2U5ZWYyZTk0MDBhLnNldENvbnRlbnQoaHRtbF82NTU5ZmQxNTBlOWI0MzMzYTBlODdmNDZlZmQwYjEwZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDY4ZDBjNDZmODFjNDQ0MGI2MTUxZTNmOGJlMGIyODAuYmluZFBvcHVwKHBvcHVwXzQ2YjZjYWM3YTI0ZTRhOWZiZjY2N2U5ZWYyZTk0MDBhKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMjhlODA4YTU5NDA0NzhlYmFlZTNjOTBkNWI2MjkxMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NzE3NjgsIC03OS4zODE1NzY0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9kZDExM2I4Yzk1ZjU0NWE4OGExZmMzYTBlMTc2NGU4ZiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYTQ1Zjc2YmIzNTVhNDg3OGFhY2U2MDBlYTBkN2IwMmIgPSAkKGA8ZGl2IGlkPSJodG1sX2E0NWY3NmJiMzU1YTQ4NzhhYWNlNjAwZWEwZDdiMDJiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ub3JvbnRvIERvbWluaW9uIENlbnRyZSwgRGVzaWduIEV4Y2hhbmdlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2RkMTEzYjhjOTVmNTQ1YTg4YTFmYzNhMGUxNzY0ZThmLnNldENvbnRlbnQoaHRtbF9hNDVmNzZiYjM1NWE0ODc4YWFjZTYwMGVhMGQ3YjAyYik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTI4ZTgwOGE1OTQwNDc4ZWJhZWUzYzkwZDViNjI5MTMuYmluZFBvcHVwKHBvcHVwX2RkMTEzYjhjOTVmNTQ1YTg4YTFmYzNhMGUxNzY0ZThmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jM2ZjYjM5NmYzNjA0YjkzYTdjNGQ1ZWZmYmRhYjM4OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjg0NzIsIC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83ZjU1OWI2MjJhM2I0N2ZhODI4MDI0YjU3OTg4YzJjNyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMDE3NDUzZTcxYWQzNGRkNjg1MjRlZDlmZmI3MmY2MTYgPSAkKGA8ZGl2IGlkPSJodG1sXzAxNzQ1M2U3MWFkMzRkZDY4NTI0ZWQ5ZmZiNzJmNjE2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ccm9ja3RvbiwgUGFya2RhbGUgVmlsbGFnZSwgRXhoaWJpdGlvbiBQbGFjZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83ZjU1OWI2MjJhM2I0N2ZhODI4MDI0YjU3OTg4YzJjNy5zZXRDb250ZW50KGh0bWxfMDE3NDUzZTcxYWQzNGRkNjg1MjRlZDlmZmI3MmY2MTYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2MzZmNiMzk2ZjM2MDRiOTNhN2M0ZDVlZmZiZGFiMzg4LmJpbmRQb3B1cChwb3B1cF83ZjU1OWI2MjJhM2I0N2ZhODI4MDI0YjU3OTg4YzJjNykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNmEyY2EwMzg2NjFhNGRiZDk5MTYzZDhmZDUxZWFkZjYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTExMTE3MDAwMDAwMDQsIC03OS4yODQ1NzcyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzkxYTI3YzI2YzM0ODQyNDc4MjUzOTI1ZTYwNzA0ZjNhID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9iZjNlODZjOTQzNWQ0OTQ1YjY2ZjQ3NGIwMzc4NmI0YSA9ICQoYDxkaXYgaWQ9Imh0bWxfYmYzZTg2Yzk0MzVkNDk0NWI2NmY0NzRiMDM3ODZiNGEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkdvbGRlbiBNaWxlLCBDbGFpcmxlYSwgT2FrcmlkZ2UgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOTFhMjdjMjZjMzQ4NDI0NzgyNTM5MjVlNjA3MDRmM2Euc2V0Q29udGVudChodG1sX2JmM2U4NmM5NDM1ZDQ5NDViNjZmNDc0YjAzNzg2YjRhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82YTJjYTAzODY2MWE0ZGJkOTkxNjNkOGZkNTFlYWRmNi5iaW5kUG9wdXAocG9wdXBfOTFhMjdjMjZjMzQ4NDI0NzgyNTM5MjVlNjA3MDRmM2EpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzIwYTc4MThiYmM5ZTQxNTRhNTk2YmJkM2M5OWM4ODQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM5MDE0NiwgLTc5LjUwNjk0MzZdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMGUxNDRjOGE4NjBjNDNjYjhkNjg3MjcyODc4NDQ2NzYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzI1NTFlOGE2YTZlZjQ5M2RhMjRjN2E4OWU4NGNlYzQ4ID0gJChgPGRpdiBpZD0iaHRtbF8yNTUxZThhNmE2ZWY0OTNkYTI0YzdhODllODRjZWM0OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG93bnN2aWV3IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzBlMTQ0YzhhODYwYzQzY2I4ZDY4NzI3Mjg3ODQ0Njc2LnNldENvbnRlbnQoaHRtbF8yNTUxZThhNmE2ZWY0OTNkYTI0YzdhODllODRjZWM0OCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjBhNzgxOGJiYzllNDE1NGE1OTZiYmQzYzk5Yzg4NDUuYmluZFBvcHVwKHBvcHVwXzBlMTQ0YzhhODYwYzQzY2I4ZDY4NzI3Mjg3ODQ0Njc2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zNmZhZmM5OTZiNDM0YzA1YTEzMGQ4MDc3Njg3NjkwZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2ODk5ODUsIC03OS4zMTU1NzE1OTk5OTk5OF0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yZGQxYzkwNjExYmE0ODZlYWRlYjQyM2NjYTcyNWViMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjkyMmFjMTFmZDg0NGJkNGFkZDI3ZjhlNDFhY2ExOWMgPSAkKGA8ZGl2IGlkPSJodG1sX2I5MjJhYzExZmQ4NDRiZDRhZGQyN2Y4ZTQxYWNhMTljIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5JbmRpYSBCYXphYXIsIFRoZSBCZWFjaGVzIFdlc3QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMmRkMWM5MDYxMWJhNDg2ZWFkZWI0MjNjY2E3MjVlYjMuc2V0Q29udGVudChodG1sX2I5MjJhYzExZmQ4NDRiZDRhZGQyN2Y4ZTQxYWNhMTljKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8zNmZhZmM5OTZiNDM0YzA1YTEzMGQ4MDc3Njg3NjkwZC5iaW5kUG9wdXAocG9wdXBfMmRkMWM5MDYxMWJhNDg2ZWFkZWI0MjNjY2E3MjVlYjMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RmZTU4ZDVkOGNmYjQxMTY5MThlMTZkMTU5MTNiZDU0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4MTk4NSwgLTc5LjM3OTgxNjkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzk1NDc2ZmRkZWM1NTQ5Zjg4N2FiZDIyN2I0Mzg3NzkwID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85ZGMzZWE3NjY5MTI0ZTQ3OWI2ZGEwNGNjOWJkZTM0MyA9ICQoYDxkaXYgaWQ9Imh0bWxfOWRjM2VhNzY2OTEyNGU0NzliNmRhMDRjYzliZGUzNDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNvbW1lcmNlIENvdXJ0LCBWaWN0b3JpYSBIb3RlbCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85NTQ3NmZkZGVjNTU0OWY4ODdhYmQyMjdiNDM4Nzc5MC5zZXRDb250ZW50KGh0bWxfOWRjM2VhNzY2OTEyNGU0NzliNmRhMDRjYzliZGUzNDMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2RmZTU4ZDVkOGNmYjQxMTY5MThlMTZkMTU5MTNiZDU0LmJpbmRQb3B1cChwb3B1cF85NTQ3NmZkZGVjNTU0OWY4ODdhYmQyMjdiNDM4Nzc5MCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjJiODA1NTlmYTk4NGZhZDg5ZDlmYjkzNjIzYTQ2NjggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTM3NTYyMDAwMDAwMDYsIC03OS40OTAwNzM4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzQyMzIwZjNjNjA3MzRmNGZhN2MzYjdkNjhmODY5MDBlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83ZDZiMmI3ZjA0YzU0NzFhYTFjMzU0NjQ0OTI1ZmI5MiA9ICQoYDxkaXYgaWQ9Imh0bWxfN2Q2YjJiN2YwNGM1NDcxYWExYzM1NDY0NDkyNWZiOTIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk5vcnRoIFBhcmssIE1hcGxlIExlYWYgUGFyaywgVXB3b29kIFBhcmsgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDIzMjBmM2M2MDczNGY0ZmE3YzNiN2Q2OGY4NjkwMGUuc2V0Q29udGVudChodG1sXzdkNmIyYjdmMDRjNTQ3MWFhMWMzNTQ2NDQ5MjVmYjkyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iMmI4MDU1OWZhOTg0ZmFkODlkOWZiOTM2MjNhNDY2OC5iaW5kUG9wdXAocG9wdXBfNDIzMjBmM2M2MDczNGY0ZmE3YzNiN2Q2OGY4NjkwMGUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYzYTgxZWVlYTU5MDRjYTA4ZmMyNzUxZjE1ZGRhYTFiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU2MzAzMywgLTc5LjU2NTk2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjMDBiNWViIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMwMGI1ZWIiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzdmOTM4YjVlZTNlZDRlNWY5MWE0YTIzZDJjYWJmMjM2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82NDUyMjUxZDJhNzg0OWZkOGE0ZTdhYjRiOTA5M2NjZSA9ICQoYDxkaXYgaWQ9Imh0bWxfNjQ1MjI1MWQyYTc4NDlmZDhhNGU3YWI0YjkwOTNjY2UiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkh1bWJlciBTdW1taXQgQ2x1c3RlciAyLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfN2Y5MzhiNWVlM2VkNGU1ZjkxYTRhMjNkMmNhYmYyMzYuc2V0Q29udGVudChodG1sXzY0NTIyNTFkMmE3ODQ5ZmQ4YTRlN2FiNGI5MDkzY2NlKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82M2E4MWVlZWE1OTA0Y2EwOGZjMjc1MWYxNWRkYWExYi5iaW5kUG9wdXAocG9wdXBfN2Y5MzhiNWVlM2VkNGU1ZjkxYTRhMjNkMmNhYmYyMzYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzRmNGE2YjJhYjY3MzQ0YWE4YzA4ZDFjMGEyMTllMGY1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzE2MzE2LCAtNzkuMjM5NDc2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMzE1ZmExNDNmNmQ0NDM1Yzg4MWZjMjk4OGFjYTc4YzEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzQwYWM5YzM4Y2VkYTRmZmRiYTg4YTRiMmFhNDE0ZjYzID0gJChgPGRpdiBpZD0iaHRtbF80MGFjOWMzOGNlZGE0ZmZkYmE4OGE0YjJhYTQxNGY2MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2xpZmZzaWRlLCBDbGlmZmNyZXN0LCBTY2FyYm9yb3VnaCBWaWxsYWdlIFdlc3QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzE1ZmExNDNmNmQ0NDM1Yzg4MWZjMjk4OGFjYTc4YzEuc2V0Q29udGVudChodG1sXzQwYWM5YzM4Y2VkYTRmZmRiYTg4YTRiMmFhNDE0ZjYzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl80ZjRhNmIyYWI2NzM0NGFhOGMwOGQxYzBhMjE5ZTBmNS5iaW5kUG9wdXAocG9wdXBfMzE1ZmExNDNmNmQ0NDM1Yzg4MWZjMjk4OGFjYTc4YzEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdiMmExNzQ3OTk2YjRlMThiMTUwOTI0MmNhM2JlNzU1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg5MDUzLCAtNzkuNDA4NDkyNzk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiNmZjAwMDAiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTQ3ZTQwODM5ZjVjNDUyZmE1ZWU3YmY1ZDk5ZDMxOTYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2YyMGMxMDg2YzJiODRmZmI4ZmE1MDRlNWZlNTU4MjNiID0gJChgPGRpdiBpZD0iaHRtbF9mMjBjMTA4NmMyYjg0ZmZiOGZhNTA0ZTVmZTU1ODIzYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSwgTmV3dG9uYnJvb2sgQ2x1c3RlciAwLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZTQ3ZTQwODM5ZjVjNDUyZmE1ZWU3YmY1ZDk5ZDMxOTYuc2V0Q29udGVudChodG1sX2YyMGMxMDg2YzJiODRmZmI4ZmE1MDRlNWZlNTU4MjNiKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl83YjJhMTc0Nzk5NmI0ZTE4YjE1MDkyNDJjYTNiZTc1NS5iaW5kUG9wdXAocG9wdXBfZTQ3ZTQwODM5ZjVjNDUyZmE1ZWU3YmY1ZDk5ZDMxOTYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ZjZmYyZGUwNjkwNzQzMGQ5NDMwNTdlNGJjOWY5Yzk1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI4NDk2NCwgLTc5LjQ5NTY5NzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzc0OTQ2NGNkOWRhODQ3ZWFiMTMxZTYyNmQ1Y2M1ZjlmID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8xZGIwYjEzYmFmMWI0MjAxYTcyMTcwNGRhMmY1YTY5NyA9ICQoYDxkaXYgaWQ9Imh0bWxfMWRiMGIxM2JhZjFiNDIwMWE3MjE3MDRkYTJmNWE2OTciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldyBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83NDk0NjRjZDlkYTg0N2VhYjEzMWU2MjZkNWNjNWY5Zi5zZXRDb250ZW50KGh0bWxfMWRiMGIxM2JhZjFiNDIwMWE3MjE3MDRkYTJmNWE2OTcpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2ZjZmYyZGUwNjkwNzQzMGQ5NDMwNTdlNGJjOWY5Yzk1LmJpbmRQb3B1cChwb3B1cF83NDk0NjRjZDlkYTg0N2VhYjEzMWU2MjZkNWNjNWY5ZikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjcyNTg0Mjc0NjljNGE1OGIxYTdhY2MyZmRjZDdhMWYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTk1MjU1LCAtNzkuMzQwOTIzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzA1ZDIzODIwMjI2NDRlZjNhZTgyYzQyMjlhNGRmODA5ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jMWE0MjRkNDgwZjA0ZTljYThhYWQyZWVjY2IyYTA0YyA9ICQoYDxkaXYgaWQ9Imh0bWxfYzFhNDI0ZDQ4MGYwNGU5Y2E4YWFkMmVlY2NiMmEwNGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0dWRpbyBEaXN0cmljdCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8wNWQyMzgyMDIyNjQ0ZWYzYWU4MmM0MjI5YTRkZjgwOS5zZXRDb250ZW50KGh0bWxfYzFhNDI0ZDQ4MGYwNGU5Y2E4YWFkMmVlY2NiMmEwNGMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2I3MjU4NDI3NDY5YzRhNThiMWE3YWNjMmZkY2Q3YTFmLmJpbmRQb3B1cChwb3B1cF8wNWQyMzgyMDIyNjQ0ZWYzYWU4MmM0MjI5YTRkZjgwOSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzIxODEyOGYwMDAxNGJlMTliODQwM2E4MDI0ZjlkMjIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MzMyODI1LCAtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zMWMxMmM1NzhmZmI0OTE5YTk3ZWEyMGFjNzAzM2MwZSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMzZkYmJlZWEyMDRmNDE3OThhOTY0MWMwY2E4MzUyNTYgPSAkKGA8ZGl2IGlkPSJodG1sXzM2ZGJiZWVhMjA0ZjQxNzk4YTk2NDFjMGNhODM1MjU2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CZWRmb3JkIFBhcmssIExhd3JlbmNlIE1hbm9yIEVhc3QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzFjMTJjNTc4ZmZiNDkxOWE5N2VhMjBhYzcwMzNjMGUuc2V0Q29udGVudChodG1sXzM2ZGJiZWVhMjA0ZjQxNzk4YTk2NDFjMGNhODM1MjU2KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jMjE4MTI4ZjAwMDE0YmUxOWI4NDAzYTgwMjRmOWQyMi5iaW5kUG9wdXAocG9wdXBfMzFjMTJjNTc4ZmZiNDkxOWE5N2VhMjBhYzcwMzNjMGUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBkNzA1YWZjN2Y2MjRiYmY4MWIyYzUyNzlmMDBkOWQ4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkxMTE1OCwgLTc5LjQ3NjAxMzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzEyZjRhN2RmNTI0ZTRlY2Y5NTBiZGE0NmI5ZmJkZGUzID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81YjdlNGEyZGM3Yzk0YzM3YjFjNTMxYmJiODcxODU3NiA9ICQoYDxkaXYgaWQ9Imh0bWxfNWI3ZTRhMmRjN2M5NGMzN2IxYzUzMWJiYjg3MTg1NzYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRlbCBSYXksIE1vdW50IERlbm5pcywgS2VlbHNkYWxlIGFuZCBTaWx2ZXJ0aG9ybiBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8xMmY0YTdkZjUyNGU0ZWNmOTUwYmRhNDZiOWZiZGRlMy5zZXRDb250ZW50KGh0bWxfNWI3ZTRhMmRjN2M5NGMzN2IxYzUzMWJiYjg3MTg1NzYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzBkNzA1YWZjN2Y2MjRiYmY4MWIyYzUyNzlmMDBkOWQ4LmJpbmRQb3B1cChwb3B1cF8xMmY0YTdkZjUyNGU0ZWNmOTUwYmRhNDZiOWZiZGRlMykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDRmMDkxNTQzNzk0NDYyMmIwNThkYmEyM2UyYWU1ZmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjQ3NjU5LCAtNzkuNTMyMjQyNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MGZmYjQiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwZmZiNCIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfN2RlNmFkMzQ1ZjUzNGZkM2FmMDYxNmYwNjhiNGVlMjYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzQ4OTY5YzBiMmVlODRlYjZiZWMyMGVjMjVjM2JjMWRiID0gJChgPGRpdiBpZD0iaHRtbF80ODk2OWMwYjJlZTg0ZWI2YmVjMjBlYzI1YzNiYzFkYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtYmVybGVhLCBFbWVyeSBDbHVzdGVyIDMuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83ZGU2YWQzNDVmNTM0ZmQzYWYwNjE2ZjA2OGI0ZWUyNi5zZXRDb250ZW50KGh0bWxfNDg5NjljMGIyZWU4NGViNmJlYzIwZWMyNWMzYmMxZGIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q0ZjA5MTU0Mzc5NDQ2MjJiMDU4ZGJhMjNlMmFlNWZkLmJpbmRQb3B1cChwb3B1cF83ZGU2YWQzNDVmNTM0ZmQzYWYwNjE2ZjA2OGI0ZWUyNikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYTJmYTRlOTEzMWFmNGJhOGFmOWI2NjNmODk5OWI0MDcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTI2NTcwMDAwMDAwMDQsIC03OS4yNjQ4NDgxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2RlYjgzOGZlMmFlZjQ2YzdhZjMxODU1MTYyYTQxNDgxID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81YjMwMWE2NzM2MWY0ZWY3ODU5YWIzZjljZTBlMWQzZCA9ICQoYDxkaXYgaWQ9Imh0bWxfNWIzMDFhNjczNjFmNGVmNzg1OWFiM2Y5Y2UwZTFkM2QiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJpcmNoIENsaWZmLCBDbGlmZnNpZGUgV2VzdCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9kZWI4MzhmZTJhZWY0NmM3YWYzMTg1NTE2MmE0MTQ4MS5zZXRDb250ZW50KGh0bWxfNWIzMDFhNjczNjFmNGVmNzg1OWFiM2Y5Y2UwZTFkM2QpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2EyZmE0ZTkxMzFhZjRiYThhZjliNjYzZjg5OTliNDA3LmJpbmRQb3B1cChwb3B1cF9kZWI4MzhmZTJhZWY0NmM3YWYzMTg1NTE2MmE0MTQ4MSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjU4YTFmMzEzODNlNDdjZGEyYzE4ZDBlZTdhNDJjOGQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzAxMTk5LCAtNzkuNDA4NDkyNzk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMzMwMjdlMDJjYjkxNDUyOGJhZjU5OWY4NzA4MzUxMzUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzIzMTczOThhYjU5NTRmMDQ5YWIyMjhjZTYyMWIxOGRkID0gJChgPGRpdiBpZD0iaHRtbF8yMzE3Mzk4YWI1OTU0ZjA0OWFiMjI4Y2U2MjFiMThkZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSwgV2lsbG93ZGFsZSBFYXN0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzMzMDI3ZTAyY2I5MTQ1MjhiYWY1OTlmODcwODM1MTM1LnNldENvbnRlbnQoaHRtbF8yMzE3Mzk4YWI1OTU0ZjA0OWFiMjI4Y2U2MjFiMThkZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjU4YTFmMzEzODNlNDdjZGEyYzE4ZDBlZTdhNDJjOGQuYmluZFBvcHVwKHBvcHVwXzMzMDI3ZTAyY2I5MTQ1MjhiYWY1OTlmODcwODM1MTM1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMDAyMzQxNGQ3ZmY0YmFjOWNkMzA0ZjE5OTVmODRhZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2MTYzMTMsIC03OS41MjA5OTk0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82N2Y0NzlhNjI4MWU0MWZiOTMzNTk5ZTJkNTgxMjc2ZSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDg0NzViNDlhMGE1NGRhMzgwMTY5MzUyNTc2YWVlODggPSAkKGA8ZGl2IGlkPSJodG1sXzQ4NDc1YjQ5YTBhNTRkYTM4MDE2OTM1MjU3NmFlZTg4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3duc3ZpZXcgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNjdmNDc5YTYyODFlNDFmYjkzMzU5OWUyZDU4MTI3NmUuc2V0Q29udGVudChodG1sXzQ4NDc1YjQ5YTBhNTRkYTM4MDE2OTM1MjU3NmFlZTg4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iMDAyMzQxNGQ3ZmY0YmFjOWNkMzA0ZjE5OTVmODRhZi5iaW5kUG9wdXAocG9wdXBfNjdmNDc5YTYyODFlNDFmYjkzMzU5OWUyZDU4MTI3NmUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2EwMGEzNjQxN2QyZjQzMDRiZmE5MmMyOTFlZmUyMjJiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI4MDIwNSwgLTc5LjM4ODc5MDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOWFjNTRmOGJkYzU0NDRhMzhmZjE3MTNkZGU1ZTk3NTEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzdjZGY1OTZmN2VlZDRlODZiNjQ3NTBkN2MwOTdmMmZiID0gJChgPGRpdiBpZD0iaHRtbF83Y2RmNTk2ZjdlZWQ0ZTg2YjY0NzUwZDdjMDk3ZjJmYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TGF3cmVuY2UgUGFyayBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85YWM1NGY4YmRjNTQ0NGEzOGZmMTcxM2RkZTVlOTc1MS5zZXRDb250ZW50KGh0bWxfN2NkZjU5NmY3ZWVkNGU4NmI2NDc1MGQ3YzA5N2YyZmIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2EwMGEzNjQxN2QyZjQzMDRiZmE5MmMyOTFlZmUyMjJiLmJpbmRQb3B1cChwb3B1cF85YWM1NGY4YmRjNTQ0NGEzOGZmMTcxM2RkZTVlOTc1MSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjk0ZTM3OGY4YWVkNGRmMjhlZGNiN2JlMDUwM2ZlMWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTE2OTQ4LCAtNzkuNDE2OTM1NTk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMDYwMTE5Y2E0MDExNDM0N2JjYmIyYjUxZmNkYzRjMGUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzU4ZDY3NDljNjEyNDQwMmQ5N2UyNDFmNWM0NTM5OTdmID0gJChgPGRpdiBpZD0iaHRtbF81OGQ2NzQ5YzYxMjQ0MDJkOTdlMjQxZjVjNDUzOTk3ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Um9zZWxhd24gQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMDYwMTE5Y2E0MDExNDM0N2JjYmIyYjUxZmNkYzRjMGUuc2V0Q29udGVudChodG1sXzU4ZDY3NDljNjEyNDQwMmQ5N2UyNDFmNWM0NTM5OTdmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82OTRlMzc4ZjhhZWQ0ZGYyOGVkY2I3YmUwNTAzZmUxYi5iaW5kUG9wdXAocG9wdXBfMDYwMTE5Y2E0MDExNDM0N2JjYmIyYjUxZmNkYzRjMGUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2E3ODk1MzhhZjY2MjRmZTdiMjE2Y2YwZTA5MjcyN2Y2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjczMTg1Mjk5OTk5OTksIC03OS40ODcyNjE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yZjRkYmFjNTU3ZmU0NTE1YjdjMzI1Y2RjZTBlZTg1MCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNGJhYTJjNTM4Mjg4NDQwOGE5MDVhM2NhNTlhZTFjMzQgPSAkKGA8ZGl2IGlkPSJodG1sXzRiYWEyYzUzODI4ODQ0MDhhOTA1YTNjYTU5YWUxYzM0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SdW5ueW1lZGUsIFRoZSBKdW5jdGlvbiBOb3J0aCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8yZjRkYmFjNTU3ZmU0NTE1YjdjMzI1Y2RjZTBlZTg1MC5zZXRDb250ZW50KGh0bWxfNGJhYTJjNTM4Mjg4NDQwOGE5MDVhM2NhNTlhZTFjMzQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2E3ODk1MzhhZjY2MjRmZTdiMjE2Y2YwZTA5MjcyN2Y2LmJpbmRQb3B1cChwb3B1cF8yZjRkYmFjNTU3ZmU0NTE1YjdjMzI1Y2RjZTBlZTg1MCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDM2MzRjYmVhZGZjNGM4ZGJiZGJkN2Q4MzZiZmU5OWQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY4NzYsIC03OS41MTgxODg0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiI2ZmMDAwMCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8xYTZlOTAwMTljZjI0M2E2YTVkYzEzNTJhZDdiNDUyNCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfM2JlZDIyYWIzYzJkNDBjM2E5Nzk5ZTNiZmM2M2I2MTQgPSAkKGA8ZGl2IGlkPSJodG1sXzNiZWQyMmFiM2MyZDQwYzNhOTc5OWUzYmZjNjNiNjE0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XZXN0b24gQ2x1c3RlciAwLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMWE2ZTkwMDE5Y2YyNDNhNmE1ZGMxMzUyYWQ3YjQ1MjQuc2V0Q29udGVudChodG1sXzNiZWQyMmFiM2MyZDQwYzNhOTc5OWUzYmZjNjNiNjE0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wMzYzNGNiZWFkZmM0YzhkYmJkYmQ3ZDgzNmJmZTk5ZC5iaW5kUG9wdXAocG9wdXBfMWE2ZTkwMDE5Y2YyNDNhNmE1ZGMxMzUyYWQ3YjQ1MjQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzkxYjUwZjliNWNmYjRlMGVhYzI5YzNkODNhZmIxMDQwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU3NDA5NiwgLTc5LjI3MzMwNDAwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2QyMGM0OTg5NjI3NjRmYjdhMDljNGI4NjY1NDY5ZWMyID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lM2MzN2UzZGFjYWM0Y2QwOTMwYzNhODU0Y2VmN2UyZSA9ICQoYDxkaXYgaWQ9Imh0bWxfZTNjMzdlM2RhY2FjNGNkMDkzMGMzYTg1NGNlZjdlMmUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvcnNldCBQYXJrLCBXZXhmb3JkIEhlaWdodHMsIFNjYXJib3JvdWdoIFRvd24gQ2VudHJlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2QyMGM0OTg5NjI3NjRmYjdhMDljNGI4NjY1NDY5ZWMyLnNldENvbnRlbnQoaHRtbF9lM2MzN2UzZGFjYWM0Y2QwOTMwYzNhODU0Y2VmN2UyZSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTFiNTBmOWI1Y2ZiNGUwZWFjMjljM2Q4M2FmYjEwNDAuYmluZFBvcHVwKHBvcHVwX2QyMGM0OTg5NjI3NjRmYjdhMDljNGI4NjY1NDY5ZWMyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84ZTMyZTUzYWU1ZmU0NTc3OTViOTlkOWM4OWVmM2M0NSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1Mjc1ODI5OTk5OTk5NiwgLTc5LjQwMDA0OTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiNmZjAwMDAiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNzNhYjlkNzYwY2U5NGIzNmI2NjUwYmM1OGEyODJkOWYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzFmODI4MDQyOTBjYTQ3YjVhYTkwNTEwNzU2OTAwZGIyID0gJChgPGRpdiBpZD0iaHRtbF8xZjgyODA0MjkwY2E0N2I1YWE5MDUxMDc1NjkwMGRiMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+WW9yayBNaWxscyBXZXN0IENsdXN0ZXIgMC4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzczYWI5ZDc2MGNlOTRiMzZiNjY1MGJjNThhMjgyZDlmLnNldENvbnRlbnQoaHRtbF8xZjgyODA0MjkwY2E0N2I1YWE5MDUxMDc1NjkwMGRiMik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOGUzMmU1M2FlNWZlNDU3Nzk1Yjk5ZDljODllZjNjNDUuYmluZFBvcHVwKHBvcHVwXzczYWI5ZDc2MGNlOTRiMzZiNjY1MGJjNThhMjgyZDlmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wMmI5NGQzYThkNDU0MmUxYTlmZTNlMTI3MmQ5YTc4YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMjc1MTEsIC03OS4zOTAxOTc1XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2JkMjBiODcyNGNmNTQ0OTdhYjY2MWY3Y2Q0ODQ4NjRjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mZWM2ZWE4ZTliZTU0ZDdlYmZlN2RmZGUzMjFlM2IxZiA9ICQoYDxkaXYgaWQ9Imh0bWxfZmVjNmVhOGU5YmU1NGQ3ZWJmZTdkZmRlMzIxZTNiMWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRhdmlzdmlsbGUgTm9ydGggQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYmQyMGI4NzI0Y2Y1NDQ5N2FiNjYxZjdjZDQ4NDg2NGMuc2V0Q29udGVudChodG1sX2ZlYzZlYThlOWJlNTRkN2ViZmU3ZGZkZTMyMWUzYjFmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wMmI5NGQzYThkNDU0MmUxYTlmZTNlMTI3MmQ5YTc4Yi5iaW5kUG9wdXAocG9wdXBfYmQyMGI4NzI0Y2Y1NDQ5N2FiNjYxZjdjZDQ4NDg2NGMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI0N2QxZTM3ZjMzNDQ4OTE5NmEyM2IwNmM1MTY0Njc1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk2OTQ3NiwgLTc5LjQxMTMwNzIwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzcxZDA4M2Q1ZmViNzQyNDBiYTkwN2ZmY2E4NDQyYzdlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8xZWM5MzA4MmE0NWQ0ZDNiYTM1ODNmMGNjMmQ4MDM5NyA9ICQoYDxkaXYgaWQ9Imh0bWxfMWVjOTMwODJhNDVkNGQzYmEzNTgzZjBjYzJkODAzOTciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZvcmVzdCBIaWxsIE5vcnRoICZhbXA7IFdlc3QsIEZvcmVzdCBIaWxsIFJvYWQgUGFyayBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83MWQwODNkNWZlYjc0MjQwYmE5MDdmZmNhODQ0MmM3ZS5zZXRDb250ZW50KGh0bWxfMWVjOTMwODJhNDVkNGQzYmEzNTgzZjBjYzJkODAzOTcpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzI0N2QxZTM3ZjMzNDQ4OTE5NmEyM2IwNmM1MTY0Njc1LmJpbmRQb3B1cChwb3B1cF83MWQwODNkNWZlYjc0MjQwYmE5MDdmZmNhODQ0MmM3ZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjFlMGFmNDkxODUxNGRiY2FiZTM0NzE0ZmU5MzE3YWMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NjE2MDgzLCAtNzkuNDY0NzYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNzU4Njg0OWRmMTllNDljYzg0ZjcxZmM4NGQyYjgzMzMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRiZTY0NzM3YWE2NjRlNDRhYmEwZmU1NmYxN2I4NjA3ID0gJChgPGRpdiBpZD0iaHRtbF80YmU2NDczN2FhNjY0ZTQ0YWJhMGZlNTZmMTdiODYwNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGlnaCBQYXJrLCBUaGUgSnVuY3Rpb24gU291dGggQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNzU4Njg0OWRmMTllNDljYzg0ZjcxZmM4NGQyYjgzMzMuc2V0Q29udGVudChodG1sXzRiZTY0NzM3YWE2NjRlNDRhYmEwZmU1NmYxN2I4NjA3KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82MWUwYWY0OTE4NTE0ZGJjYWJlMzQ3MTRmZTkzMTdhYy5iaW5kUG9wdXAocG9wdXBfNzU4Njg0OWRmMTllNDljYzg0ZjcxZmM4NGQyYjgzMzMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzEwYTAzNTAwZDg4MzQ5MDc4NzNmNWYzODNlNjU1ZGZhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk2MzE5LCAtNzkuNTMyMjQyNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNDY0NzdiMzdlOGM2NDliYjlhNjNjM2UyOGE0NzcwOTggPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2UzZDY3OGVmMzgzYTQzMWZhM2RiNmRkYzI4Y2M5ZTJkID0gJChgPGRpdiBpZD0iaHRtbF9lM2Q2NzhlZjM4M2E0MzFmYTNkYjZkZGMyOGNjOWUyZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2VzdG1vdW50IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzQ2NDc3YjM3ZThjNjQ5YmI5YTYzYzNlMjhhNDc3MDk4LnNldENvbnRlbnQoaHRtbF9lM2Q2NzhlZjM4M2E0MzFmYTNkYjZkZGMyOGNjOWUyZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMTBhMDM1MDBkODgzNDkwNzg3M2Y1ZjM4M2U2NTVkZmEuYmluZFBvcHVwKHBvcHVwXzQ2NDc3YjM3ZThjNjQ5YmI5YTYzYzNlMjhhNDc3MDk4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xNzRhNGM2ZjNhOTk0Zjg0YTE3NDNlNGQ3NWIyNjhlMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1MDA3MTUwMDAwMDAwNCwgLTc5LjI5NTg0OTFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZGQ3ZGE2MDMxM2U3NGQ0YmE3YmQ0NDQzZTY4Y2I2Y2QgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzczN2RjMGVhZDNlNzRmNjc4NzYyOTNmNTcyMmZlOTE5ID0gJChgPGRpdiBpZD0iaHRtbF83MzdkYzBlYWQzZTc0ZjY3ODc2MjkzZjU3MjJmZTkxOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2V4Zm9yZCwgTWFyeXZhbGUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZGQ3ZGE2MDMxM2U3NGQ0YmE3YmQ0NDQzZTY4Y2I2Y2Quc2V0Q29udGVudChodG1sXzczN2RjMGVhZDNlNzRmNjc4NzYyOTNmNTcyMmZlOTE5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNzRhNGM2ZjNhOTk0Zjg0YTE3NDNlNGQ3NWIyNjhlMy5iaW5kUG9wdXAocG9wdXBfZGQ3ZGE2MDMxM2U3NGQ0YmE3YmQ0NDQzZTY4Y2I2Y2QpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzNmMDI3YjZlYzUzYTQ2N2M4ZmQwNGU5YWJjNWJhOGFiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzgyNzM2NCwgLTc5LjQ0MjI1OTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZjlkNDFkOTFhYmZjNGNhMzk2OGE5YTRmMTdmOWMwYmEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRiMWE1NDg1OTA0NjRmZTk4NDAzODZmNmViNjgyYWExID0gJChgPGRpdiBpZD0iaHRtbF80YjFhNTQ4NTkwNDY0ZmU5ODQwMzg2ZjZlYjY4MmFhMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSwgV2lsbG93ZGFsZSBXZXN0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Y5ZDQxZDkxYWJmYzRjYTM5NjhhOWE0ZjE3ZjljMGJhLnNldENvbnRlbnQoaHRtbF80YjFhNTQ4NTkwNDY0ZmU5ODQwMzg2ZjZlYjY4MmFhMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfM2YwMjdiNmVjNTNhNDY3YzhmZDA0ZTlhYmM1YmE4YWIuYmluZFBvcHVwKHBvcHVwX2Y5ZDQxZDkxYWJmYzRjYTM5NjhhOWE0ZjE3ZjljMGJhKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iYTE5ZDM4ZDcyZjI0MDRkYWZhYTI1NDZlYjI2Y2U5ZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxNTM4MzQsIC03OS40MDU2Nzg0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85N2FlNTcyZTBkYjk0NWVhYTYxNGEzNmY2ZTJiNGVlYiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjUyMWUyMzZhNzAyNDUxZDk4MzEzNTg0NWVkNWNlZDQgPSAkKGA8ZGl2IGlkPSJodG1sX2I1MjFlMjM2YTcwMjQ1MWQ5ODMxMzU4NDVlZDVjZWQ0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aCBUb3JvbnRvIFdlc3QsIExhd3JlbmNlIFBhcmsgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOTdhZTU3MmUwZGI5NDVlYWE2MTRhMzZmNmUyYjRlZWIuc2V0Q29udGVudChodG1sX2I1MjFlMjM2YTcwMjQ1MWQ5ODMxMzU4NDVlZDVjZWQ0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iYTE5ZDM4ZDcyZjI0MDRkYWZhYTI1NDZlYjI2Y2U5ZC5iaW5kUG9wdXAocG9wdXBfOTdhZTU3MmUwZGI5NDVlYWE2MTRhMzZmNmUyYjRlZWIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2U5NDE2YmM2MGQyYjRmMzRhYWI3ZmQzNzY3NTFjMmMxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjcyNzA5NywgLTc5LjQwNTY3ODQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2QwY2MxNGFkNjYxMzQyNzNiNzQwNDJkM2M1NWIyNDQwID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF84MDc5NjFhOGJhNmI0ZmE5YjM3NDFlMjFiY2Q2MWEzOCA9ICQoYDxkaXYgaWQ9Imh0bWxfODA3OTYxYThiYTZiNGZhOWIzNzQxZTIxYmNkNjFhMzgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRoZSBBbm5leCwgTm9ydGggTWlkdG93biwgWW9ya3ZpbGxlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2QwY2MxNGFkNjYxMzQyNzNiNzQwNDJkM2M1NWIyNDQwLnNldENvbnRlbnQoaHRtbF84MDc5NjFhOGJhNmI0ZmE5YjM3NDFlMjFiY2Q2MWEzOCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZTk0MTZiYzYwZDJiNGYzNGFhYjdmZDM3Njc1MWMyYzEuYmluZFBvcHVwKHBvcHVwX2QwY2MxNGFkNjYxMzQyNzNiNzQwNDJkM2M1NWIyNDQwKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iNmE1MWE3YWRiYmY0ZjI4OTI2OGZiMmYzNDFjOWY4MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0ODk1OTcsIC03OS40NTYzMjVdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOThjOGU2ZjUyYmM2NDZmMzk5NzdjOGY0Njc5MWI4MzIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzg1MWU4NjdmMzE2NzQ5NDZiYjIyNWQxMDM2NzhhNTMyID0gJChgPGRpdiBpZD0iaHRtbF84NTFlODY3ZjMxNjc0OTQ2YmIyMjVkMTAzNjc4YTUzMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGFya2RhbGUsIFJvbmNlc3ZhbGxlcyBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85OGM4ZTZmNTJiYzY0NmYzOTk3N2M4ZjQ2NzkxYjgzMi5zZXRDb250ZW50KGh0bWxfODUxZTg2N2YzMTY3NDk0NmJiMjI1ZDEwMzY3OGE1MzIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2I2YTUxYTdhZGJiZjRmMjg5MjY4ZmIyZjM0MWM5ZjgxLmJpbmRQb3B1cChwb3B1cF85OGM4ZTZmNTJiYzY0NmYzOTk3N2M4ZjQ2NzkxYjgzMikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfODhhMTk1MGU5OTRlNDc0MzhjNGExYWJlNDE4ZWQwMjEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MzY5NjU2LCAtNzkuNjE1ODE4OTk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOTVlNThmMDc3MTY2NDgzMzg5MGQ4MmJmZGU5MWFmOWYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzlhYTIyMTZkMTE5ZTRjNDlhOGExN2I5MzNkOGQ2MDRiID0gJChgPGRpdiBpZD0iaHRtbF85YWEyMjE2ZDExOWU0YzQ5YThhMTdiOTMzZDhkNjA0YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2FuYWRhIFBvc3QgR2F0ZXdheSBQcm9jZXNzaW5nIENlbnRyZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85NWU1OGYwNzcxNjY0ODMzODkwZDgyYmZkZTkxYWY5Zi5zZXRDb250ZW50KGh0bWxfOWFhMjIxNmQxMTllNGM0OWE4YTE3YjkzM2Q4ZDYwNGIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzg4YTE5NTBlOTk0ZTQ3NDM4YzRhMWFiZTQxOGVkMDIxLmJpbmRQb3B1cChwb3B1cF85NWU1OGYwNzcxNjY0ODMzODkwZDgyYmZkZTkxYWY5ZikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWJhY2FhMDFmNTkwNGQ5Y2ExYjU5NGI4NzM4NGEyYzEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODg5MDU0LCAtNzkuNTU0NzI0NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZDY0NjQxNDYxZjJkNGE2ZDk3ZWRhNGM5NWNkMGNkYWIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2E1OWJiNGZlNDZiMzRjNjJiMWJhMWIwZGNkNzg2ODY1ID0gJChgPGRpdiBpZD0iaHRtbF9hNTliYjRmZTQ2YjM0YzYyYjFiYTFiMGRjZDc4Njg2NSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+S2luZ3N2aWV3IFZpbGxhZ2UsIFN0LiBQaGlsbGlwcywgTWFydGluIEdyb3ZlIEdhcmRlbnMsIFJpY2h2aWV3IEdhcmRlbnMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZDY0NjQxNDYxZjJkNGE2ZDk3ZWRhNGM5NWNkMGNkYWIuc2V0Q29udGVudChodG1sX2E1OWJiNGZlNDZiMzRjNjJiMWJhMWIwZGNkNzg2ODY1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9hYmFjYWEwMWY1OTA0ZDljYTFiNTk0Yjg3Mzg0YTJjMS5iaW5kUG9wdXAocG9wdXBfZDY0NjQxNDYxZjJkNGE2ZDk3ZWRhNGM5NWNkMGNkYWIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2UwYTk1OWRmZTg0NDQ4Y2JiM2JiYjYzZmE4MGZjMjJlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzk0MjAwMywgLTc5LjI2MjAyOTQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzUyZjRjY2Y2NzkxMDRkZDNiNzdkOGYzNDAwNjQxNGM0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8wYzlkMjAzYmRmNzg0Y2EyYThlZTY1MjFiNzQwMWY3MCA9ICQoYDxkaXYgaWQ9Imh0bWxfMGM5ZDIwM2JkZjc4NGNhMmE4ZWU2NTIxYjc0MDFmNzAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFnaW5jb3VydCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF81MmY0Y2NmNjc5MTA0ZGQzYjc3ZDhmMzQwMDY0MTRjNC5zZXRDb250ZW50KGh0bWxfMGM5ZDIwM2JkZjc4NGNhMmE4ZWU2NTIxYjc0MDFmNzApOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2UwYTk1OWRmZTg0NDQ4Y2JiM2JiYjYzZmE4MGZjMjJlLmJpbmRQb3B1cChwb3B1cF81MmY0Y2NmNjc5MTA0ZGQzYjc3ZDhmMzQwMDY0MTRjNCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjQ5OTAxYWNkOTYzNDllMDhhMjc2ZjJhOGQyODYyOTAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDQzMjQ0LCAtNzkuMzg4NzkwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zZTRiNTQ3OWY0OGU0MjRkYWU3YTUyNDBjZmIxZTI3OSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYzlkYmE4ZmRmZDgyNDkwZWI1Y2M0ZTU5YTQ2OGExMWUgPSAkKGA8ZGl2IGlkPSJodG1sX2M5ZGJhOGZkZmQ4MjQ5MGViNWNjNGU1OWE0NjhhMTFlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EYXZpc3ZpbGxlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzNlNGI1NDc5ZjQ4ZTQyNGRhZTdhNTI0MGNmYjFlMjc5LnNldENvbnRlbnQoaHRtbF9jOWRiYThmZGZkODI0OTBlYjVjYzRlNTlhNDY4YTExZSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNjQ5OTAxYWNkOTYzNDllMDhhMjc2ZjJhOGQyODYyOTAuYmluZFBvcHVwKHBvcHVwXzNlNGI1NDc5ZjQ4ZTQyNGRhZTdhNTI0MGNmYjFlMjc5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xYWYzMDY5NmViNDE0ODViODZlYmQxMGQyNjAzOWJmNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MjY5NTYsIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzgxZjQ5ZTc4ODc5YzRmOTFhNjc5NzY5YTcxOTVlMDY1ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF84NzVmZTViMzk1MGM0NTBkODVkYzljYTQ3NjkyOGRlYSA9ICQoYDxkaXYgaWQ9Imh0bWxfODc1ZmU1YjM5NTBjNDUwZDg1ZGM5Y2E0NzY5MjhkZWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlVuaXZlcnNpdHkgb2YgVG9yb250bywgSGFyYm9yZCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF84MWY0OWU3ODg3OWM0ZjkxYTY3OTc2OWE3MTk1ZTA2NS5zZXRDb250ZW50KGh0bWxfODc1ZmU1YjM5NTBjNDUwZDg1ZGM5Y2E0NzY5MjhkZWEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzFhZjMwNjk2ZWI0MTQ4NWI4NmViZDEwZDI2MDM5YmY2LmJpbmRQb3B1cChwb3B1cF84MWY0OWU3ODg3OWM0ZjkxYTY3OTc2OWE3MTk1ZTA2NSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfY2M1YTY3Zjc0MjU3NDVjMTk5Y2MwZWViNDBhMWJhOGYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTE1NzA2LCAtNzkuNDg0NDQ5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lNGFmMmM1YmI4YmY0ZDQzOGU0Y2RiYTA1NDJiNWFiYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjE2NGZkM2Q5ZmNkNDZiMWI1MGYzOTI0M2FlZGNjZTMgPSAkKGA8ZGl2IGlkPSJodG1sX2IxNjRmZDNkOWZjZDQ2YjFiNTBmMzkyNDNhZWRjY2UzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SdW5ueW1lZGUsIFN3YW5zZWEgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZTRhZjJjNWJiOGJmNGQ0MzhlNGNkYmEwNTQyYjVhYmEuc2V0Q29udGVudChodG1sX2IxNjRmZDNkOWZjZDQ2YjFiNTBmMzkyNDNhZWRjY2UzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jYzVhNjdmNzQyNTc0NWMxOTljYzBlZWI0MGExYmE4Zi5iaW5kUG9wdXAocG9wdXBfZTRhZjJjNWJiOGJmNGQ0MzhlNGNkYmEwNTQyYjVhYmEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q3MDRiNjliN2NlMzRjODE4MWQyOTk3MTMzZGNjMDAwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzgxNjM3NSwgLTc5LjMwNDMwMjFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYmJjODc0NGYwMTI1NDFmOTljYjVlMWQ2NzA1YTNiNmMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2EyNjZmODY2YWUxMDQ1MzY4ZGExMjAyODE5MjBhMDJmID0gJChgPGRpdiBpZD0iaHRtbF9hMjY2Zjg2NmFlMTA0NTM2OGRhMTIwMjgxOTIwYTAyZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2xhcmtzIENvcm5lcnMsIFRhbSBPJiMzOTtTaGFudGVyLCBTdWxsaXZhbiBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iYmM4NzQ0ZjAxMjU0MWY5OWNiNWUxZDY3MDVhM2I2Yy5zZXRDb250ZW50KGh0bWxfYTI2NmY4NjZhZTEwNDUzNjhkYTEyMDI4MTkyMGEwMmYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q3MDRiNjliN2NlMzRjODE4MWQyOTk3MTMzZGNjMDAwLmJpbmRQb3B1cChwb3B1cF9iYmM4NzQ0ZjAxMjU0MWY5OWNiNWUxZDY3MDVhM2I2YykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOTdmODNiMmU3M2ZkNDQxZGI5ZTg4ZThhNzhlMTFmMzIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODk1NzQzLCAtNzkuMzgzMTU5OTAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYmUwZDZjOGFjZmFlNGE4YzkxYTgxMWQ0OTkyYzQwMmEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzNmYjYyODMxY2EzMzRiODNhNjhjMjBlMGM0ODQ3OTRkID0gJChgPGRpdiBpZD0iaHRtbF8zZmI2MjgzMWNhMzM0YjgzYTY4YzIwZTBjNDg0Nzk0ZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TW9vcmUgUGFyaywgU3VtbWVyaGlsbCBFYXN0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2JlMGQ2YzhhY2ZhZTRhOGM5MWE4MTFkNDk5MmM0MDJhLnNldENvbnRlbnQoaHRtbF8zZmI2MjgzMWNhMzM0YjgzYTY4YzIwZTBjNDg0Nzk0ZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTdmODNiMmU3M2ZkNDQxZGI5ZTg4ZThhNzhlMTFmMzIuYmluZFBvcHVwKHBvcHVwX2JlMGQ2YzhhY2ZhZTRhOGM5MWE4MTFkNDk5MmM0MDJhKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kZjBkZmIyZjgzMmI0OGIwOTU5NDkwMjRmNzI0YzhjMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MzIwNTcsIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzcwNDQ1YTdmNDQ0YjQxNWQ4ZGQ5YzBlOWMxMDlmNzdkID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9kMzU3ZDQyZTdiNDE0N2IwOTUxY2I5NTNiMzA2ZGY4MyA9ICQoYDxkaXYgaWQ9Imh0bWxfZDM1N2Q0MmU3YjQxNDdiMDk1MWNiOTUzYjMwNmRmODMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPktlbnNpbmd0b24gTWFya2V0LCBDaGluYXRvd24sIEdyYW5nZSBQYXJrIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzcwNDQ1YTdmNDQ0YjQxNWQ4ZGQ5YzBlOWMxMDlmNzdkLnNldENvbnRlbnQoaHRtbF9kMzU3ZDQyZTdiNDE0N2IwOTUxY2I5NTNiMzA2ZGY4Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZGYwZGZiMmY4MzJiNDhiMDk1OTQ5MDI0ZjcyNGM4YzIuYmluZFBvcHVwKHBvcHVwXzcwNDQ1YTdmNDQ0YjQxNWQ4ZGQ5YzBlOWMxMDlmNzdkKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zNmZjMmM4ZGE0ZGM0YTI0YTViYTQwMjMwNmM1YjBjMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgxNTI1MjIsIC03OS4yODQ1NzcyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjZmYwMDAwIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiNmZjAwMDAiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2Q3OTdjY2FlNDE4ZDRlYjk4ZDlkNTQ5NGE1MDgyMzc0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81N2IxZDY5ZjI2ZDk0MGZjYTJlZWQwNTBjYmQ1ZGExMiA9ICQoYDxkaXYgaWQ9Imh0bWxfNTdiMWQ2OWYyNmQ5NDBmY2EyZWVkMDUwY2JkNWRhMTIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1pbGxpa2VuLCBBZ2luY291cnQgTm9ydGgsIFN0ZWVsZXMgRWFzdCwgTCYjMzk7QW1vcmVhdXggRWFzdCBDbHVzdGVyIDAuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9kNzk3Y2NhZTQxOGQ0ZWI5OGQ5ZDU0OTRhNTA4MjM3NC5zZXRDb250ZW50KGh0bWxfNTdiMWQ2OWYyNmQ5NDBmY2EyZWVkMDUwY2JkNWRhMTIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzM2ZmMyYzhkYTRkYzRhMjRhNWJhNDAyMzA2YzViMGMwLmJpbmRQb3B1cChwb3B1cF9kNzk3Y2NhZTQxOGQ0ZWI5OGQ5ZDU0OTRhNTA4MjM3NCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZmQwZTYxNGRiODQ1NGRiZmI4ODA1OGQxYmE2MDYwMmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODY0MTIyOTk5OTk5OSwgLTc5LjQwMDA0OTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTJmM2RjMmM5YzRjNDllNGFhYzViMThkZTg0MDAxNzkgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzg4ODk2OWZmMDMyNjRiYzc5MjgzZTMyNzRmNzM0ODM5ID0gJChgPGRpdiBpZD0iaHRtbF84ODg5NjlmZjAzMjY0YmM3OTI4M2UzMjc0ZjczNDgzOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3VtbWVyaGlsbCBXZXN0LCBSYXRobmVsbHksIFNvdXRoIEhpbGwsIEZvcmVzdCBIaWxsIFNFLCBEZWVyIFBhcmsgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZTJmM2RjMmM5YzRjNDllNGFhYzViMThkZTg0MDAxNzkuc2V0Q29udGVudChodG1sXzg4ODk2OWZmMDMyNjRiYzc5MjgzZTMyNzRmNzM0ODM5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9mZDBlNjE0ZGI4NDU0ZGJmYjg4MDU4ZDFiYTYwNjAyZC5iaW5kUG9wdXAocG9wdXBfZTJmM2RjMmM5YzRjNDllNGFhYzViMThkZTg0MDAxNzkpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzAwODY2Njk3ZDZmNzQxNzc5NDVjNmE5Yjk5MDQ5MjcyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4OTQ2NywgLTc5LjM5NDQxOTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYzIyYTYwZWNhYTAwNGViZTgwZjZkMTFjZDFlMjU1NmUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzI0MWIzZDFhMzUwNzQ0ZGZhMTY4OTY0NjdkZDNlMjc1ID0gJChgPGRpdiBpZD0iaHRtbF8yNDFiM2QxYTM1MDc0NGRmYTE2ODk2NDY3ZGQzZTI3NSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q04gVG93ZXIsIEtpbmcgYW5kIFNwYWRpbmEsIFJhaWx3YXkgTGFuZHMsIEhhcmJvdXJmcm9udCBXZXN0LCBCYXRodXJzdCBRdWF5LCBTb3V0aCBOaWFnYXJhLCBJc2xhbmQgYWlycG9ydCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9jMjJhNjBlY2FhMDA0ZWJlODBmNmQxMWNkMWUyNTU2ZS5zZXRDb250ZW50KGh0bWxfMjQxYjNkMWEzNTA3NDRkZmExNjg5NjQ2N2RkM2UyNzUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzAwODY2Njk3ZDZmNzQxNzc5NDVjNmE5Yjk5MDQ5MjcyLmJpbmRQb3B1cChwb3B1cF9jMjJhNjBlY2FhMDA0ZWJlODBmNmQxMWNkMWUyNTU2ZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOWU5NTVjOGM1ZGFlNDA4YmE1YTNkNGFlNTQzOGJkMjggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MDU2NDY2LCAtNzkuNTAxMzIwNzAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZDI5OWE5OTUyNjE2NDVlOWI4OGIyMjA1Zjc2NjRjZTUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzUyYzAzZGEyZThkNDRmOTFiODQ3ODcyOTYxZTMwYmVhID0gJChgPGRpdiBpZD0iaHRtbF81MmMwM2RhMmU4ZDQ0ZjkxYjg0Nzg3Mjk2MWUzMGJlYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TmV3IFRvcm9udG8sIE1pbWljbyBTb3V0aCwgSHVtYmVyIEJheSBTaG9yZXMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZDI5OWE5OTUyNjE2NDVlOWI4OGIyMjA1Zjc2NjRjZTUuc2V0Q29udGVudChodG1sXzUyYzAzZGEyZThkNDRmOTFiODQ3ODcyOTYxZTMwYmVhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85ZTk1NWM4YzVkYWU0MDhiYTVhM2Q0YWU1NDM4YmQyOC5iaW5kUG9wdXAocG9wdXBfZDI5OWE5OTUyNjE2NDVlOWI4OGIyMjA1Zjc2NjRjZTUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y4MjM1MTM0MTgxZjQwMmJhYzZiNjVjMzJlY2YyODM0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM5NDE2Mzk5OTk5OTk2LCAtNzkuNTg4NDM2OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF81YjBlNzcxN2NlZTY0MWViOTRmNjEwMjdiMTAzMWI3MiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjZkZmMxZWFjNGI4NGJmNmE3MmViYjA3MGFkOWY1MGIgPSAkKGA8ZGl2IGlkPSJodG1sX2I2ZGZjMWVhYzRiODRiZjZhNzJlYmIwNzBhZDlmNTBiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Tb3V0aCBTdGVlbGVzLCBTaWx2ZXJzdG9uZSwgSHVtYmVyZ2F0ZSwgSmFtZXN0b3duLCBNb3VudCBPbGl2ZSwgQmVhdW1vbmQgSGVpZ2h0cywgVGhpc3RsZXRvd24sIEFsYmlvbiBHYXJkZW5zIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzViMGU3NzE3Y2VlNjQxZWI5NGY2MTAyN2IxMDMxYjcyLnNldENvbnRlbnQoaHRtbF9iNmRmYzFlYWM0Yjg0YmY2YTcyZWJiMDcwYWQ5ZjUwYik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZjgyMzUxMzQxODFmNDAyYmFjNmI2NWMzMmVjZjI4MzQuYmluZFBvcHVwKHBvcHVwXzViMGU3NzE3Y2VlNjQxZWI5NGY2MTAyN2IxMDMxYjcyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yNGU1MjNiMDE2OGQ0MGIwYjQzYjE1ZjU5OTRkYTQ4YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5OTUyNTIwMDAwMDAwNSwgLTc5LjMxODM4ODddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTA1MGRiZTZlYjlhNGE4YWFhZDAyMTMyZTgxZDM5MjYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzIyZjg2YjMwN2E5MTQyY2FiYWU4M2UzOGM3MTAxZGUyID0gJChgPGRpdiBpZD0iaHRtbF8yMmY4NmIzMDdhOTE0MmNhYmFlODNlMzhjNzEwMWRlMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3RlZWxlcyBXZXN0LCBMJiMzOTtBbW9yZWF1eCBXZXN0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2UwNTBkYmU2ZWI5YTRhOGFhYWQwMjEzMmU4MWQzOTI2LnNldENvbnRlbnQoaHRtbF8yMmY4NmIzMDdhOTE0MmNhYmFlODNlMzhjNzEwMWRlMik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjRlNTIzYjAxNjhkNDBiMGI0M2IxNWY1OTk0ZGE0OGIuYmluZFBvcHVwKHBvcHVwX2UwNTBkYmU2ZWI5YTRhOGFhYWQwMjEzMmU4MWQzOTI2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kNDY2N2I0YWNkMWY0MzQxYjZiZDdkMDdiOTI4MzZkMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3OTU2MjYsIC03OS4zNzc1Mjk0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiI2ZmMDAwMCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9jNDk3MzNiZWMxNTE0NGRhODNiZjdjMzNkMDZkMjRmNiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDk4ZjFjN2EwNTVmNGU1YWEyYWEzYWVlODZhOThhYWIgPSAkKGA8ZGl2IGlkPSJodG1sXzQ5OGYxYzdhMDU1ZjRlNWFhMmFhM2FlZTg2YTk4YWFiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3NlZGFsZSBDbHVzdGVyIDAuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9jNDk3MzNiZWMxNTE0NGRhODNiZjdjMzNkMDZkMjRmNi5zZXRDb250ZW50KGh0bWxfNDk4ZjFjN2EwNTVmNGU1YWEyYWEzYWVlODZhOThhYWIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q0NjY3YjRhY2QxZjQzNDFiNmJkN2QwN2I5MjgzNmQzLmJpbmRQb3B1cChwb3B1cF9jNDk3MzNiZWMxNTE0NGRhODNiZjdjMzNkMDZkMjRmNikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZWViNGY4OGY4NTE3NGIzZTg1NGU2N2RmZDk1MjgzOTkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDY0MzUyLCAtNzkuMzc0ODQ1OTk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZWU5ODMxNTY5YzE2NGE3MmE0NDdhMjUzNmI0ZDExMWQgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzVlYTA2ODdmMzhkNDRjZDg5M2YxNTUxZWUyODY3OGEzID0gJChgPGRpdiBpZD0iaHRtbF81ZWEwNjg3ZjM4ZDQ0Y2Q4OTNmMTU1MWVlMjg2NzhhMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3RuIEEgUE8gQm94ZXMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWU5ODMxNTY5YzE2NGE3MmE0NDdhMjUzNmI0ZDExMWQuc2V0Q29udGVudChodG1sXzVlYTA2ODdmMzhkNDRjZDg5M2YxNTUxZWUyODY3OGEzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9lZWI0Zjg4Zjg1MTc0YjNlODU0ZTY3ZGZkOTUyODM5OS5iaW5kUG9wdXAocG9wdXBfZWU5ODMxNTY5YzE2NGE3MmE0NDdhMjUzNmI0ZDExMWQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q4YmY1ZDI2YjNjMTRjYWU4NDFhYTk1ZmNhYTVhYWI1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjAyNDEzNzAwMDAwMDEsIC03OS41NDM0ODQwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8wNzIwNjRlOTQxODg0YzhlODkyNzgxMzhlOGYwYTc5MiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDFmZTM1ZDU1YmI5NDE4ZDk1ODA2NTAwNTk1NzVkNDMgPSAkKGA8ZGl2IGlkPSJodG1sXzQxZmUzNWQ1NWJiOTQxOGQ5NTgwNjUwMDU5NTc1ZDQzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BbGRlcndvb2QsIExvbmcgQnJhbmNoIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzA3MjA2NGU5NDE4ODRjOGU4OTI3ODEzOGU4ZjBhNzkyLnNldENvbnRlbnQoaHRtbF80MWZlMzVkNTViYjk0MThkOTU4MDY1MDA1OTU3NWQ0Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDhiZjVkMjZiM2MxNGNhZTg0MWFhOTVmY2FhNWFhYjUuYmluZFBvcHVwKHBvcHVwXzA3MjA2NGU5NDE4ODRjOGU4OTI3ODEzOGU4ZjBhNzkyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMDIwNzY5Mzg5Njk0NDAyOTVlNjliYTU4OTBmZDdhNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNjc0ODI5OTk5OTk5NCwgLTc5LjU5NDA1NDRdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMjUxZjdiMmFmMTc2NDc4NTkyNzA4NzE5YTU2NDQ3NDggPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzlkYWM0YTk3ZTNhZDQ1YzQ5YjBiYzg3MGM5MWE1MmY0ID0gJChgPGRpdiBpZD0iaHRtbF85ZGFjNGE5N2UzYWQ0NWM0OWIwYmM4NzBjOTFhNTJmNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGh3ZXN0LCBXZXN0IEh1bWJlciAtIENsYWlydmlsbGUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMjUxZjdiMmFmMTc2NDc4NTkyNzA4NzE5YTU2NDQ3NDguc2V0Q29udGVudChodG1sXzlkYWM0YTk3ZTNhZDQ1YzQ5YjBiYzg3MGM5MWE1MmY0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iMDIwNzY5Mzg5Njk0NDAyOTVlNjliYTU4OTBmZDdhNi5iaW5kUG9wdXAocG9wdXBfMjUxZjdiMmFmMTc2NDc4NTkyNzA4NzE5YTU2NDQ3NDgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzViNmRlMGU1NDNlYzQwZTg5MjA2M2JiMDAzMDljMzEzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY3OTY3LCAtNzkuMzY3Njc1M10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF84YjNiY2VkM2ZhOTQ0Y2VhYTc2MTY2ZDhmZTk5NmNmZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZWIyM2ZiZmRkNmNiNGRmY2FkZjc5MTcyNjkyOGQ1OWUgPSAkKGA8ZGl2IGlkPSJodG1sX2ViMjNmYmZkZDZjYjRkZmNhZGY3OTE3MjY5MjhkNTllIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdC4gSmFtZXMgVG93biwgQ2FiYmFnZXRvd24gQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOGIzYmNlZDNmYTk0NGNlYWE3NjE2NmQ4ZmU5OTZjZmQuc2V0Q29udGVudChodG1sX2ViMjNmYmZkZDZjYjRkZmNhZGY3OTE3MjY5MjhkNTllKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81YjZkZTBlNTQzZWM0MGU4OTIwNjNiYjAwMzA5YzMxMy5iaW5kUG9wdXAocG9wdXBfOGIzYmNlZDNmYTk0NGNlYWE3NjE2NmQ4ZmU5OTZjZmQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI4NTk1NzdiYTUxMjRiMDE4YjRjNjA4ZDE1OTJiOTRjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4NDI5MiwgLTc5LjM4MjI4MDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNDIyYzhhMDFlMTEyNDdmY2FmNzdjZDIxZTdkNjM0NjggPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzE2Yjg2Yjk2Mjc5NDQxMWM4ZjMzMGM3Y2ZjMWYyY2Q4ID0gJChgPGRpdiBpZD0iaHRtbF8xNmI4NmI5NjI3OTQ0MTFjOGYzMzBjN2NmYzFmMmNkOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Rmlyc3QgQ2FuYWRpYW4gUGxhY2UsIFVuZGVyZ3JvdW5kIGNpdHkgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDIyYzhhMDFlMTEyNDdmY2FmNzdjZDIxZTdkNjM0Njguc2V0Q29udGVudChodG1sXzE2Yjg2Yjk2Mjc5NDQxMWM4ZjMzMGM3Y2ZjMWYyY2Q4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8yODU5NTc3YmE1MTI0YjAxOGI0YzYwOGQxNTkyYjk0Yy5iaW5kUG9wdXAocG9wdXBfNDIyYzhhMDFlMTEyNDdmY2FmNzdjZDIxZTdkNjM0NjgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzhiN2ZjYWFkN2IzZDRhN2ZiMDY0OWNhYTE2ZGJkMjYzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUzNjUzNjAwMDAwMDA1LCAtNzkuNTA2OTQzNl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80ODkxZDQ5ZWEzY2E0ZTZlOTMxNTAwMTczYjc5NjViZiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYTYwMWRiMDE2YjAzNDczOGI3ZjkzMjI5MzE4NThiM2UgPSAkKGA8ZGl2IGlkPSJodG1sX2E2MDFkYjAxNmIwMzQ3MzhiN2Y5MzIyOTMxODU4YjNlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgS2luZ3N3YXksIE1vbnRnb21lcnkgUm9hZCwgT2xkIE1pbGwgTm9ydGggQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDg5MWQ0OWVhM2NhNGU2ZTkzMTUwMDE3M2I3OTY1YmYuc2V0Q29udGVudChodG1sX2E2MDFkYjAxNmIwMzQ3MzhiN2Y5MzIyOTMxODU4YjNlKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl84YjdmY2FhZDdiM2Q0YTdmYjA2NDljYWExNmRiZDI2My5iaW5kUG9wdXAocG9wdXBfNDg5MWQ0OWVhM2NhNGU2ZTkzMTUwMDE3M2I3OTY1YmYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NjZjhhN2JkODcyYjRkNDNiZDE4OGZlMWI4MDgyNmMxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY1ODU5OSwgLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2YzMjIzOWIyNjQ1OTQ2ZTQ5ZTlhOTQ0ZDI0NjRkNjg1ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lYTJiNTY4NTg1YzM0MjE3YTMwZjFjNjZlOTYyNGMyMSA9ICQoYDxkaXYgaWQ9Imh0bWxfZWEyYjU2ODU4NWMzNDIxN2EzMGYxYzY2ZTk2MjRjMjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNodXJjaCBhbmQgV2VsbGVzbGV5IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2YzMjIzOWIyNjQ1OTQ2ZTQ5ZTlhOTQ0ZDI0NjRkNjg1LnNldENvbnRlbnQoaHRtbF9lYTJiNTY4NTg1YzM0MjE3YTMwZjFjNjZlOTYyNGMyMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfY2NmOGE3YmQ4NzJiNGQ0M2JkMTg4ZmUxYjgwODI2YzEuYmluZFBvcHVwKHBvcHVwX2YzMjIzOWIyNjQ1OTQ2ZTQ5ZTlhOTQ0ZDI0NjRkNjg1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hOTYxNWU5YzI1YWI0YzJlYmUyMjRiOTUyZjU4MTk1MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Mjc0MzksIC03OS4zMjE1NThdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYjc4ZWRlZTFiMjVlNDI0Yzk1MmE2NTVkZTk4YWJkOGYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2FjMGNmZDBmMTY5MDRkNjQ4OWRhNmY3MzE4Mjg3M2I5ID0gJChgPGRpdiBpZD0iaHRtbF9hYzBjZmQwZjE2OTA0ZDY0ODlkYTZmNzMxODI4NzNiOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnVzaW5lc3MgcmVwbHkgbWFpbCBQcm9jZXNzaW5nIENlbnRyZSwgU291dGggQ2VudHJhbCBMZXR0ZXIgUHJvY2Vzc2luZyBQbGFudCBUb3JvbnRvIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2I3OGVkZWUxYjI1ZTQyNGM5NTJhNjU1ZGU5OGFiZDhmLnNldENvbnRlbnQoaHRtbF9hYzBjZmQwZjE2OTA0ZDY0ODlkYTZmNzMxODI4NzNiOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTk2MTVlOWMyNWFiNGMyZWJlMjI0Yjk1MmY1ODE5NTEuYmluZFBvcHVwKHBvcHVwX2I3OGVkZWUxYjI1ZTQyNGM5NTJhNjU1ZGU5OGFiZDhmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YmZiOTRlOTNkNjI0MzVkYmIxMzJkNzY2MDg5ZDY1ZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjI1NzksIC03OS40OTg1MDkwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwZmZiNCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODBmZmI0IiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF81OTA2MWM4ZjI5ZGE0OTgyOTM0NDZlMjBmOTAyNDE1YSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYzhmZGUyOWQ3ODdkNDkzMDg1NWIxMWY2MmViOTk0YzIgPSAkKGA8ZGl2IGlkPSJodG1sX2M4ZmRlMjlkNzg3ZDQ5MzA4NTViMTFmNjJlYjk5NGMyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5PbGQgTWlsbCBTb3V0aCwgS2luZyYjMzk7cyBNaWxsIFBhcmssIFN1bm55bGVhLCBIdW1iZXIgQmF5LCBNaW1pY28gTkUsIFRoZSBRdWVlbnN3YXkgRWFzdCwgUm95YWwgWW9yayBTb3V0aCBFYXN0LCBLaW5nc3dheSBQYXJrIFNvdXRoIEVhc3QgQ2x1c3RlciAzLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNTkwNjFjOGYyOWRhNDk4MjkzNDQ2ZTIwZjkwMjQxNWEuc2V0Q29udGVudChodG1sX2M4ZmRlMjlkNzg3ZDQ5MzA4NTViMTFmNjJlYjk5NGMyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85YmZiOTRlOTNkNjI0MzVkYmIxMzJkNzY2MDg5ZDY1ZC5iaW5kUG9wdXAocG9wdXBfNTkwNjFjOGYyOWRhNDk4MjkzNDQ2ZTIwZjkwMjQxNWEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBjMGQyZjJiODJlMDRmNDU4ZjdlYWNlZTA4YjQ5MjgxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4ODQwOCwgLTc5LjUyMDk5OTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2VhZDJlMzA5YmIzMTQ5MzA5ZWVmZTU4MjIxMzMzY2FiID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9iYmQ0ZTllZjc1MTk0NDU3OGYyNDhlM2VlYTM3OTg2OCA9ICQoYDxkaXYgaWQ9Imh0bWxfYmJkNGU5ZWY3NTE5NDQ1NzhmMjQ4ZTNlZWEzNzk4NjgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1pbWljbyBOVywgVGhlIFF1ZWVuc3dheSBXZXN0LCBTb3V0aCBvZiBCbG9vciwgS2luZ3N3YXkgUGFyayBTb3V0aCBXZXN0LCBSb3lhbCBZb3JrIFNvdXRoIFdlc3QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWFkMmUzMDliYjMxNDkzMDllZWZlNTgyMjEzMzNjYWIuc2V0Q29udGVudChodG1sX2JiZDRlOWVmNzUxOTQ0NTc4ZjI0OGUzZWVhMzc5ODY4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wYzBkMmYyYjgyZTA0ZjQ1OGY3ZWFjZWUwOGI0OTI4MS5iaW5kUG9wdXAocG9wdXBfZWFkMmUzMDliYjMxNDkzMDllZWZlNTgyMjEzMzNjYWIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAo8L3NjcmlwdD4= onload=\"this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>" + ], + "text/plain": [ + "<folium.folium.Map at 0x1a065958388>" + ] + }, + "execution_count": 115, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import matplotlib.cm as cm\n", + "import matplotlib.colors as colors\n", + "\n", + "# create map\n", + "map_clusters = folium.Map(location=[latitude, longitude], zoom_start=11)\n", + "\n", + "# 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", + "toronto_merged_nonan = toronto_merged.dropna(subset=['Cluster Labels'])\n", + "\n", + "# add markers to the map\n", + "markers_colors = []\n", + "for lat, lon, poi, cluster in zip(toronto_merged_nonan['Latitude'], toronto_merged_nonan['Longitude'], toronto_merged_nonan['Neighbourhood'], toronto_merged_nonan['Cluster Labels']):\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[int(cluster-1)],\n", + " fill=True,\n", + " fill_color=rainbow[int(cluster-1)],\n", + " fill_opacity=0.7).add_to(map_clusters)\n", + " \n", + "map_clusters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cluster 1" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "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>Borough</th>\n", + " <th>Cluster Labels</th>\n", + " <th>1st Most Common Venue</th>\n", + " <th>2nd Most Common Venue</th>\n", + " <th>3rd Most Common Venue</th>\n", + " <th>4th Most Common Venue</th>\n", + " <th>5th Most Common Venue</th>\n", + " <th>6th Most Common Venue</th>\n", + " <th>7th Most Common Venue</th>\n", + " <th>8th Most Common Venue</th>\n", + " <th>9th Most Common Venue</th>\n", + " <th>10th Most Common Venue</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>North York</td>\n", + " <td>0.0</td>\n", + " <td>Park</td>\n", + " <td>Food & Drink Shop</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Donut Shop</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Drugstore</td>\n", + " </tr>\n", + " <tr>\n", + " <th>21</th>\n", + " <td>York</td>\n", + " <td>0.0</td>\n", + " <td>Park</td>\n", + " <td>Women's Store</td>\n", + " <td>Pool</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Dim Sum Restaurant</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " </tr>\n", + " <tr>\n", + " <th>35</th>\n", + " <td>East York</td>\n", + " <td>0.0</td>\n", + " <td>Park</td>\n", + " <td>Convenience Store</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Donut Shop</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Dumpling Restaurant</td>\n", + " </tr>\n", + " <tr>\n", + " <th>52</th>\n", + " <td>North York</td>\n", + " <td>0.0</td>\n", + " <td>Park</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Donut Shop</td>\n", + " <td>Dim Sum Restaurant</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Drugstore</td>\n", + " </tr>\n", + " <tr>\n", + " <th>64</th>\n", + " <td>York</td>\n", + " <td>0.0</td>\n", + " <td>Park</td>\n", + " <td>Convenience Store</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Donut Shop</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Dumpling Restaurant</td>\n", + " </tr>\n", + " <tr>\n", + " <th>66</th>\n", + " <td>North York</td>\n", + " <td>0.0</td>\n", + " <td>Park</td>\n", + " <td>Construction & Landscaping</td>\n", + " <td>Convenience Store</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Donut Shop</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " </tr>\n", + " <tr>\n", + " <th>85</th>\n", + " <td>Scarborough</td>\n", + " <td>0.0</td>\n", + " <td>Park</td>\n", + " <td>Playground</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Dim Sum Restaurant</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " </tr>\n", + " <tr>\n", + " <th>91</th>\n", + " <td>Downtown Toronto</td>\n", + " <td>0.0</td>\n", + " <td>Park</td>\n", + " <td>Trail</td>\n", + " <td>Playground</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Dessert Shop</td>\n", + " <td>Dim Sum Restaurant</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Borough Cluster Labels 1st Most Common Venue \\\n", + "0 North York 0.0 Park \n", + "21 York 0.0 Park \n", + "35 East York 0.0 Park \n", + "52 North York 0.0 Park \n", + "64 York 0.0 Park \n", + "66 North York 0.0 Park \n", + "85 Scarborough 0.0 Park \n", + "91 Downtown Toronto 0.0 Park \n", + "\n", + " 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n", + "0 Food & Drink Shop Yoga Studio Donut Shop \n", + "21 Women's Store Pool Yoga Studio \n", + "35 Convenience Store Yoga Studio Donut Shop \n", + "52 Yoga Studio Donut Shop Dim Sum Restaurant \n", + "64 Convenience Store Yoga Studio Donut Shop \n", + "66 Construction & Landscaping Convenience Store Yoga Studio \n", + "85 Playground Coffee Shop Yoga Studio \n", + "91 Trail Playground Yoga Studio \n", + "\n", + " 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n", + "0 Diner Discount Store Distribution Center \n", + "21 Doner Restaurant Dim Sum Restaurant Diner \n", + "35 Diner Discount Store Distribution Center \n", + "52 Diner Discount Store Distribution Center \n", + "64 Diner Discount Store Distribution Center \n", + "66 Donut Shop Diner Discount Store \n", + "85 Doner Restaurant Dim Sum Restaurant Diner \n", + "91 Dessert Shop Dim Sum Restaurant Diner \n", + "\n", + " 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n", + "0 Dog Run Doner Restaurant Drugstore \n", + "21 Discount Store Distribution Center Dog Run \n", + "35 Dog Run Doner Restaurant Dumpling Restaurant \n", + "52 Dog Run Doner Restaurant Drugstore \n", + "64 Dog Run Doner Restaurant Dumpling Restaurant \n", + "66 Distribution Center Dog Run Doner Restaurant \n", + "85 Discount Store Distribution Center Dog Run \n", + "91 Discount Store Distribution Center Dog Run " + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 0, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cluster 2" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "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>Borough</th>\n", + " <th>Cluster Labels</th>\n", + " <th>1st Most Common Venue</th>\n", + " <th>2nd Most Common Venue</th>\n", + " <th>3rd Most Common Venue</th>\n", + " <th>4th Most Common Venue</th>\n", + " <th>5th Most Common Venue</th>\n", + " <th>6th Most Common Venue</th>\n", + " <th>7th Most Common Venue</th>\n", + " <th>8th Most Common Venue</th>\n", + " <th>9th Most Common Venue</th>\n", + " <th>10th Most Common Venue</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>North York</td>\n", + " <td>1.0</td>\n", + " <td>Hockey Arena</td>\n", + " <td>Pizza Place</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Portuguese Restaurant</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Dim Sum Restaurant</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>Downtown Toronto</td>\n", + " <td>1.0</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Bakery</td>\n", + " <td>Pub</td>\n", + " <td>Park</td>\n", + " <td>Breakfast Spot</td>\n", + " <td>Café</td>\n", + " <td>Theater</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Mexican Restaurant</td>\n", + " <td>Shoe Store</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>North York</td>\n", + " <td>1.0</td>\n", + " <td>Clothing Store</td>\n", + " <td>Accessories Store</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Boutique</td>\n", + " <td>Miscellaneous Shop</td>\n", + " <td>Event Space</td>\n", + " <td>Furniture / Home Store</td>\n", + " <td>Women's Store</td>\n", + " <td>Vietnamese Restaurant</td>\n", + " <td>Convenience Store</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>Downtown Toronto</td>\n", + " <td>1.0</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Diner</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Bar</td>\n", + " <td>Beer Bar</td>\n", + " <td>Smoothie Shop</td>\n", + " <td>Sandwich Place</td>\n", + " <td>Burrito Place</td>\n", + " <td>Café</td>\n", + " <td>Park</td>\n", + " </tr>\n", + " <tr>\n", + " <th>6</th>\n", + " <td>Scarborough</td>\n", + " <td>1.0</td>\n", + " <td>Print Shop</td>\n", + " <td>Fast Food Restaurant</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Dim Sum Restaurant</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Donut Shop</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>97</th>\n", + " <td>Downtown Toronto</td>\n", + " <td>1.0</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Café</td>\n", + " <td>Hotel</td>\n", + " <td>Restaurant</td>\n", + " <td>Gym</td>\n", + " <td>Japanese Restaurant</td>\n", + " <td>American Restaurant</td>\n", + " <td>Steakhouse</td>\n", + " <td>Asian Restaurant</td>\n", + " <td>Seafood Restaurant</td>\n", + " </tr>\n", + " <tr>\n", + " <th>98</th>\n", + " <td>Etobicoke</td>\n", + " <td>1.0</td>\n", + " <td>River</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Dessert Shop</td>\n", + " <td>Dim Sum Restaurant</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Department Store</td>\n", + " </tr>\n", + " <tr>\n", + " <th>99</th>\n", + " <td>Downtown Toronto</td>\n", + " <td>1.0</td>\n", + " <td>Coffee Shop</td>\n", + " <td>Sushi Restaurant</td>\n", + " <td>Japanese Restaurant</td>\n", + " <td>Gay Bar</td>\n", + " <td>Restaurant</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Bubble Tea Shop</td>\n", + " <td>Dance Studio</td>\n", + " <td>Mediterranean Restaurant</td>\n", + " <td>Men's Store</td>\n", + " </tr>\n", + " <tr>\n", + " <th>100</th>\n", + " <td>East Toronto</td>\n", + " <td>1.0</td>\n", + " <td>Light Rail Station</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Auto Workshop</td>\n", + " <td>Smoke Shop</td>\n", + " <td>Brewery</td>\n", + " <td>Spa</td>\n", + " <td>Farmers Market</td>\n", + " <td>Fast Food Restaurant</td>\n", + " <td>Burrito Place</td>\n", + " <td>Restaurant</td>\n", + " </tr>\n", + " <tr>\n", + " <th>102</th>\n", + " <td>Etobicoke</td>\n", + " <td>1.0</td>\n", + " <td>Grocery Store</td>\n", + " <td>Tanning Salon</td>\n", + " <td>Convenience Store</td>\n", + " <td>Discount Store</td>\n", + " <td>Burrito Place</td>\n", + " <td>Burger Joint</td>\n", + " <td>Sandwich Place</td>\n", + " <td>Kids Store</td>\n", + " <td>Supplement Shop</td>\n", + " <td>Bakery</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>87 rows × 12 columns</p>\n", + "</div>" + ], + "text/plain": [ + " Borough Cluster Labels 1st Most Common Venue \\\n", + "1 North York 1.0 Hockey Arena \n", + "2 Downtown Toronto 1.0 Coffee Shop \n", + "3 North York 1.0 Clothing Store \n", + "4 Downtown Toronto 1.0 Coffee Shop \n", + "6 Scarborough 1.0 Print Shop \n", + ".. ... ... ... \n", + "97 Downtown Toronto 1.0 Coffee Shop \n", + "98 Etobicoke 1.0 River \n", + "99 Downtown Toronto 1.0 Coffee Shop \n", + "100 East Toronto 1.0 Light Rail Station \n", + "102 Etobicoke 1.0 Grocery Store \n", + "\n", + " 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n", + "1 Pizza Place Coffee Shop Portuguese Restaurant \n", + "2 Bakery Pub Park \n", + "3 Accessories Store Coffee Shop Boutique \n", + "4 Diner Yoga Studio Bar \n", + "6 Fast Food Restaurant Yoga Studio Dim Sum Restaurant \n", + ".. ... ... ... \n", + "97 Café Hotel Restaurant \n", + "98 Doner Restaurant Dessert Shop Dim Sum Restaurant \n", + "99 Sushi Restaurant Japanese Restaurant Gay Bar \n", + "100 Yoga Studio Auto Workshop Smoke Shop \n", + "102 Tanning Salon Convenience Store Discount Store \n", + "\n", + " 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n", + "1 Yoga Studio Dim Sum Restaurant Diner \n", + "2 Breakfast Spot Café Theater \n", + "3 Miscellaneous Shop Event Space Furniture / Home Store \n", + "4 Beer Bar Smoothie Shop Sandwich Place \n", + "6 Diner Discount Store Distribution Center \n", + ".. ... ... ... \n", + "97 Gym Japanese Restaurant American Restaurant \n", + "98 Diner Discount Store Distribution Center \n", + "99 Restaurant Yoga Studio Bubble Tea Shop \n", + "100 Brewery Spa Farmers Market \n", + "102 Burrito Place Burger Joint Sandwich Place \n", + "\n", + " 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n", + "1 Discount Store Distribution Center Dog Run \n", + "2 Yoga Studio Mexican Restaurant Shoe Store \n", + "3 Women's Store Vietnamese Restaurant Convenience Store \n", + "4 Burrito Place Café Park \n", + "6 Dog Run Doner Restaurant Donut Shop \n", + ".. ... ... ... \n", + "97 Steakhouse Asian Restaurant Seafood Restaurant \n", + "98 Dog Run Yoga Studio Department Store \n", + "99 Dance Studio Mediterranean Restaurant Men's Store \n", + "100 Fast Food Restaurant Burrito Place Restaurant \n", + "102 Kids Store Supplement Shop Bakery \n", + "\n", + "[87 rows x 12 columns]" + ] + }, + "execution_count": 117, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 1, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cluster 3" + ] + }, + { + "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>Borough</th>\n", + " <th>Cluster Labels</th>\n", + " <th>1st Most Common Venue</th>\n", + " <th>2nd Most Common Venue</th>\n", + " <th>3rd Most Common Venue</th>\n", + " <th>4th Most Common Venue</th>\n", + " <th>5th Most Common Venue</th>\n", + " <th>6th Most Common Venue</th>\n", + " <th>7th Most Common Venue</th>\n", + " <th>8th Most Common Venue</th>\n", + " <th>9th Most Common Venue</th>\n", + " <th>10th Most Common Venue</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>32</th>\n", + " <td>Scarborough</td>\n", + " <td>2.0</td>\n", + " <td>Pizza Place</td>\n", + " <td>Playground</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Dessert Shop</td>\n", + " <td>Dim Sum Restaurant</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Donut Shop</td>\n", + " </tr>\n", + " <tr>\n", + " <th>50</th>\n", + " <td>North York</td>\n", + " <td>2.0</td>\n", + " <td>Pizza Place</td>\n", + " <td>Department Store</td>\n", + " <td>Event Space</td>\n", + " <td>Ethiopian Restaurant</td>\n", + " <td>Electronics Store</td>\n", + " <td>Eastern European Restaurant</td>\n", + " <td>Dumpling Restaurant</td>\n", + " <td>Drugstore</td>\n", + " <td>Donut Shop</td>\n", + " <td>Doner Restaurant</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Borough Cluster Labels 1st Most Common Venue 2nd Most Common Venue \\\n", + "32 Scarborough 2.0 Pizza Place Playground \n", + "50 North York 2.0 Pizza Place Department Store \n", + "\n", + " 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n", + "32 Doner Restaurant Dessert Shop Dim Sum Restaurant \n", + "50 Event Space Ethiopian Restaurant Electronics Store \n", + "\n", + " 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n", + "32 Diner Discount Store Distribution Center \n", + "50 Eastern European Restaurant Dumpling Restaurant Drugstore \n", + "\n", + " 9th Most Common Venue 10th Most Common Venue \n", + "32 Dog Run Donut Shop \n", + "50 Donut Shop Doner Restaurant " + ] + }, + "execution_count": 118, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 2, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cluster 4" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "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>Borough</th>\n", + " <th>Cluster Labels</th>\n", + " <th>1st Most Common Venue</th>\n", + " <th>2nd Most Common Venue</th>\n", + " <th>3rd Most Common Venue</th>\n", + " <th>4th Most Common Venue</th>\n", + " <th>5th Most Common Venue</th>\n", + " <th>6th Most Common Venue</th>\n", + " <th>7th Most Common Venue</th>\n", + " <th>8th Most Common Venue</th>\n", + " <th>9th Most Common Venue</th>\n", + " <th>10th Most Common Venue</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>57</th>\n", + " <td>North York</td>\n", + " <td>3.0</td>\n", + " <td>Fabric Shop</td>\n", + " <td>Baseball Field</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Donut Shop</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Drugstore</td>\n", + " </tr>\n", + " <tr>\n", + " <th>101</th>\n", + " <td>Etobicoke</td>\n", + " <td>3.0</td>\n", + " <td>Baseball Field</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Donut Shop</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Drugstore</td>\n", + " <td>Farmers Market</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Borough Cluster Labels 1st Most Common Venue 2nd Most Common Venue \\\n", + "57 North York 3.0 Fabric Shop Baseball Field \n", + "101 Etobicoke 3.0 Baseball Field Yoga Studio \n", + "\n", + " 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n", + "57 Yoga Studio Donut Shop Diner \n", + "101 Donut Shop Diner Discount Store \n", + "\n", + " 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n", + "57 Discount Store Distribution Center Dog Run \n", + "101 Distribution Center Dog Run Doner Restaurant \n", + "\n", + " 9th Most Common Venue 10th Most Common Venue \n", + "57 Doner Restaurant Drugstore \n", + "101 Drugstore Farmers Market " + ] + }, + "execution_count": 119, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 3, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cluster 5" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "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>Borough</th>\n", + " <th>Cluster Labels</th>\n", + " <th>1st Most Common Venue</th>\n", + " <th>2nd Most Common Venue</th>\n", + " <th>3rd Most Common Venue</th>\n", + " <th>4th Most Common Venue</th>\n", + " <th>5th Most Common Venue</th>\n", + " <th>6th Most Common Venue</th>\n", + " <th>7th Most Common Venue</th>\n", + " <th>8th Most Common Venue</th>\n", + " <th>9th Most Common Venue</th>\n", + " <th>10th Most Common Venue</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>11</th>\n", + " <td>Etobicoke</td>\n", + " <td>4.0</td>\n", + " <td>Jewelry Store</td>\n", + " <td>Yoga Studio</td>\n", + " <td>Diner</td>\n", + " <td>Discount Store</td>\n", + " <td>Distribution Center</td>\n", + " <td>Dog Run</td>\n", + " <td>Doner Restaurant</td>\n", + " <td>Donut Shop</td>\n", + " <td>Drugstore</td>\n", + " <td>Farmers Market</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " Borough Cluster Labels 1st Most Common Venue 2nd Most Common Venue \\\n", + "11 Etobicoke 4.0 Jewelry Store Yoga Studio \n", + "\n", + " 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n", + "11 Diner Discount Store Distribution Center \n", + "\n", + " 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n", + "11 Dog Run Doner Restaurant Donut Shop \n", + "\n", + " 9th Most Common Venue 10th Most Common Venue \n", + "11 Drugstore Farmers Market " + ] + }, + "execution_count": 120, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 4, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]" + ] + } + ], + "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.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} |