cmc/data-science
Personal data science learning files.
clone: git clone https://gitbay.org/cmc/data-science.git
main: notebooks/Segmenting_and_Clustering_Neighbourhoods_in_Toronto.ipynb · raw
1{
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "# Segmenting and Clustering Neighbourhoods in Toronto\n",
8 "---\n",
9 "# Part 1\n",
10 "Import libraries"
11 ]
12 },
13 {
14 "cell_type": "code",
15 "execution_count": 68,
16 "metadata": {},
17 "outputs": [],
18 "source": [
19 "import pandas as pd\n",
20 "import numpy as np\n",
21 "import requests"
22 ]
23 },
24 {
25 "cell_type": "markdown",
26 "metadata": {},
27 "source": [
28 "Get the HTML page of Wikipedia and use read_html we convert the html data into list of Data frame objects.\n",
29 "\n",
30 "Remove cells which have neighbourhood as \"Not assigned.\""
31 ]
32 },
33 {
34 "cell_type": "code",
35 "execution_count": 69,
36 "metadata": {},
37 "outputs": [
38 {
39 "data": {
40 "text/html": [
41 "<div>\n",
42 "<style scoped>\n",
43 " .dataframe tbody tr th:only-of-type {\n",
44 " vertical-align: middle;\n",
45 " }\n",
46 "\n",
47 " .dataframe tbody tr th {\n",
48 " vertical-align: top;\n",
49 " }\n",
50 "\n",
51 " .dataframe thead th {\n",
52 " text-align: right;\n",
53 " }\n",
54 "</style>\n",
55 "<table border=\"1\" class=\"dataframe\">\n",
56 " <thead>\n",
57 " <tr style=\"text-align: right;\">\n",
58 " <th></th>\n",
59 " <th>Postal Code</th>\n",
60 " <th>Borough</th>\n",
61 " <th>Neighbourhood</th>\n",
62 " </tr>\n",
63 " </thead>\n",
64 " <tbody>\n",
65 " <tr>\n",
66 " <th>0</th>\n",
67 " <td>M3A</td>\n",
68 " <td>North York</td>\n",
69 " <td>Parkwoods</td>\n",
70 " </tr>\n",
71 " <tr>\n",
72 " <th>1</th>\n",
73 " <td>M4A</td>\n",
74 " <td>North York</td>\n",
75 " <td>Victoria Village</td>\n",
76 " </tr>\n",
77 " <tr>\n",
78 " <th>2</th>\n",
79 " <td>M5A</td>\n",
80 " <td>Downtown Toronto</td>\n",
81 " <td>Regent Park, Harbourfront</td>\n",
82 " </tr>\n",
83 " <tr>\n",
84 " <th>3</th>\n",
85 " <td>M6A</td>\n",
86 " <td>North York</td>\n",
87 " <td>Lawrence Manor, Lawrence Heights</td>\n",
88 " </tr>\n",
89 " <tr>\n",
90 " <th>4</th>\n",
91 " <td>M7A</td>\n",
92 " <td>Downtown Toronto</td>\n",
93 " <td>Queen's Park, Ontario Provincial Government</td>\n",
94 " </tr>\n",
95 " </tbody>\n",
96 "</table>\n",
97 "</div>"
98 ],
99 "text/plain": [
100 " Postal Code Borough Neighbourhood\n",
101 "0 M3A North York Parkwoods\n",
102 "1 M4A North York Victoria Village\n",
103 "2 M5A Downtown Toronto Regent Park, Harbourfront\n",
104 "3 M6A North York Lawrence Manor, Lawrence Heights\n",
105 "4 M7A Downtown Toronto Queen's Park, Ontario Provincial Government"
106 ]
107 },
108 "execution_count": 69,
109 "metadata": {},
110 "output_type": "execute_result"
111 }
112 ],
113 "source": [
114 "wiki = 'https://en.wikipedia.org/wiki/List_of_postal_codes_of_Canada:_M'\n",
115 "wiki_page = requests.get(wiki)\n",
116 "\n",
117 "wiki_raw = pd.read_html(wiki_page.content, header = 0)[0]\n",
118 "df = wiki_raw[wiki_raw.Neighbourhood != 'Not assigned']\n",
119 "df.reset_index(inplace=True, drop=True)\n",
120 "df.head()"
121 ]
122 },
123 {
124 "cell_type": "code",
125 "execution_count": 70,
126 "metadata": {},
127 "outputs": [
128 {
129 "data": {
130 "text/html": [
131 "<div>\n",
132 "<style scoped>\n",
133 " .dataframe tbody tr th:only-of-type {\n",
134 " vertical-align: middle;\n",
135 " }\n",
136 "\n",
137 " .dataframe tbody tr th {\n",
138 " vertical-align: top;\n",
139 " }\n",
140 "\n",
141 " .dataframe thead th {\n",
142 " text-align: right;\n",
143 " }\n",
144 "</style>\n",
145 "<table border=\"1\" class=\"dataframe\">\n",
146 " <thead>\n",
147 " <tr style=\"text-align: right;\">\n",
148 " <th></th>\n",
149 " <th>Borough</th>\n",
150 " <th>Neighbourhood</th>\n",
151 " </tr>\n",
152 " <tr>\n",
153 " <th>Postal Code</th>\n",
154 " <th></th>\n",
155 " <th></th>\n",
156 " </tr>\n",
157 " </thead>\n",
158 " <tbody>\n",
159 " <tr>\n",
160 " <th>M1B</th>\n",
161 " <td>Scarborough</td>\n",
162 " <td>Malvern, Rouge</td>\n",
163 " </tr>\n",
164 " <tr>\n",
165 " <th>M1C</th>\n",
166 " <td>Scarborough</td>\n",
167 " <td>Rouge Hill, Port Union, Highland Creek</td>\n",
168 " </tr>\n",
169 " <tr>\n",
170 " <th>M1E</th>\n",
171 " <td>Scarborough</td>\n",
172 " <td>Guildwood, Morningside, West Hill</td>\n",
173 " </tr>\n",
174 " <tr>\n",
175 " <th>M1G</th>\n",
176 " <td>Scarborough</td>\n",
177 " <td>Woburn</td>\n",
178 " </tr>\n",
179 " <tr>\n",
180 " <th>M1H</th>\n",
181 " <td>Scarborough</td>\n",
182 " <td>Cedarbrae</td>\n",
183 " </tr>\n",
184 " <tr>\n",
185 " <th>...</th>\n",
186 " <td>...</td>\n",
187 " <td>...</td>\n",
188 " </tr>\n",
189 " <tr>\n",
190 " <th>M9N</th>\n",
191 " <td>York</td>\n",
192 " <td>Weston</td>\n",
193 " </tr>\n",
194 " <tr>\n",
195 " <th>M9P</th>\n",
196 " <td>Etobicoke</td>\n",
197 " <td>Westmount</td>\n",
198 " </tr>\n",
199 " <tr>\n",
200 " <th>M9R</th>\n",
201 " <td>Etobicoke</td>\n",
202 " <td>Kingsview Village, St. Phillips, Martin Grove ...</td>\n",
203 " </tr>\n",
204 " <tr>\n",
205 " <th>M9V</th>\n",
206 " <td>Etobicoke</td>\n",
207 " <td>South Steeles, Silverstone, Humbergate, Jamest...</td>\n",
208 " </tr>\n",
209 " <tr>\n",
210 " <th>M9W</th>\n",
211 " <td>Etobicoke</td>\n",
212 " <td>Northwest, West Humber - Clairville</td>\n",
213 " </tr>\n",
214 " </tbody>\n",
215 "</table>\n",
216 "<p>103 rows × 2 columns</p>\n",
217 "</div>"
218 ],
219 "text/plain": [
220 " Borough Neighbourhood\n",
221 "Postal Code \n",
222 "M1B Scarborough Malvern, Rouge\n",
223 "M1C Scarborough Rouge Hill, Port Union, Highland Creek\n",
224 "M1E Scarborough Guildwood, Morningside, West Hill\n",
225 "M1G Scarborough Woburn\n",
226 "M1H Scarborough Cedarbrae\n",
227 "... ... ...\n",
228 "M9N York Weston\n",
229 "M9P Etobicoke Westmount\n",
230 "M9R Etobicoke Kingsview Village, St. Phillips, Martin Grove ...\n",
231 "M9V Etobicoke South Steeles, Silverstone, Humbergate, Jamest...\n",
232 "M9W Etobicoke Northwest, West Humber - Clairville\n",
233 "\n",
234 "[103 rows x 2 columns]"
235 ]
236 },
237 "execution_count": 70,
238 "metadata": {},
239 "output_type": "execute_result"
240 }
241 ],
242 "source": [
243 "df.groupby(['Postal Code']).first()"
244 ]
245 },
246 {
247 "cell_type": "code",
248 "execution_count": 71,
249 "metadata": {},
250 "outputs": [
251 {
252 "data": {
253 "text/plain": [
254 "103"
255 ]
256 },
257 "execution_count": 71,
258 "metadata": {},
259 "output_type": "execute_result"
260 }
261 ],
262 "source": [
263 "len(df['Postal Code'].unique())"
264 ]
265 },
266 {
267 "cell_type": "code",
268 "execution_count": 72,
269 "metadata": {},
270 "outputs": [
271 {
272 "data": {
273 "text/html": [
274 "<div>\n",
275 "<style scoped>\n",
276 " .dataframe tbody tr th:only-of-type {\n",
277 " vertical-align: middle;\n",
278 " }\n",
279 "\n",
280 " .dataframe tbody tr th {\n",
281 " vertical-align: top;\n",
282 " }\n",
283 "\n",
284 " .dataframe thead th {\n",
285 " text-align: right;\n",
286 " }\n",
287 "</style>\n",
288 "<table border=\"1\" class=\"dataframe\">\n",
289 " <thead>\n",
290 " <tr style=\"text-align: right;\">\n",
291 " <th></th>\n",
292 " <th>Postal Code</th>\n",
293 " <th>Borough</th>\n",
294 " <th>Neighbourhood</th>\n",
295 " </tr>\n",
296 " </thead>\n",
297 " <tbody>\n",
298 " </tbody>\n",
299 "</table>\n",
300 "</div>"
301 ],
302 "text/plain": [
303 "Empty DataFrame\n",
304 "Columns: [Postal Code, Borough, Neighbourhood]\n",
305 "Index: []"
306 ]
307 },
308 "execution_count": 72,
309 "metadata": {},
310 "output_type": "execute_result"
311 }
312 ],
313 "source": [
314 "df[df['Borough'] == 'Not assigned']"
315 ]
316 },
317 {
318 "cell_type": "code",
319 "execution_count": 73,
320 "metadata": {},
321 "outputs": [
322 {
323 "data": {
324 "text/plain": [
325 "(103, 3)"
326 ]
327 },
328 "execution_count": 73,
329 "metadata": {},
330 "output_type": "execute_result"
331 }
332 ],
333 "source": [
334 "df.shape"
335 ]
336 },
337 {
338 "cell_type": "markdown",
339 "metadata": {},
340 "source": [
341 "---\n",
342 "# Part 2"
343 ]
344 },
345 {
346 "cell_type": "code",
347 "execution_count": 74,
348 "metadata": {},
349 "outputs": [
350 {
351 "name": "stdout",
352 "output_type": "stream",
353 "text": [
354 "Requirement already satisfied: geocoder in c:\\users\\my_user\\anaconda3\\lib\\site-packages (1.38.1)\n",
355 "Requirement already satisfied: future in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (0.18.2)\n",
356 "Requirement already satisfied: ratelim in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (0.1.6)\n",
357 "Requirement already satisfied: requests in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (2.22.0)\n",
358 "Requirement already satisfied: click in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (7.0)\n",
359 "Requirement already satisfied: six in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (1.14.0)\n",
360 "Requirement already satisfied: decorator in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from ratelim->geocoder) (4.4.1)\n",
361 "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",
362 "Requirement already satisfied: idna<2.9,>=2.5 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (2.8)\n",
363 "Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (2019.11.28)\n",
364 "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",
365 "Note: you may need to restart the kernel to use updated packages.\n"
366 ]
367 }
368 ],
369 "source": [
370 "pip install geocoder"
371 ]
372 },
373 {
374 "cell_type": "code",
375 "execution_count": 75,
376 "metadata": {},
377 "outputs": [],
378 "source": [
379 "import geocoder"
380 ]
381 },
382 {
383 "cell_type": "code",
384 "execution_count": 76,
385 "metadata": {},
386 "outputs": [
387 {
388 "data": {
389 "text/html": [
390 "<div>\n",
391 "<style scoped>\n",
392 " .dataframe tbody tr th:only-of-type {\n",
393 " vertical-align: middle;\n",
394 " }\n",
395 "\n",
396 " .dataframe tbody tr th {\n",
397 " vertical-align: top;\n",
398 " }\n",
399 "\n",
400 " .dataframe thead th {\n",
401 " text-align: right;\n",
402 " }\n",
403 "</style>\n",
404 "<table border=\"1\" class=\"dataframe\">\n",
405 " <thead>\n",
406 " <tr style=\"text-align: right;\">\n",
407 " <th></th>\n",
408 " <th>Postal Code</th>\n",
409 " <th>Latitude</th>\n",
410 " <th>Longitude</th>\n",
411 " </tr>\n",
412 " </thead>\n",
413 " <tbody>\n",
414 " <tr>\n",
415 " <th>0</th>\n",
416 " <td>M1B</td>\n",
417 " <td>43.806686</td>\n",
418 " <td>-79.194353</td>\n",
419 " </tr>\n",
420 " <tr>\n",
421 " <th>1</th>\n",
422 " <td>M1C</td>\n",
423 " <td>43.784535</td>\n",
424 " <td>-79.160497</td>\n",
425 " </tr>\n",
426 " <tr>\n",
427 " <th>2</th>\n",
428 " <td>M1E</td>\n",
429 " <td>43.763573</td>\n",
430 " <td>-79.188711</td>\n",
431 " </tr>\n",
432 " <tr>\n",
433 " <th>3</th>\n",
434 " <td>M1G</td>\n",
435 " <td>43.770992</td>\n",
436 " <td>-79.216917</td>\n",
437 " </tr>\n",
438 " <tr>\n",
439 " <th>4</th>\n",
440 " <td>M1H</td>\n",
441 " <td>43.773136</td>\n",
442 " <td>-79.239476</td>\n",
443 " </tr>\n",
444 " </tbody>\n",
445 "</table>\n",
446 "</div>"
447 ],
448 "text/plain": [
449 " Postal Code Latitude Longitude\n",
450 "0 M1B 43.806686 -79.194353\n",
451 "1 M1C 43.784535 -79.160497\n",
452 "2 M1E 43.763573 -79.188711\n",
453 "3 M1G 43.770992 -79.216917\n",
454 "4 M1H 43.773136 -79.239476"
455 ]
456 },
457 "execution_count": 76,
458 "metadata": {},
459 "output_type": "execute_result"
460 }
461 ],
462 "source": [
463 "url = 'http://cocl.us/Geospatial_data'\n",
464 "df_geo = pd.read_csv(url)\n",
465 "df_geo.head()"
466 ]
467 },
468 {
469 "cell_type": "code",
470 "execution_count": 77,
471 "metadata": {},
472 "outputs": [
473 {
474 "data": {
475 "text/plain": [
476 "Postal Code object\n",
477 "Latitude float64\n",
478 "Longitude float64\n",
479 "dtype: object"
480 ]
481 },
482 "execution_count": 77,
483 "metadata": {},
484 "output_type": "execute_result"
485 }
486 ],
487 "source": [
488 "df_geo.dtypes"
489 ]
490 },
491 {
492 "cell_type": "code",
493 "execution_count": 78,
494 "metadata": {},
495 "outputs": [
496 {
497 "data": {
498 "text/plain": [
499 "Postal Code object\n",
500 "Borough object\n",
501 "Neighbourhood object\n",
502 "dtype: object"
503 ]
504 },
505 "execution_count": 78,
506 "metadata": {},
507 "output_type": "execute_result"
508 }
509 ],
510 "source": [
511 "df.dtypes"
512 ]
513 },
514 {
515 "cell_type": "code",
516 "execution_count": 79,
517 "metadata": {},
518 "outputs": [
519 {
520 "data": {
521 "text/plain": [
522 "(103, 3)"
523 ]
524 },
525 "execution_count": 79,
526 "metadata": {},
527 "output_type": "execute_result"
528 }
529 ],
530 "source": [
531 "df.shape"
532 ]
533 },
534 {
535 "cell_type": "code",
536 "execution_count": 80,
537 "metadata": {},
538 "outputs": [
539 {
540 "data": {
541 "text/plain": [
542 "(103, 3)"
543 ]
544 },
545 "execution_count": 80,
546 "metadata": {},
547 "output_type": "execute_result"
548 }
549 ],
550 "source": [
551 "df_geo.shape"
552 ]
553 },
554 {
555 "cell_type": "code",
556 "execution_count": 81,
557 "metadata": {},
558 "outputs": [
559 {
560 "data": {
561 "text/html": [
562 "<div>\n",
563 "<style scoped>\n",
564 " .dataframe tbody tr th:only-of-type {\n",
565 " vertical-align: middle;\n",
566 " }\n",
567 "\n",
568 " .dataframe tbody tr th {\n",
569 " vertical-align: top;\n",
570 " }\n",
571 "\n",
572 " .dataframe thead th {\n",
573 " text-align: right;\n",
574 " }\n",
575 "</style>\n",
576 "<table border=\"1\" class=\"dataframe\">\n",
577 " <thead>\n",
578 " <tr style=\"text-align: right;\">\n",
579 " <th></th>\n",
580 " <th>Postal Code</th>\n",
581 " <th>Borough</th>\n",
582 " <th>Neighbourhood</th>\n",
583 " <th>Latitude</th>\n",
584 " <th>Longitude</th>\n",
585 " </tr>\n",
586 " </thead>\n",
587 " <tbody>\n",
588 " <tr>\n",
589 " <th>0</th>\n",
590 " <td>M3A</td>\n",
591 " <td>North York</td>\n",
592 " <td>Parkwoods</td>\n",
593 " <td>43.753259</td>\n",
594 " <td>-79.329656</td>\n",
595 " </tr>\n",
596 " <tr>\n",
597 " <th>1</th>\n",
598 " <td>M4A</td>\n",
599 " <td>North York</td>\n",
600 " <td>Victoria Village</td>\n",
601 " <td>43.725882</td>\n",
602 " <td>-79.315572</td>\n",
603 " </tr>\n",
604 " <tr>\n",
605 " <th>2</th>\n",
606 " <td>M5A</td>\n",
607 " <td>Downtown Toronto</td>\n",
608 " <td>Regent Park, Harbourfront</td>\n",
609 " <td>43.654260</td>\n",
610 " <td>-79.360636</td>\n",
611 " </tr>\n",
612 " <tr>\n",
613 " <th>3</th>\n",
614 " <td>M6A</td>\n",
615 " <td>North York</td>\n",
616 " <td>Lawrence Manor, Lawrence Heights</td>\n",
617 " <td>43.718518</td>\n",
618 " <td>-79.464763</td>\n",
619 " </tr>\n",
620 " <tr>\n",
621 " <th>4</th>\n",
622 " <td>M7A</td>\n",
623 " <td>Downtown Toronto</td>\n",
624 " <td>Queen's Park, Ontario Provincial Government</td>\n",
625 " <td>43.662301</td>\n",
626 " <td>-79.389494</td>\n",
627 " </tr>\n",
628 " <tr>\n",
629 " <th>5</th>\n",
630 " <td>M9A</td>\n",
631 " <td>Etobicoke</td>\n",
632 " <td>Islington Avenue, Humber Valley Village</td>\n",
633 " <td>43.667856</td>\n",
634 " <td>-79.532242</td>\n",
635 " </tr>\n",
636 " <tr>\n",
637 " <th>6</th>\n",
638 " <td>M1B</td>\n",
639 " <td>Scarborough</td>\n",
640 " <td>Malvern, Rouge</td>\n",
641 " <td>43.806686</td>\n",
642 " <td>-79.194353</td>\n",
643 " </tr>\n",
644 " <tr>\n",
645 " <th>7</th>\n",
646 " <td>M3B</td>\n",
647 " <td>North York</td>\n",
648 " <td>Don Mills</td>\n",
649 " <td>43.745906</td>\n",
650 " <td>-79.352188</td>\n",
651 " </tr>\n",
652 " <tr>\n",
653 " <th>8</th>\n",
654 " <td>M4B</td>\n",
655 " <td>East York</td>\n",
656 " <td>Parkview Hill, Woodbine Gardens</td>\n",
657 " <td>43.706397</td>\n",
658 " <td>-79.309937</td>\n",
659 " </tr>\n",
660 " <tr>\n",
661 " <th>9</th>\n",
662 " <td>M5B</td>\n",
663 " <td>Downtown Toronto</td>\n",
664 " <td>Garden District, Ryerson</td>\n",
665 " <td>43.657162</td>\n",
666 " <td>-79.378937</td>\n",
667 " </tr>\n",
668 " <tr>\n",
669 " <th>10</th>\n",
670 " <td>M6B</td>\n",
671 " <td>North York</td>\n",
672 " <td>Glencairn</td>\n",
673 " <td>43.709577</td>\n",
674 " <td>-79.445073</td>\n",
675 " </tr>\n",
676 " <tr>\n",
677 " <th>11</th>\n",
678 " <td>M9B</td>\n",
679 " <td>Etobicoke</td>\n",
680 " <td>West Deane Park, Princess Gardens, Martin Grov...</td>\n",
681 " <td>43.650943</td>\n",
682 " <td>-79.554724</td>\n",
683 " </tr>\n",
684 " </tbody>\n",
685 "</table>\n",
686 "</div>"
687 ],
688 "text/plain": [
689 " Postal Code Borough \\\n",
690 "0 M3A North York \n",
691 "1 M4A North York \n",
692 "2 M5A Downtown Toronto \n",
693 "3 M6A North York \n",
694 "4 M7A Downtown Toronto \n",
695 "5 M9A Etobicoke \n",
696 "6 M1B Scarborough \n",
697 "7 M3B North York \n",
698 "8 M4B East York \n",
699 "9 M5B Downtown Toronto \n",
700 "10 M6B North York \n",
701 "11 M9B Etobicoke \n",
702 "\n",
703 " Neighbourhood Latitude Longitude \n",
704 "0 Parkwoods 43.753259 -79.329656 \n",
705 "1 Victoria Village 43.725882 -79.315572 \n",
706 "2 Regent Park, Harbourfront 43.654260 -79.360636 \n",
707 "3 Lawrence Manor, Lawrence Heights 43.718518 -79.464763 \n",
708 "4 Queen's Park, Ontario Provincial Government 43.662301 -79.389494 \n",
709 "5 Islington Avenue, Humber Valley Village 43.667856 -79.532242 \n",
710 "6 Malvern, Rouge 43.806686 -79.194353 \n",
711 "7 Don Mills 43.745906 -79.352188 \n",
712 "8 Parkview Hill, Woodbine Gardens 43.706397 -79.309937 \n",
713 "9 Garden District, Ryerson 43.657162 -79.378937 \n",
714 "10 Glencairn 43.709577 -79.445073 \n",
715 "11 West Deane Park, Princess Gardens, Martin Grov... 43.650943 -79.554724 "
716 ]
717 },
718 "execution_count": 81,
719 "metadata": {},
720 "output_type": "execute_result"
721 }
722 ],
723 "source": [
724 "df = df.join(df_geo.set_index('Postal Code'), on='Postal Code')\n",
725 "df.head(12)"
726 ]
727 },
728 {
729 "cell_type": "code",
730 "execution_count": 82,
731 "metadata": {},
732 "outputs": [
733 {
734 "data": {
735 "text/plain": [
736 "(103, 5)"
737 ]
738 },
739 "execution_count": 82,
740 "metadata": {},
741 "output_type": "execute_result"
742 }
743 ],
744 "source": [
745 "df.shape"
746 ]
747 },
748 {
749 "cell_type": "markdown",
750 "metadata": {},
751 "source": [
752 "---\n",
753 "# Part 3\n",
754 "Using the foursquere API to segment and cluster the neighborhoods of Toronto"
755 ]
756 },
757 {
758 "cell_type": "code",
759 "execution_count": 85,
760 "metadata": {},
761 "outputs": [
762 {
763 "name": "stdout",
764 "output_type": "stream",
765 "text": [
766 "Collecting package metadata (current_repodata.json): ...working... done\n",
767 "Solving environment: ...working... done\n",
768 "\n",
769 "# All requested packages already installed.\n",
770 "\n",
771 "Collecting geopy\n",
772 " Downloading geopy-2.0.0-py3-none-any.whl (111 kB)\n",
773 "Collecting geographiclib<2,>=1.49\n",
774 " Downloading geographiclib-1.50-py3-none-any.whl (38 kB)\n",
775 "Installing collected packages: geographiclib, geopy\n",
776 "Successfully installed geographiclib-1.50 geopy-2.0.0\n",
777 "The geograpical coordinate of Toronto are 43.6534817, -79.3839347.\n"
778 ]
779 }
780 ],
781 "source": [
782 "!conda install -c conda-forge geocoder --yes\n",
783 "import geocoder\n",
784 "!pip install geopy\n",
785 "from geopy.geocoders import Nominatim \n",
786 "\n",
787 "address = 'Toronto, Ontario'\n",
788 "\n",
789 "geolocator = Nominatim(user_agent=\"toronto_explorer\")\n",
790 "location = geolocator.geocode(address)\n",
791 "latitude = location.latitude\n",
792 "longitude = location.longitude\n",
793 "print('The geograpical coordinate of Toronto are {}, {}.'.format(latitude, longitude))"
794 ]
795 },
796 {
797 "cell_type": "markdown",
798 "metadata": {},
799 "source": [
800 "Printing the map"
801 ]
802 },
803 {
804 "cell_type": "code",
805 "execution_count": 89,
806 "metadata": {},
807 "outputs": [
808 {
809 "data": {
810 "text/html": [
811 "<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>"
812 ],
813 "text/plain": [
814 "<folium.folium.Map at 0x1a0657a4808>"
815 ]
816 },
817 "execution_count": 89,
818 "metadata": {},
819 "output_type": "execute_result"
820 }
821 ],
822 "source": [
823 "import folium\n",
824 "\n",
825 "# create map of Toronto using latitude and longitude values\n",
826 "map_Toronto = folium.Map(location=[latitude, longitude], zoom_start=10)\n",
827 "\n",
828 "# add markers to map\n",
829 "for lat, lng, borough, neighborhood in zip(df['Latitude'], df['Longitude'], df['Borough'], df['Neighbourhood']):\n",
830 " label = '{}, {}'.format(neighborhood, borough)\n",
831 " label = folium.Popup(label, parse_html=True)\n",
832 " folium.CircleMarker(\n",
833 " [lat, lng],\n",
834 " radius=5,\n",
835 " popup=label,\n",
836 " color='blue',\n",
837 " fill=True,\n",
838 " fill_color='#3186cc',\n",
839 " fill_opacity=0.7,\n",
840 " ).add_to(map_Toronto) \n",
841 " \n",
842 "map_Toronto"
843 ]
844 },
845 {
846 "cell_type": "markdown",
847 "metadata": {},
848 "source": [
849 "Define Foursquare parameters"
850 ]
851 },
852 {
853 "cell_type": "code",
854 "execution_count": 90,
855 "metadata": {},
856 "outputs": [],
857 "source": [
858 "CLIENT_ID = 'MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN'\n",
859 "CLIENT_SECRET = 'YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ'"
860 ]
861 },
862 {
863 "cell_type": "code",
864 "execution_count": 91,
865 "metadata": {},
866 "outputs": [
867 {
868 "name": "stdout",
869 "output_type": "stream",
870 "text": [
871 "Your credentails:\n",
872 "CLIENT_ID: MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN\n",
873 "CLIENT_SECRET:YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ\n"
874 ]
875 }
876 ],
877 "source": [
878 "VERSION = '20180604' # Foursquare API version\n",
879 "\n",
880 "print('Your credentails:')\n",
881 "print('CLIENT_ID: ' + CLIENT_ID)\n",
882 "print('CLIENT_SECRET:' + CLIENT_SECRET)"
883 ]
884 },
885 {
886 "cell_type": "markdown",
887 "metadata": {},
888 "source": [
889 "Explore the data, and get the venues in 500 meters range from our first entry"
890 ]
891 },
892 {
893 "cell_type": "code",
894 "execution_count": 93,
895 "metadata": {},
896 "outputs": [
897 {
898 "name": "stdout",
899 "output_type": "stream",
900 "text": [
901 "Latitude and longitude values of Parkwoods are 43.7532586, -79.3296565.\n"
902 ]
903 }
904 ],
905 "source": [
906 "neighborhood_latitude = df.loc[0, 'Latitude'] # neighborhood latitude value\n",
907 "neighborhood_longitude = df.loc[0, 'Longitude'] # neighborhood longitude value\n",
908 "\n",
909 "neighborhood_name = df.loc[0, 'Neighbourhood'] # neighborhood name\n",
910 "\n",
911 "print('Latitude and longitude values of {} are {}, {}.'.format(neighborhood_name, \n",
912 " neighborhood_latitude, \n",
913 " neighborhood_longitude))"
914 ]
915 },
916 {
917 "cell_type": "markdown",
918 "metadata": {},
919 "source": [
920 "Create the GET request URL"
921 ]
922 },
923 {
924 "cell_type": "code",
925 "execution_count": 94,
926 "metadata": {},
927 "outputs": [
928 {
929 "data": {
930 "text/plain": [
931 "'https://api.foursquare.com/v2/venues/explore?&client_id=MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN&client_secret=YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ&v=20180604&ll=43.7532586,-79.3296565&radius=500&limit=100'"
932 ]
933 },
934 "execution_count": 94,
935 "metadata": {},
936 "output_type": "execute_result"
937 }
938 ],
939 "source": [
940 "LIMIT = 100\n",
941 "radius = 500\n",
942 "url = 'https://api.foursquare.com/v2/venues/explore?&client_id={}&client_secret={}&v={}&ll={},{}&radius={}&limit={}'.format(\n",
943 " CLIENT_ID, \n",
944 " CLIENT_SECRET, \n",
945 " VERSION, \n",
946 " neighborhood_latitude, \n",
947 " neighborhood_longitude, \n",
948 " radius, \n",
949 " LIMIT)\n",
950 "url"
951 ]
952 },
953 {
954 "cell_type": "code",
955 "execution_count": 95,
956 "metadata": {},
957 "outputs": [
958 {
959 "data": {
960 "text/plain": [
961 "{'meta': {'code': 200, 'requestId': '5f1dab2fb0d9d01cac2a7fbc'},\n",
962 " '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",
963 " 'headerLocation': 'Parkwoods - Donalda',\n",
964 " 'headerFullLocation': 'Parkwoods - Donalda, Toronto',\n",
965 " 'headerLocationGranularity': 'neighborhood',\n",
966 " 'totalResults': 2,\n",
967 " 'suggestedBounds': {'ne': {'lat': 43.757758604500005,\n",
968 " 'lng': -79.32343823984928},\n",
969 " 'sw': {'lat': 43.7487585955, 'lng': -79.33587476015072}},\n",
970 " 'groups': [{'type': 'Recommended Places',\n",
971 " 'name': 'recommended',\n",
972 " 'items': [{'reasons': {'count': 0,\n",
973 " 'items': [{'summary': 'This spot is popular',\n",
974 " 'type': 'general',\n",
975 " 'reasonName': 'globalInteractionReason'}]},\n",
976 " 'venue': {'id': '4e8d9dcdd5fbbbb6b3003c7b',\n",
977 " 'name': 'Brookbanks Park',\n",
978 " 'location': {'address': 'Toronto',\n",
979 " 'lat': 43.751976046055574,\n",
980 " 'lng': -79.33214044722958,\n",
981 " 'labeledLatLngs': [{'label': 'display',\n",
982 " 'lat': 43.751976046055574,\n",
983 " 'lng': -79.33214044722958}],\n",
984 " 'distance': 245,\n",
985 " 'cc': 'CA',\n",
986 " 'city': 'Toronto',\n",
987 " 'state': 'ON',\n",
988 " 'country': 'Canada',\n",
989 " 'formattedAddress': ['Toronto', 'Toronto ON', 'Canada']},\n",
990 " 'categories': [{'id': '4bf58dd8d48988d163941735',\n",
991 " 'name': 'Park',\n",
992 " 'pluralName': 'Parks',\n",
993 " 'shortName': 'Park',\n",
994 " 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/parks_outdoors/park_',\n",
995 " 'suffix': '.png'},\n",
996 " 'primary': True}],\n",
997 " 'photos': {'count': 0, 'groups': []}},\n",
998 " 'referralId': 'e-0-4e8d9dcdd5fbbbb6b3003c7b-0'},\n",
999 " {'reasons': {'count': 0,\n",
1000 " 'items': [{'summary': 'This spot is popular',\n",
1001 " 'type': 'general',\n",
1002 " 'reasonName': 'globalInteractionReason'}]},\n",
1003 " 'venue': {'id': '4cb11e2075ebb60cd1c4caad',\n",
1004 " 'name': 'Variety Store',\n",
1005 " 'location': {'address': '29 Valley Woods Road',\n",
1006 " 'lat': 43.75197441585782,\n",
1007 " 'lng': -79.33311418516017,\n",
1008 " 'labeledLatLngs': [{'label': 'display',\n",
1009 " 'lat': 43.75197441585782,\n",
1010 " 'lng': -79.33311418516017}],\n",
1011 " 'distance': 312,\n",
1012 " 'cc': 'CA',\n",
1013 " 'city': 'Toronto',\n",
1014 " 'state': 'ON',\n",
1015 " 'country': 'Canada',\n",
1016 " 'formattedAddress': ['29 Valley Woods Road', 'Toronto ON', 'Canada']},\n",
1017 " 'categories': [{'id': '4bf58dd8d48988d1f9941735',\n",
1018 " 'name': 'Food & Drink Shop',\n",
1019 " 'pluralName': 'Food & Drink Shops',\n",
1020 " 'shortName': 'Food & Drink',\n",
1021 " 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/shops/foodanddrink_',\n",
1022 " 'suffix': '.png'},\n",
1023 " 'primary': True}],\n",
1024 " 'photos': {'count': 0, 'groups': []}},\n",
1025 " 'referralId': 'e-0-4cb11e2075ebb60cd1c4caad-1'}]}]}}"
1026 ]
1027 },
1028 "execution_count": 95,
1029 "metadata": {},
1030 "output_type": "execute_result"
1031 }
1032 ],
1033 "source": [
1034 "results = requests.get(url).json()\n",
1035 "results"
1036 ]
1037 },
1038 {
1039 "cell_type": "code",
1040 "execution_count": 96,
1041 "metadata": {},
1042 "outputs": [],
1043 "source": [
1044 "# function that extracts the category of the venue\n",
1045 "def get_category_type(row):\n",
1046 " try:\n",
1047 " categories_list = row['categories']\n",
1048 " except:\n",
1049 " categories_list = row['venue.categories']\n",
1050 " \n",
1051 " if len(categories_list) == 0:\n",
1052 " return None\n",
1053 " else:\n",
1054 " return categories_list[0]['name']"
1055 ]
1056 },
1057 {
1058 "cell_type": "code",
1059 "execution_count": 97,
1060 "metadata": {},
1061 "outputs": [
1062 {
1063 "name": "stderr",
1064 "output_type": "stream",
1065 "text": [
1066 "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",
1067 " \n"
1068 ]
1069 },
1070 {
1071 "data": {
1072 "text/html": [
1073 "<div>\n",
1074 "<style scoped>\n",
1075 " .dataframe tbody tr th:only-of-type {\n",
1076 " vertical-align: middle;\n",
1077 " }\n",
1078 "\n",
1079 " .dataframe tbody tr th {\n",
1080 " vertical-align: top;\n",
1081 " }\n",
1082 "\n",
1083 " .dataframe thead th {\n",
1084 " text-align: right;\n",
1085 " }\n",
1086 "</style>\n",
1087 "<table border=\"1\" class=\"dataframe\">\n",
1088 " <thead>\n",
1089 " <tr style=\"text-align: right;\">\n",
1090 " <th></th>\n",
1091 " <th>name</th>\n",
1092 " <th>categories</th>\n",
1093 " <th>lat</th>\n",
1094 " <th>lng</th>\n",
1095 " </tr>\n",
1096 " </thead>\n",
1097 " <tbody>\n",
1098 " <tr>\n",
1099 " <th>0</th>\n",
1100 " <td>Brookbanks Park</td>\n",
1101 " <td>Park</td>\n",
1102 " <td>43.751976</td>\n",
1103 " <td>-79.332140</td>\n",
1104 " </tr>\n",
1105 " <tr>\n",
1106 " <th>1</th>\n",
1107 " <td>Variety Store</td>\n",
1108 " <td>Food & Drink Shop</td>\n",
1109 " <td>43.751974</td>\n",
1110 " <td>-79.333114</td>\n",
1111 " </tr>\n",
1112 " </tbody>\n",
1113 "</table>\n",
1114 "</div>"
1115 ],
1116 "text/plain": [
1117 " name categories lat lng\n",
1118 "0 Brookbanks Park Park 43.751976 -79.332140\n",
1119 "1 Variety Store Food & Drink Shop 43.751974 -79.333114"
1120 ]
1121 },
1122 "execution_count": 97,
1123 "metadata": {},
1124 "output_type": "execute_result"
1125 }
1126 ],
1127 "source": [
1128 "import json\n",
1129 "from pandas.io.json import json_normalize\n",
1130 "\n",
1131 "venues = results['response']['groups'][0]['items']\n",
1132 " \n",
1133 "nearby_venues = json_normalize(venues) # flatten JSON\n",
1134 "\n",
1135 "# filter columns\n",
1136 "filtered_columns = ['venue.name', 'venue.categories', 'venue.location.lat', 'venue.location.lng']\n",
1137 "nearby_venues =nearby_venues.loc[:, filtered_columns]\n",
1138 "\n",
1139 "# filter the category for each row\n",
1140 "nearby_venues['venue.categories'] = nearby_venues.apply(get_category_type, axis=1)\n",
1141 "\n",
1142 "# clean columns\n",
1143 "nearby_venues.columns = [col.split(\".\")[-1] for col in nearby_venues.columns]\n",
1144 "\n",
1145 "nearby_venues.head()"
1146 ]
1147 },
1148 {
1149 "cell_type": "markdown",
1150 "metadata": {},
1151 "source": [
1152 "Generalize to obtain the venues from all neighbourhoods in Toronto"
1153 ]
1154 },
1155 {
1156 "cell_type": "code",
1157 "execution_count": 98,
1158 "metadata": {},
1159 "outputs": [],
1160 "source": [
1161 "def getNearbyVenues(names, latitudes, longitudes, radius=500):\n",
1162 " \n",
1163 " venues_list=[]\n",
1164 " for name, lat, lng in zip(names, latitudes, longitudes):\n",
1165 " print(name)\n",
1166 " \n",
1167 " # create the API request URL\n",
1168 " url = 'https://api.foursquare.com/v2/venues/explore?&client_id={}&client_secret={}&v={}&ll={},{}&radius={}&limit={}'.format(\n",
1169 " CLIENT_ID, \n",
1170 " CLIENT_SECRET, \n",
1171 " VERSION, \n",
1172 " lat, \n",
1173 " lng, \n",
1174 " radius, \n",
1175 " LIMIT)\n",
1176 " \n",
1177 " # make the GET request\n",
1178 " results = requests.get(url).json()[\"response\"]['groups'][0]['items']\n",
1179 " \n",
1180 " # return only relevant information for each nearby venue\n",
1181 " venues_list.append([(\n",
1182 " name, \n",
1183 " lat, \n",
1184 " lng, \n",
1185 " v['venue']['name'], \n",
1186 " v['venue']['location']['lat'], \n",
1187 " v['venue']['location']['lng'], \n",
1188 " v['venue']['categories'][0]['name']) for v in results])\n",
1189 "\n",
1190 " nearby_venues = pd.DataFrame([item for venue_list in venues_list for item in venue_list])\n",
1191 " nearby_venues.columns = ['Neighbourhood', \n",
1192 " 'Neighborhood Latitude', \n",
1193 " 'Neighborhood Longitude', \n",
1194 " 'Venue', \n",
1195 " 'Venue Latitude', \n",
1196 " 'Venue Longitude', \n",
1197 " 'Venue Category']\n",
1198 " \n",
1199 " return(nearby_venues)"
1200 ]
1201 },
1202 {
1203 "cell_type": "code",
1204 "execution_count": 100,
1205 "metadata": {},
1206 "outputs": [
1207 {
1208 "name": "stdout",
1209 "output_type": "stream",
1210 "text": [
1211 "Parkwoods\n",
1212 "Victoria Village\n",
1213 "Regent Park, Harbourfront\n",
1214 "Lawrence Manor, Lawrence Heights\n",
1215 "Queen's Park, Ontario Provincial Government\n",
1216 "Islington Avenue, Humber Valley Village\n",
1217 "Malvern, Rouge\n",
1218 "Don Mills\n",
1219 "Parkview Hill, Woodbine Gardens\n",
1220 "Garden District, Ryerson\n",
1221 "Glencairn\n",
1222 "West Deane Park, Princess Gardens, Martin Grove, Islington, Cloverdale\n",
1223 "Rouge Hill, Port Union, Highland Creek\n",
1224 "Don Mills\n",
1225 "Woodbine Heights\n",
1226 "St. James Town\n",
1227 "Humewood-Cedarvale\n",
1228 "Eringate, Bloordale Gardens, Old Burnhamthorpe, Markland Wood\n",
1229 "Guildwood, Morningside, West Hill\n",
1230 "The Beaches\n",
1231 "Berczy Park\n",
1232 "Caledonia-Fairbanks\n",
1233 "Woburn\n",
1234 "Leaside\n",
1235 "Central Bay Street\n",
1236 "my_usertie\n",
1237 "Cedarbrae\n",
1238 "Hillcrest Village\n",
1239 "Bathurst Manor, Wilson Heights, Downsview North\n",
1240 "Thorncliffe Park\n",
1241 "Richmond, Adelaide, King\n",
1242 "Dufferin, Dovercourt Village\n",
1243 "Scarborough Village\n",
1244 "Fairview, Henry Farm, Oriole\n",
1245 "Northwood Park, York University\n",
1246 "East Toronto, Broadview North (Old East York)\n",
1247 "Harbourfront East, Union Station, Toronto Islands\n",
1248 "Little Portugal, Trinity\n",
1249 "Kennedy Park, Ionview, East Birchmount Park\n",
1250 "Bayview Village\n",
1251 "Downsview\n",
1252 "The Danforth West, Riverdale\n",
1253 "Toronto Dominion Centre, Design Exchange\n",
1254 "Brockton, Parkdale Village, Exhibition Place\n",
1255 "Golden Mile, Clairlea, Oakridge\n",
1256 "York Mills, Silver Hills\n",
1257 "Downsview\n",
1258 "India Bazaar, The Beaches West\n",
1259 "Commerce Court, Victoria Hotel\n",
1260 "North Park, Maple Leaf Park, Upwood Park\n",
1261 "Humber Summit\n",
1262 "Cliffside, Cliffcrest, Scarborough Village West\n",
1263 "Willowdale, Newtonbrook\n",
1264 "Downsview\n",
1265 "Studio District\n",
1266 "Bedford Park, Lawrence Manor East\n",
1267 "Del Ray, Mount Dennis, Keelsdale and Silverthorn\n",
1268 "Humberlea, Emery\n",
1269 "Birch Cliff, Cliffside West\n",
1270 "Willowdale, Willowdale East\n",
1271 "Downsview\n",
1272 "Lawrence Park\n",
1273 "Roselawn\n",
1274 "Runnymede, The Junction North\n",
1275 "Weston\n",
1276 "Dorset Park, Wexford Heights, Scarborough Town Centre\n",
1277 "York Mills West\n",
1278 "Davisville North\n",
1279 "Forest Hill North & West, Forest Hill Road Park\n",
1280 "High Park, The Junction South\n",
1281 "Westmount\n",
1282 "Wexford, Maryvale\n",
1283 "Willowdale, Willowdale West\n",
1284 "North Toronto West, Lawrence Park\n",
1285 "The Annex, North Midtown, Yorkville\n",
1286 "Parkdale, Roncesvalles\n",
1287 "Canada Post Gateway Processing Centre\n",
1288 "Kingsview Village, St. Phillips, Martin Grove Gardens, Richview Gardens\n",
1289 "Agincourt\n",
1290 "Davisville\n",
1291 "University of Toronto, Harbord\n",
1292 "Runnymede, Swansea\n",
1293 "Clarks Corners, Tam O'Shanter, Sullivan\n",
1294 "Moore Park, Summerhill East\n",
1295 "Kensington Market, Chinatown, Grange Park\n",
1296 "Milliken, Agincourt North, Steeles East, L'Amoreaux East\n",
1297 "Summerhill West, Rathnelly, South Hill, Forest Hill SE, Deer Park\n",
1298 "CN Tower, King and Spadina, Railway Lands, Harbourfront West, Bathurst Quay, South Niagara, Island airport\n",
1299 "New Toronto, Mimico South, Humber Bay Shores\n",
1300 "South Steeles, Silverstone, Humbergate, Jamestown, Mount Olive, Beaumond Heights, Thistletown, Albion Gardens\n",
1301 "Steeles West, L'Amoreaux West\n",
1302 "Rosedale\n",
1303 "Stn A PO Boxes\n",
1304 "Alderwood, Long Branch\n",
1305 "Northwest, West Humber - Clairville\n",
1306 "Upper Rouge\n",
1307 "St. James Town, Cabbagetown\n",
1308 "First Canadian Place, Underground city\n",
1309 "The Kingsway, Montgomery Road, Old Mill North\n",
1310 "Church and Wellesley\n",
1311 "Business reply mail Processing Centre, South Central Letter Processing Plant Toronto\n",
1312 "Old Mill South, King's Mill Park, Sunnylea, Humber Bay, Mimico NE, The Queensway East, Royal York South East, Kingsway Park South East\n",
1313 "Mimico NW, The Queensway West, South of Bloor, Kingsway Park South West, Royal York South West\n"
1314 ]
1315 }
1316 ],
1317 "source": [
1318 "toronto_venues = getNearbyVenues(names=df['Neighbourhood'],\n",
1319 " latitudes=df['Latitude'],\n",
1320 " longitudes=df['Longitude']\n",
1321 " )"
1322 ]
1323 },
1324 {
1325 "cell_type": "markdown",
1326 "metadata": {},
1327 "source": [
1328 "Checking the size of df"
1329 ]
1330 },
1331 {
1332 "cell_type": "code",
1333 "execution_count": 101,
1334 "metadata": {},
1335 "outputs": [
1336 {
1337 "name": "stdout",
1338 "output_type": "stream",
1339 "text": [
1340 "(2153, 7)\n"
1341 ]
1342 },
1343 {
1344 "data": {
1345 "text/html": [
1346 "<div>\n",
1347 "<style scoped>\n",
1348 " .dataframe tbody tr th:only-of-type {\n",
1349 " vertical-align: middle;\n",
1350 " }\n",
1351 "\n",
1352 " .dataframe tbody tr th {\n",
1353 " vertical-align: top;\n",
1354 " }\n",
1355 "\n",
1356 " .dataframe thead th {\n",
1357 " text-align: right;\n",
1358 " }\n",
1359 "</style>\n",
1360 "<table border=\"1\" class=\"dataframe\">\n",
1361 " <thead>\n",
1362 " <tr style=\"text-align: right;\">\n",
1363 " <th></th>\n",
1364 " <th>Neighbourhood</th>\n",
1365 " <th>Neighborhood Latitude</th>\n",
1366 " <th>Neighborhood Longitude</th>\n",
1367 " <th>Venue</th>\n",
1368 " <th>Venue Latitude</th>\n",
1369 " <th>Venue Longitude</th>\n",
1370 " <th>Venue Category</th>\n",
1371 " </tr>\n",
1372 " </thead>\n",
1373 " <tbody>\n",
1374 " <tr>\n",
1375 " <th>0</th>\n",
1376 " <td>Parkwoods</td>\n",
1377 " <td>43.753259</td>\n",
1378 " <td>-79.329656</td>\n",
1379 " <td>Brookbanks Park</td>\n",
1380 " <td>43.751976</td>\n",
1381 " <td>-79.332140</td>\n",
1382 " <td>Park</td>\n",
1383 " </tr>\n",
1384 " <tr>\n",
1385 " <th>1</th>\n",
1386 " <td>Parkwoods</td>\n",
1387 " <td>43.753259</td>\n",
1388 " <td>-79.329656</td>\n",
1389 " <td>Variety Store</td>\n",
1390 " <td>43.751974</td>\n",
1391 " <td>-79.333114</td>\n",
1392 " <td>Food & Drink Shop</td>\n",
1393 " </tr>\n",
1394 " <tr>\n",
1395 " <th>2</th>\n",
1396 " <td>Victoria Village</td>\n",
1397 " <td>43.725882</td>\n",
1398 " <td>-79.315572</td>\n",
1399 " <td>Victoria Village Arena</td>\n",
1400 " <td>43.723481</td>\n",
1401 " <td>-79.315635</td>\n",
1402 " <td>Hockey Arena</td>\n",
1403 " </tr>\n",
1404 " <tr>\n",
1405 " <th>3</th>\n",
1406 " <td>Victoria Village</td>\n",
1407 " <td>43.725882</td>\n",
1408 " <td>-79.315572</td>\n",
1409 " <td>Portugril</td>\n",
1410 " <td>43.725819</td>\n",
1411 " <td>-79.312785</td>\n",
1412 " <td>Portuguese Restaurant</td>\n",
1413 " </tr>\n",
1414 " <tr>\n",
1415 " <th>4</th>\n",
1416 " <td>Victoria Village</td>\n",
1417 " <td>43.725882</td>\n",
1418 " <td>-79.315572</td>\n",
1419 " <td>Tim Hortons</td>\n",
1420 " <td>43.725517</td>\n",
1421 " <td>-79.313103</td>\n",
1422 " <td>Coffee Shop</td>\n",
1423 " </tr>\n",
1424 " </tbody>\n",
1425 "</table>\n",
1426 "</div>"
1427 ],
1428 "text/plain": [
1429 " Neighbourhood Neighborhood Latitude Neighborhood Longitude \\\n",
1430 "0 Parkwoods 43.753259 -79.329656 \n",
1431 "1 Parkwoods 43.753259 -79.329656 \n",
1432 "2 Victoria Village 43.725882 -79.315572 \n",
1433 "3 Victoria Village 43.725882 -79.315572 \n",
1434 "4 Victoria Village 43.725882 -79.315572 \n",
1435 "\n",
1436 " Venue Venue Latitude Venue Longitude \\\n",
1437 "0 Brookbanks Park 43.751976 -79.332140 \n",
1438 "1 Variety Store 43.751974 -79.333114 \n",
1439 "2 Victoria Village Arena 43.723481 -79.315635 \n",
1440 "3 Portugril 43.725819 -79.312785 \n",
1441 "4 Tim Hortons 43.725517 -79.313103 \n",
1442 "\n",
1443 " Venue Category \n",
1444 "0 Park \n",
1445 "1 Food & Drink Shop \n",
1446 "2 Hockey Arena \n",
1447 "3 Portuguese Restaurant \n",
1448 "4 Coffee Shop "
1449 ]
1450 },
1451 "execution_count": 101,
1452 "metadata": {},
1453 "output_type": "execute_result"
1454 }
1455 ],
1456 "source": [
1457 "print(toronto_venues.shape)\n",
1458 "toronto_venues.head()"
1459 ]
1460 },
1461 {
1462 "cell_type": "markdown",
1463 "metadata": {},
1464 "source": [
1465 "Checking how many venues there are for each venue"
1466 ]
1467 },
1468 {
1469 "cell_type": "code",
1470 "execution_count": 102,
1471 "metadata": {},
1472 "outputs": [
1473 {
1474 "data": {
1475 "text/html": [
1476 "<div>\n",
1477 "<style scoped>\n",
1478 " .dataframe tbody tr th:only-of-type {\n",
1479 " vertical-align: middle;\n",
1480 " }\n",
1481 "\n",
1482 " .dataframe tbody tr th {\n",
1483 " vertical-align: top;\n",
1484 " }\n",
1485 "\n",
1486 " .dataframe thead th {\n",
1487 " text-align: right;\n",
1488 " }\n",
1489 "</style>\n",
1490 "<table border=\"1\" class=\"dataframe\">\n",
1491 " <thead>\n",
1492 " <tr style=\"text-align: right;\">\n",
1493 " <th></th>\n",
1494 " <th>Neighborhood Latitude</th>\n",
1495 " <th>Neighborhood Longitude</th>\n",
1496 " <th>Venue</th>\n",
1497 " <th>Venue Latitude</th>\n",
1498 " <th>Venue Longitude</th>\n",
1499 " <th>Venue Category</th>\n",
1500 " </tr>\n",
1501 " <tr>\n",
1502 " <th>Neighbourhood</th>\n",
1503 " <th></th>\n",
1504 " <th></th>\n",
1505 " <th></th>\n",
1506 " <th></th>\n",
1507 " <th></th>\n",
1508 " <th></th>\n",
1509 " </tr>\n",
1510 " </thead>\n",
1511 " <tbody>\n",
1512 " <tr>\n",
1513 " <th>Agincourt</th>\n",
1514 " <td>4</td>\n",
1515 " <td>4</td>\n",
1516 " <td>4</td>\n",
1517 " <td>4</td>\n",
1518 " <td>4</td>\n",
1519 " <td>4</td>\n",
1520 " </tr>\n",
1521 " <tr>\n",
1522 " <th>Alderwood, Long Branch</th>\n",
1523 " <td>8</td>\n",
1524 " <td>8</td>\n",
1525 " <td>8</td>\n",
1526 " <td>8</td>\n",
1527 " <td>8</td>\n",
1528 " <td>8</td>\n",
1529 " </tr>\n",
1530 " <tr>\n",
1531 " <th>Bathurst Manor, Wilson Heights, Downsview North</th>\n",
1532 " <td>21</td>\n",
1533 " <td>21</td>\n",
1534 " <td>21</td>\n",
1535 " <td>21</td>\n",
1536 " <td>21</td>\n",
1537 " <td>21</td>\n",
1538 " </tr>\n",
1539 " <tr>\n",
1540 " <th>Bayview Village</th>\n",
1541 " <td>4</td>\n",
1542 " <td>4</td>\n",
1543 " <td>4</td>\n",
1544 " <td>4</td>\n",
1545 " <td>4</td>\n",
1546 " <td>4</td>\n",
1547 " </tr>\n",
1548 " <tr>\n",
1549 " <th>Bedford Park, Lawrence Manor East</th>\n",
1550 " <td>25</td>\n",
1551 " <td>25</td>\n",
1552 " <td>25</td>\n",
1553 " <td>25</td>\n",
1554 " <td>25</td>\n",
1555 " <td>25</td>\n",
1556 " </tr>\n",
1557 " <tr>\n",
1558 " <th>...</th>\n",
1559 " <td>...</td>\n",
1560 " <td>...</td>\n",
1561 " <td>...</td>\n",
1562 " <td>...</td>\n",
1563 " <td>...</td>\n",
1564 " <td>...</td>\n",
1565 " </tr>\n",
1566 " <tr>\n",
1567 " <th>Willowdale, Willowdale East</th>\n",
1568 " <td>34</td>\n",
1569 " <td>34</td>\n",
1570 " <td>34</td>\n",
1571 " <td>34</td>\n",
1572 " <td>34</td>\n",
1573 " <td>34</td>\n",
1574 " </tr>\n",
1575 " <tr>\n",
1576 " <th>Willowdale, Willowdale West</th>\n",
1577 " <td>6</td>\n",
1578 " <td>6</td>\n",
1579 " <td>6</td>\n",
1580 " <td>6</td>\n",
1581 " <td>6</td>\n",
1582 " <td>6</td>\n",
1583 " </tr>\n",
1584 " <tr>\n",
1585 " <th>Woburn</th>\n",
1586 " <td>4</td>\n",
1587 " <td>4</td>\n",
1588 " <td>4</td>\n",
1589 " <td>4</td>\n",
1590 " <td>4</td>\n",
1591 " <td>4</td>\n",
1592 " </tr>\n",
1593 " <tr>\n",
1594 " <th>Woodbine Heights</th>\n",
1595 " <td>9</td>\n",
1596 " <td>9</td>\n",
1597 " <td>9</td>\n",
1598 " <td>9</td>\n",
1599 " <td>9</td>\n",
1600 " <td>9</td>\n",
1601 " </tr>\n",
1602 " <tr>\n",
1603 " <th>York Mills West</th>\n",
1604 " <td>3</td>\n",
1605 " <td>3</td>\n",
1606 " <td>3</td>\n",
1607 " <td>3</td>\n",
1608 " <td>3</td>\n",
1609 " <td>3</td>\n",
1610 " </tr>\n",
1611 " </tbody>\n",
1612 "</table>\n",
1613 "<p>96 rows × 6 columns</p>\n",
1614 "</div>"
1615 ],
1616 "text/plain": [
1617 " Neighborhood Latitude \\\n",
1618 "Neighbourhood \n",
1619 "Agincourt 4 \n",
1620 "Alderwood, Long Branch 8 \n",
1621 "Bathurst Manor, Wilson Heights, Downsview North 21 \n",
1622 "Bayview Village 4 \n",
1623 "Bedford Park, Lawrence Manor East 25 \n",
1624 "... ... \n",
1625 "Willowdale, Willowdale East 34 \n",
1626 "Willowdale, Willowdale West 6 \n",
1627 "Woburn 4 \n",
1628 "Woodbine Heights 9 \n",
1629 "York Mills West 3 \n",
1630 "\n",
1631 " Neighborhood Longitude \\\n",
1632 "Neighbourhood \n",
1633 "Agincourt 4 \n",
1634 "Alderwood, Long Branch 8 \n",
1635 "Bathurst Manor, Wilson Heights, Downsview North 21 \n",
1636 "Bayview Village 4 \n",
1637 "Bedford Park, Lawrence Manor East 25 \n",
1638 "... ... \n",
1639 "Willowdale, Willowdale East 34 \n",
1640 "Willowdale, Willowdale West 6 \n",
1641 "Woburn 4 \n",
1642 "Woodbine Heights 9 \n",
1643 "York Mills West 3 \n",
1644 "\n",
1645 " Venue Venue Latitude \\\n",
1646 "Neighbourhood \n",
1647 "Agincourt 4 4 \n",
1648 "Alderwood, Long Branch 8 8 \n",
1649 "Bathurst Manor, Wilson Heights, Downsview North 21 21 \n",
1650 "Bayview Village 4 4 \n",
1651 "Bedford Park, Lawrence Manor East 25 25 \n",
1652 "... ... ... \n",
1653 "Willowdale, Willowdale East 34 34 \n",
1654 "Willowdale, Willowdale West 6 6 \n",
1655 "Woburn 4 4 \n",
1656 "Woodbine Heights 9 9 \n",
1657 "York Mills West 3 3 \n",
1658 "\n",
1659 " Venue Longitude \\\n",
1660 "Neighbourhood \n",
1661 "Agincourt 4 \n",
1662 "Alderwood, Long Branch 8 \n",
1663 "Bathurst Manor, Wilson Heights, Downsview North 21 \n",
1664 "Bayview Village 4 \n",
1665 "Bedford Park, Lawrence Manor East 25 \n",
1666 "... ... \n",
1667 "Willowdale, Willowdale East 34 \n",
1668 "Willowdale, Willowdale West 6 \n",
1669 "Woburn 4 \n",
1670 "Woodbine Heights 9 \n",
1671 "York Mills West 3 \n",
1672 "\n",
1673 " Venue Category \n",
1674 "Neighbourhood \n",
1675 "Agincourt 4 \n",
1676 "Alderwood, Long Branch 8 \n",
1677 "Bathurst Manor, Wilson Heights, Downsview North 21 \n",
1678 "Bayview Village 4 \n",
1679 "Bedford Park, Lawrence Manor East 25 \n",
1680 "... ... \n",
1681 "Willowdale, Willowdale East 34 \n",
1682 "Willowdale, Willowdale West 6 \n",
1683 "Woburn 4 \n",
1684 "Woodbine Heights 9 \n",
1685 "York Mills West 3 \n",
1686 "\n",
1687 "[96 rows x 6 columns]"
1688 ]
1689 },
1690 "execution_count": 102,
1691 "metadata": {},
1692 "output_type": "execute_result"
1693 }
1694 ],
1695 "source": [
1696 "toronto_venues.groupby('Neighbourhood').count()"
1697 ]
1698 },
1699 {
1700 "cell_type": "markdown",
1701 "metadata": {},
1702 "source": [
1703 "How many categorys can we find?"
1704 ]
1705 },
1706 {
1707 "cell_type": "code",
1708 "execution_count": 103,
1709 "metadata": {},
1710 "outputs": [
1711 {
1712 "data": {
1713 "text/html": [
1714 "<div>\n",
1715 "<style scoped>\n",
1716 " .dataframe tbody tr th:only-of-type {\n",
1717 " vertical-align: middle;\n",
1718 " }\n",
1719 "\n",
1720 " .dataframe tbody tr th {\n",
1721 " vertical-align: top;\n",
1722 " }\n",
1723 "\n",
1724 " .dataframe thead th {\n",
1725 " text-align: right;\n",
1726 " }\n",
1727 "</style>\n",
1728 "<table border=\"1\" class=\"dataframe\">\n",
1729 " <thead>\n",
1730 " <tr style=\"text-align: right;\">\n",
1731 " <th></th>\n",
1732 " <th>Neighbourhood</th>\n",
1733 " <th>Accessories Store</th>\n",
1734 " <th>Afghan Restaurant</th>\n",
1735 " <th>Airport</th>\n",
1736 " <th>Airport Food Court</th>\n",
1737 " <th>Airport Lounge</th>\n",
1738 " <th>Airport Service</th>\n",
1739 " <th>Airport Terminal</th>\n",
1740 " <th>American Restaurant</th>\n",
1741 " <th>Antique Shop</th>\n",
1742 " <th>...</th>\n",
1743 " <th>Vegetarian / Vegan Restaurant</th>\n",
1744 " <th>Video Game Store</th>\n",
1745 " <th>Video Store</th>\n",
1746 " <th>Vietnamese Restaurant</th>\n",
1747 " <th>Warehouse Store</th>\n",
1748 " <th>Wine Bar</th>\n",
1749 " <th>Wine Shop</th>\n",
1750 " <th>Wings Joint</th>\n",
1751 " <th>Women's Store</th>\n",
1752 " <th>Yoga Studio</th>\n",
1753 " </tr>\n",
1754 " </thead>\n",
1755 " <tbody>\n",
1756 " <tr>\n",
1757 " <th>0</th>\n",
1758 " <td>Parkwoods</td>\n",
1759 " <td>0</td>\n",
1760 " <td>0</td>\n",
1761 " <td>0</td>\n",
1762 " <td>0</td>\n",
1763 " <td>0</td>\n",
1764 " <td>0</td>\n",
1765 " <td>0</td>\n",
1766 " <td>0</td>\n",
1767 " <td>0</td>\n",
1768 " <td>...</td>\n",
1769 " <td>0</td>\n",
1770 " <td>0</td>\n",
1771 " <td>0</td>\n",
1772 " <td>0</td>\n",
1773 " <td>0</td>\n",
1774 " <td>0</td>\n",
1775 " <td>0</td>\n",
1776 " <td>0</td>\n",
1777 " <td>0</td>\n",
1778 " <td>0</td>\n",
1779 " </tr>\n",
1780 " <tr>\n",
1781 " <th>1</th>\n",
1782 " <td>Parkwoods</td>\n",
1783 " <td>0</td>\n",
1784 " <td>0</td>\n",
1785 " <td>0</td>\n",
1786 " <td>0</td>\n",
1787 " <td>0</td>\n",
1788 " <td>0</td>\n",
1789 " <td>0</td>\n",
1790 " <td>0</td>\n",
1791 " <td>0</td>\n",
1792 " <td>...</td>\n",
1793 " <td>0</td>\n",
1794 " <td>0</td>\n",
1795 " <td>0</td>\n",
1796 " <td>0</td>\n",
1797 " <td>0</td>\n",
1798 " <td>0</td>\n",
1799 " <td>0</td>\n",
1800 " <td>0</td>\n",
1801 " <td>0</td>\n",
1802 " <td>0</td>\n",
1803 " </tr>\n",
1804 " <tr>\n",
1805 " <th>2</th>\n",
1806 " <td>Victoria Village</td>\n",
1807 " <td>0</td>\n",
1808 " <td>0</td>\n",
1809 " <td>0</td>\n",
1810 " <td>0</td>\n",
1811 " <td>0</td>\n",
1812 " <td>0</td>\n",
1813 " <td>0</td>\n",
1814 " <td>0</td>\n",
1815 " <td>0</td>\n",
1816 " <td>...</td>\n",
1817 " <td>0</td>\n",
1818 " <td>0</td>\n",
1819 " <td>0</td>\n",
1820 " <td>0</td>\n",
1821 " <td>0</td>\n",
1822 " <td>0</td>\n",
1823 " <td>0</td>\n",
1824 " <td>0</td>\n",
1825 " <td>0</td>\n",
1826 " <td>0</td>\n",
1827 " </tr>\n",
1828 " <tr>\n",
1829 " <th>3</th>\n",
1830 " <td>Victoria Village</td>\n",
1831 " <td>0</td>\n",
1832 " <td>0</td>\n",
1833 " <td>0</td>\n",
1834 " <td>0</td>\n",
1835 " <td>0</td>\n",
1836 " <td>0</td>\n",
1837 " <td>0</td>\n",
1838 " <td>0</td>\n",
1839 " <td>0</td>\n",
1840 " <td>...</td>\n",
1841 " <td>0</td>\n",
1842 " <td>0</td>\n",
1843 " <td>0</td>\n",
1844 " <td>0</td>\n",
1845 " <td>0</td>\n",
1846 " <td>0</td>\n",
1847 " <td>0</td>\n",
1848 " <td>0</td>\n",
1849 " <td>0</td>\n",
1850 " <td>0</td>\n",
1851 " </tr>\n",
1852 " <tr>\n",
1853 " <th>4</th>\n",
1854 " <td>Victoria Village</td>\n",
1855 " <td>0</td>\n",
1856 " <td>0</td>\n",
1857 " <td>0</td>\n",
1858 " <td>0</td>\n",
1859 " <td>0</td>\n",
1860 " <td>0</td>\n",
1861 " <td>0</td>\n",
1862 " <td>0</td>\n",
1863 " <td>0</td>\n",
1864 " <td>...</td>\n",
1865 " <td>0</td>\n",
1866 " <td>0</td>\n",
1867 " <td>0</td>\n",
1868 " <td>0</td>\n",
1869 " <td>0</td>\n",
1870 " <td>0</td>\n",
1871 " <td>0</td>\n",
1872 " <td>0</td>\n",
1873 " <td>0</td>\n",
1874 " <td>0</td>\n",
1875 " </tr>\n",
1876 " </tbody>\n",
1877 "</table>\n",
1878 "<p>5 rows × 270 columns</p>\n",
1879 "</div>"
1880 ],
1881 "text/plain": [
1882 " Neighbourhood Accessories Store Afghan Restaurant Airport \\\n",
1883 "0 Parkwoods 0 0 0 \n",
1884 "1 Parkwoods 0 0 0 \n",
1885 "2 Victoria Village 0 0 0 \n",
1886 "3 Victoria Village 0 0 0 \n",
1887 "4 Victoria Village 0 0 0 \n",
1888 "\n",
1889 " Airport Food Court Airport Lounge Airport Service Airport Terminal \\\n",
1890 "0 0 0 0 0 \n",
1891 "1 0 0 0 0 \n",
1892 "2 0 0 0 0 \n",
1893 "3 0 0 0 0 \n",
1894 "4 0 0 0 0 \n",
1895 "\n",
1896 " American Restaurant Antique Shop ... Vegetarian / Vegan Restaurant \\\n",
1897 "0 0 0 ... 0 \n",
1898 "1 0 0 ... 0 \n",
1899 "2 0 0 ... 0 \n",
1900 "3 0 0 ... 0 \n",
1901 "4 0 0 ... 0 \n",
1902 "\n",
1903 " Video Game Store Video Store Vietnamese Restaurant Warehouse Store \\\n",
1904 "0 0 0 0 0 \n",
1905 "1 0 0 0 0 \n",
1906 "2 0 0 0 0 \n",
1907 "3 0 0 0 0 \n",
1908 "4 0 0 0 0 \n",
1909 "\n",
1910 " Wine Bar Wine Shop Wings Joint Women's Store Yoga Studio \n",
1911 "0 0 0 0 0 0 \n",
1912 "1 0 0 0 0 0 \n",
1913 "2 0 0 0 0 0 \n",
1914 "3 0 0 0 0 0 \n",
1915 "4 0 0 0 0 0 \n",
1916 "\n",
1917 "[5 rows x 270 columns]"
1918 ]
1919 },
1920 "execution_count": 103,
1921 "metadata": {},
1922 "output_type": "execute_result"
1923 }
1924 ],
1925 "source": [
1926 "# one hot encoding\n",
1927 "toronto_onehot = pd.get_dummies(toronto_venues[['Venue Category']], prefix=\"\", prefix_sep=\"\")\n",
1928 "\n",
1929 "# add neighborhood column back to dataframe\n",
1930 "toronto_onehot['Neighbourhood'] = toronto_venues['Neighbourhood'] \n",
1931 "\n",
1932 "# move neighborhood column to the first column\n",
1933 "fixed_columns = [toronto_onehot.columns[-1]] + list(toronto_onehot.columns[:-1])\n",
1934 "toronto_onehot = toronto_onehot[fixed_columns]\n",
1935 "\n",
1936 "toronto_onehot.head()"
1937 ]
1938 },
1939 {
1940 "cell_type": "code",
1941 "execution_count": 104,
1942 "metadata": {},
1943 "outputs": [
1944 {
1945 "data": {
1946 "text/plain": [
1947 "(2153, 270)"
1948 ]
1949 },
1950 "execution_count": 104,
1951 "metadata": {},
1952 "output_type": "execute_result"
1953 }
1954 ],
1955 "source": [
1956 "toronto_onehot.shape"
1957 ]
1958 },
1959 {
1960 "cell_type": "code",
1961 "execution_count": 105,
1962 "metadata": {},
1963 "outputs": [
1964 {
1965 "data": {
1966 "text/html": [
1967 "<div>\n",
1968 "<style scoped>\n",
1969 " .dataframe tbody tr th:only-of-type {\n",
1970 " vertical-align: middle;\n",
1971 " }\n",
1972 "\n",
1973 " .dataframe tbody tr th {\n",
1974 " vertical-align: top;\n",
1975 " }\n",
1976 "\n",
1977 " .dataframe thead th {\n",
1978 " text-align: right;\n",
1979 " }\n",
1980 "</style>\n",
1981 "<table border=\"1\" class=\"dataframe\">\n",
1982 " <thead>\n",
1983 " <tr style=\"text-align: right;\">\n",
1984 " <th></th>\n",
1985 " <th>Neighbourhood</th>\n",
1986 " <th>Accessories Store</th>\n",
1987 " <th>Afghan Restaurant</th>\n",
1988 " <th>Airport</th>\n",
1989 " <th>Airport Food Court</th>\n",
1990 " <th>Airport Lounge</th>\n",
1991 " <th>Airport Service</th>\n",
1992 " <th>Airport Terminal</th>\n",
1993 " <th>American Restaurant</th>\n",
1994 " <th>Antique Shop</th>\n",
1995 " <th>...</th>\n",
1996 " <th>Vegetarian / Vegan Restaurant</th>\n",
1997 " <th>Video Game Store</th>\n",
1998 " <th>Video Store</th>\n",
1999 " <th>Vietnamese Restaurant</th>\n",
2000 " <th>Warehouse Store</th>\n",
2001 " <th>Wine Bar</th>\n",
2002 " <th>Wine Shop</th>\n",
2003 " <th>Wings Joint</th>\n",
2004 " <th>Women's Store</th>\n",
2005 " <th>Yoga Studio</th>\n",
2006 " </tr>\n",
2007 " </thead>\n",
2008 " <tbody>\n",
2009 " <tr>\n",
2010 " <th>0</th>\n",
2011 " <td>Agincourt</td>\n",
2012 " <td>0.0</td>\n",
2013 " <td>0.0</td>\n",
2014 " <td>0.0</td>\n",
2015 " <td>0.0</td>\n",
2016 " <td>0.0</td>\n",
2017 " <td>0.0</td>\n",
2018 " <td>0.0</td>\n",
2019 " <td>0.00</td>\n",
2020 " <td>0.0</td>\n",
2021 " <td>...</td>\n",
2022 " <td>0.0</td>\n",
2023 " <td>0.0</td>\n",
2024 " <td>0.0</td>\n",
2025 " <td>0.0</td>\n",
2026 " <td>0.0</td>\n",
2027 " <td>0.0</td>\n",
2028 " <td>0.0</td>\n",
2029 " <td>0.0</td>\n",
2030 " <td>0.00</td>\n",
2031 " <td>0.0</td>\n",
2032 " </tr>\n",
2033 " <tr>\n",
2034 " <th>1</th>\n",
2035 " <td>Alderwood, Long Branch</td>\n",
2036 " <td>0.0</td>\n",
2037 " <td>0.0</td>\n",
2038 " <td>0.0</td>\n",
2039 " <td>0.0</td>\n",
2040 " <td>0.0</td>\n",
2041 " <td>0.0</td>\n",
2042 " <td>0.0</td>\n",
2043 " <td>0.00</td>\n",
2044 " <td>0.0</td>\n",
2045 " <td>...</td>\n",
2046 " <td>0.0</td>\n",
2047 " <td>0.0</td>\n",
2048 " <td>0.0</td>\n",
2049 " <td>0.0</td>\n",
2050 " <td>0.0</td>\n",
2051 " <td>0.0</td>\n",
2052 " <td>0.0</td>\n",
2053 " <td>0.0</td>\n",
2054 " <td>0.00</td>\n",
2055 " <td>0.0</td>\n",
2056 " </tr>\n",
2057 " <tr>\n",
2058 " <th>2</th>\n",
2059 " <td>Bathurst Manor, Wilson Heights, Downsview North</td>\n",
2060 " <td>0.0</td>\n",
2061 " <td>0.0</td>\n",
2062 " <td>0.0</td>\n",
2063 " <td>0.0</td>\n",
2064 " <td>0.0</td>\n",
2065 " <td>0.0</td>\n",
2066 " <td>0.0</td>\n",
2067 " <td>0.00</td>\n",
2068 " <td>0.0</td>\n",
2069 " <td>...</td>\n",
2070 " <td>0.0</td>\n",
2071 " <td>0.0</td>\n",
2072 " <td>0.0</td>\n",
2073 " <td>0.0</td>\n",
2074 " <td>0.0</td>\n",
2075 " <td>0.0</td>\n",
2076 " <td>0.0</td>\n",
2077 " <td>0.0</td>\n",
2078 " <td>0.00</td>\n",
2079 " <td>0.0</td>\n",
2080 " </tr>\n",
2081 " <tr>\n",
2082 " <th>3</th>\n",
2083 " <td>Bayview Village</td>\n",
2084 " <td>0.0</td>\n",
2085 " <td>0.0</td>\n",
2086 " <td>0.0</td>\n",
2087 " <td>0.0</td>\n",
2088 " <td>0.0</td>\n",
2089 " <td>0.0</td>\n",
2090 " <td>0.0</td>\n",
2091 " <td>0.00</td>\n",
2092 " <td>0.0</td>\n",
2093 " <td>...</td>\n",
2094 " <td>0.0</td>\n",
2095 " <td>0.0</td>\n",
2096 " <td>0.0</td>\n",
2097 " <td>0.0</td>\n",
2098 " <td>0.0</td>\n",
2099 " <td>0.0</td>\n",
2100 " <td>0.0</td>\n",
2101 " <td>0.0</td>\n",
2102 " <td>0.00</td>\n",
2103 " <td>0.0</td>\n",
2104 " </tr>\n",
2105 " <tr>\n",
2106 " <th>4</th>\n",
2107 " <td>Bedford Park, Lawrence Manor East</td>\n",
2108 " <td>0.0</td>\n",
2109 " <td>0.0</td>\n",
2110 " <td>0.0</td>\n",
2111 " <td>0.0</td>\n",
2112 " <td>0.0</td>\n",
2113 " <td>0.0</td>\n",
2114 " <td>0.0</td>\n",
2115 " <td>0.04</td>\n",
2116 " <td>0.0</td>\n",
2117 " <td>...</td>\n",
2118 " <td>0.0</td>\n",
2119 " <td>0.0</td>\n",
2120 " <td>0.0</td>\n",
2121 " <td>0.0</td>\n",
2122 " <td>0.0</td>\n",
2123 " <td>0.0</td>\n",
2124 " <td>0.0</td>\n",
2125 " <td>0.0</td>\n",
2126 " <td>0.04</td>\n",
2127 " <td>0.0</td>\n",
2128 " </tr>\n",
2129 " </tbody>\n",
2130 "</table>\n",
2131 "<p>5 rows × 270 columns</p>\n",
2132 "</div>"
2133 ],
2134 "text/plain": [
2135 " Neighbourhood Accessories Store \\\n",
2136 "0 Agincourt 0.0 \n",
2137 "1 Alderwood, Long Branch 0.0 \n",
2138 "2 Bathurst Manor, Wilson Heights, Downsview North 0.0 \n",
2139 "3 Bayview Village 0.0 \n",
2140 "4 Bedford Park, Lawrence Manor East 0.0 \n",
2141 "\n",
2142 " Afghan Restaurant Airport Airport Food Court Airport Lounge \\\n",
2143 "0 0.0 0.0 0.0 0.0 \n",
2144 "1 0.0 0.0 0.0 0.0 \n",
2145 "2 0.0 0.0 0.0 0.0 \n",
2146 "3 0.0 0.0 0.0 0.0 \n",
2147 "4 0.0 0.0 0.0 0.0 \n",
2148 "\n",
2149 " Airport Service Airport Terminal American Restaurant Antique Shop ... \\\n",
2150 "0 0.0 0.0 0.00 0.0 ... \n",
2151 "1 0.0 0.0 0.00 0.0 ... \n",
2152 "2 0.0 0.0 0.00 0.0 ... \n",
2153 "3 0.0 0.0 0.00 0.0 ... \n",
2154 "4 0.0 0.0 0.04 0.0 ... \n",
2155 "\n",
2156 " Vegetarian / Vegan Restaurant Video Game Store Video Store \\\n",
2157 "0 0.0 0.0 0.0 \n",
2158 "1 0.0 0.0 0.0 \n",
2159 "2 0.0 0.0 0.0 \n",
2160 "3 0.0 0.0 0.0 \n",
2161 "4 0.0 0.0 0.0 \n",
2162 "\n",
2163 " Vietnamese Restaurant Warehouse Store Wine Bar Wine Shop Wings Joint \\\n",
2164 "0 0.0 0.0 0.0 0.0 0.0 \n",
2165 "1 0.0 0.0 0.0 0.0 0.0 \n",
2166 "2 0.0 0.0 0.0 0.0 0.0 \n",
2167 "3 0.0 0.0 0.0 0.0 0.0 \n",
2168 "4 0.0 0.0 0.0 0.0 0.0 \n",
2169 "\n",
2170 " Women's Store Yoga Studio \n",
2171 "0 0.00 0.0 \n",
2172 "1 0.00 0.0 \n",
2173 "2 0.00 0.0 \n",
2174 "3 0.00 0.0 \n",
2175 "4 0.04 0.0 \n",
2176 "\n",
2177 "[5 rows x 270 columns]"
2178 ]
2179 },
2180 "execution_count": 105,
2181 "metadata": {},
2182 "output_type": "execute_result"
2183 }
2184 ],
2185 "source": [
2186 "toronto_grouped = toronto_onehot.groupby('Neighbourhood').mean().reset_index()\n",
2187 "toronto_grouped.head()"
2188 ]
2189 },
2190 {
2191 "cell_type": "code",
2192 "execution_count": 106,
2193 "metadata": {},
2194 "outputs": [
2195 {
2196 "data": {
2197 "text/plain": [
2198 "(96, 270)"
2199 ]
2200 },
2201 "execution_count": 106,
2202 "metadata": {},
2203 "output_type": "execute_result"
2204 }
2205 ],
2206 "source": [
2207 "toronto_grouped.shape"
2208 ]
2209 },
2210 {
2211 "cell_type": "markdown",
2212 "metadata": {},
2213 "source": [
2214 "Getting the top 10 for each neighbourhood"
2215 ]
2216 },
2217 {
2218 "cell_type": "code",
2219 "execution_count": 107,
2220 "metadata": {},
2221 "outputs": [],
2222 "source": [
2223 "def return_most_common_venues(row, num_top_venues):\n",
2224 " row_categories = row.iloc[1:]\n",
2225 " row_categories_sorted = row_categories.sort_values(ascending=False)\n",
2226 " \n",
2227 " return row_categories_sorted.index.values[0:num_top_venues]"
2228 ]
2229 },
2230 {
2231 "cell_type": "code",
2232 "execution_count": 108,
2233 "metadata": {},
2234 "outputs": [
2235 {
2236 "data": {
2237 "text/html": [
2238 "<div>\n",
2239 "<style scoped>\n",
2240 " .dataframe tbody tr th:only-of-type {\n",
2241 " vertical-align: middle;\n",
2242 " }\n",
2243 "\n",
2244 " .dataframe tbody tr th {\n",
2245 " vertical-align: top;\n",
2246 " }\n",
2247 "\n",
2248 " .dataframe thead th {\n",
2249 " text-align: right;\n",
2250 " }\n",
2251 "</style>\n",
2252 "<table border=\"1\" class=\"dataframe\">\n",
2253 " <thead>\n",
2254 " <tr style=\"text-align: right;\">\n",
2255 " <th></th>\n",
2256 " <th>Neighbourhood</th>\n",
2257 " <th>1st Most Common Venue</th>\n",
2258 " <th>2nd Most Common Venue</th>\n",
2259 " <th>3rd Most Common Venue</th>\n",
2260 " <th>4th Most Common Venue</th>\n",
2261 " <th>5th Most Common Venue</th>\n",
2262 " <th>6th Most Common Venue</th>\n",
2263 " <th>7th Most Common Venue</th>\n",
2264 " <th>8th Most Common Venue</th>\n",
2265 " <th>9th Most Common Venue</th>\n",
2266 " <th>10th Most Common Venue</th>\n",
2267 " </tr>\n",
2268 " </thead>\n",
2269 " <tbody>\n",
2270 " <tr>\n",
2271 " <th>0</th>\n",
2272 " <td>Agincourt</td>\n",
2273 " <td>Lounge</td>\n",
2274 " <td>Latin American Restaurant</td>\n",
2275 " <td>Skating Rink</td>\n",
2276 " <td>Breakfast Spot</td>\n",
2277 " <td>Donut Shop</td>\n",
2278 " <td>Diner</td>\n",
2279 " <td>Discount Store</td>\n",
2280 " <td>Distribution Center</td>\n",
2281 " <td>Dog Run</td>\n",
2282 " <td>Doner Restaurant</td>\n",
2283 " </tr>\n",
2284 " <tr>\n",
2285 " <th>1</th>\n",
2286 " <td>Alderwood, Long Branch</td>\n",
2287 " <td>Pizza Place</td>\n",
2288 " <td>Pharmacy</td>\n",
2289 " <td>Sandwich Place</td>\n",
2290 " <td>Dance Studio</td>\n",
2291 " <td>Coffee Shop</td>\n",
2292 " <td>Pub</td>\n",
2293 " <td>Gym</td>\n",
2294 " <td>Airport Terminal</td>\n",
2295 " <td>Falafel Restaurant</td>\n",
2296 " <td>Event Space</td>\n",
2297 " </tr>\n",
2298 " <tr>\n",
2299 " <th>2</th>\n",
2300 " <td>Bathurst Manor, Wilson Heights, Downsview North</td>\n",
2301 " <td>Coffee Shop</td>\n",
2302 " <td>Bank</td>\n",
2303 " <td>Frozen Yogurt Shop</td>\n",
2304 " <td>Bridal Shop</td>\n",
2305 " <td>Sandwich Place</td>\n",
2306 " <td>Diner</td>\n",
2307 " <td>Restaurant</td>\n",
2308 " <td>Deli / Bodega</td>\n",
2309 " <td>Middle Eastern Restaurant</td>\n",
2310 " <td>Supermarket</td>\n",
2311 " </tr>\n",
2312 " <tr>\n",
2313 " <th>3</th>\n",
2314 " <td>Bayview Village</td>\n",
2315 " <td>Café</td>\n",
2316 " <td>Bank</td>\n",
2317 " <td>Chinese Restaurant</td>\n",
2318 " <td>Japanese Restaurant</td>\n",
2319 " <td>Yoga Studio</td>\n",
2320 " <td>Diner</td>\n",
2321 " <td>Discount Store</td>\n",
2322 " <td>Distribution Center</td>\n",
2323 " <td>Dog Run</td>\n",
2324 " <td>Doner Restaurant</td>\n",
2325 " </tr>\n",
2326 " <tr>\n",
2327 " <th>4</th>\n",
2328 " <td>Bedford Park, Lawrence Manor East</td>\n",
2329 " <td>Sandwich Place</td>\n",
2330 " <td>Restaurant</td>\n",
2331 " <td>Italian Restaurant</td>\n",
2332 " <td>Coffee Shop</td>\n",
2333 " <td>Liquor Store</td>\n",
2334 " <td>Thai Restaurant</td>\n",
2335 " <td>Café</td>\n",
2336 " <td>Pub</td>\n",
2337 " <td>Butcher</td>\n",
2338 " <td>Sushi Restaurant</td>\n",
2339 " </tr>\n",
2340 " </tbody>\n",
2341 "</table>\n",
2342 "</div>"
2343 ],
2344 "text/plain": [
2345 " Neighbourhood 1st Most Common Venue \\\n",
2346 "0 Agincourt Lounge \n",
2347 "1 Alderwood, Long Branch Pizza Place \n",
2348 "2 Bathurst Manor, Wilson Heights, Downsview North Coffee Shop \n",
2349 "3 Bayview Village Café \n",
2350 "4 Bedford Park, Lawrence Manor East Sandwich Place \n",
2351 "\n",
2352 " 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n",
2353 "0 Latin American Restaurant Skating Rink Breakfast Spot \n",
2354 "1 Pharmacy Sandwich Place Dance Studio \n",
2355 "2 Bank Frozen Yogurt Shop Bridal Shop \n",
2356 "3 Bank Chinese Restaurant Japanese Restaurant \n",
2357 "4 Restaurant Italian Restaurant Coffee Shop \n",
2358 "\n",
2359 " 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n",
2360 "0 Donut Shop Diner Discount Store \n",
2361 "1 Coffee Shop Pub Gym \n",
2362 "2 Sandwich Place Diner Restaurant \n",
2363 "3 Yoga Studio Diner Discount Store \n",
2364 "4 Liquor Store Thai Restaurant Café \n",
2365 "\n",
2366 " 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n",
2367 "0 Distribution Center Dog Run Doner Restaurant \n",
2368 "1 Airport Terminal Falafel Restaurant Event Space \n",
2369 "2 Deli / Bodega Middle Eastern Restaurant Supermarket \n",
2370 "3 Distribution Center Dog Run Doner Restaurant \n",
2371 "4 Pub Butcher Sushi Restaurant "
2372 ]
2373 },
2374 "execution_count": 108,
2375 "metadata": {},
2376 "output_type": "execute_result"
2377 }
2378 ],
2379 "source": [
2380 "import numpy as np\n",
2381 "num_top_venues = 10\n",
2382 "\n",
2383 "indicators = ['st', 'nd', 'rd']\n",
2384 "\n",
2385 "# create columns according to number of top venues\n",
2386 "columns = ['Neighbourhood']\n",
2387 "for ind in np.arange(num_top_venues):\n",
2388 " try:\n",
2389 " columns.append('{}{} Most Common Venue'.format(ind+1, indicators[ind]))\n",
2390 " except:\n",
2391 " columns.append('{}th Most Common Venue'.format(ind+1))\n",
2392 "\n",
2393 "# create a new dataframe\n",
2394 "neighborhoods_venues_sorted = pd.DataFrame(columns=columns)\n",
2395 "neighborhoods_venues_sorted['Neighbourhood'] = toronto_grouped['Neighbourhood']\n",
2396 "\n",
2397 "for ind in np.arange(toronto_grouped.shape[0]):\n",
2398 " neighborhoods_venues_sorted.iloc[ind, 1:] = return_most_common_venues(toronto_grouped.iloc[ind, :], num_top_venues)\n",
2399 "\n",
2400 "neighborhoods_venues_sorted.head()"
2401 ]
2402 },
2403 {
2404 "cell_type": "markdown",
2405 "metadata": {},
2406 "source": [
2407 "Clustering Neighborhoods"
2408 ]
2409 },
2410 {
2411 "cell_type": "code",
2412 "execution_count": 109,
2413 "metadata": {},
2414 "outputs": [
2415 {
2416 "data": {
2417 "text/plain": [
2418 "array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])"
2419 ]
2420 },
2421 "execution_count": 109,
2422 "metadata": {},
2423 "output_type": "execute_result"
2424 }
2425 ],
2426 "source": [
2427 "# import k-means from clustering stage\n",
2428 "from sklearn.cluster import KMeans\n",
2429 "\n",
2430 "# set number of clusters\n",
2431 "kclusters = 5\n",
2432 "\n",
2433 "toronto_grouped_clustering = toronto_grouped.drop('Neighbourhood', 1)\n",
2434 "\n",
2435 "# run k-means clustering\n",
2436 "kmeans = KMeans(n_clusters=kclusters, random_state=0).fit(toronto_grouped_clustering)\n",
2437 "\n",
2438 "# check cluster labels generated for each row in the dataframe\n",
2439 "kmeans.labels_[0:10]"
2440 ]
2441 },
2442 {
2443 "cell_type": "markdown",
2444 "metadata": {},
2445 "source": [
2446 "Merge the dataframe with the top 10 and the cluster for each neighbourhood"
2447 ]
2448 },
2449 {
2450 "cell_type": "code",
2451 "execution_count": 121,
2452 "metadata": {},
2453 "outputs": [
2454 {
2455 "data": {
2456 "text/html": [
2457 "<div>\n",
2458 "<style scoped>\n",
2459 " .dataframe tbody tr th:only-of-type {\n",
2460 " vertical-align: middle;\n",
2461 " }\n",
2462 "\n",
2463 " .dataframe tbody tr th {\n",
2464 " vertical-align: top;\n",
2465 " }\n",
2466 "\n",
2467 " .dataframe thead th {\n",
2468 " text-align: right;\n",
2469 " }\n",
2470 "</style>\n",
2471 "<table border=\"1\" class=\"dataframe\">\n",
2472 " <thead>\n",
2473 " <tr style=\"text-align: right;\">\n",
2474 " <th></th>\n",
2475 " <th>Postal Code</th>\n",
2476 " <th>Borough</th>\n",
2477 " <th>Neighbourhood</th>\n",
2478 " <th>Latitude</th>\n",
2479 " <th>Longitude</th>\n",
2480 " </tr>\n",
2481 " </thead>\n",
2482 " <tbody>\n",
2483 " <tr>\n",
2484 " <th>0</th>\n",
2485 " <td>M3A</td>\n",
2486 " <td>North York</td>\n",
2487 " <td>Parkwoods</td>\n",
2488 " <td>43.753259</td>\n",
2489 " <td>-79.329656</td>\n",
2490 " </tr>\n",
2491 " <tr>\n",
2492 " <th>1</th>\n",
2493 " <td>M4A</td>\n",
2494 " <td>North York</td>\n",
2495 " <td>Victoria Village</td>\n",
2496 " <td>43.725882</td>\n",
2497 " <td>-79.315572</td>\n",
2498 " </tr>\n",
2499 " <tr>\n",
2500 " <th>2</th>\n",
2501 " <td>M5A</td>\n",
2502 " <td>Downtown Toronto</td>\n",
2503 " <td>Regent Park, Harbourfront</td>\n",
2504 " <td>43.654260</td>\n",
2505 " <td>-79.360636</td>\n",
2506 " </tr>\n",
2507 " <tr>\n",
2508 " <th>3</th>\n",
2509 " <td>M6A</td>\n",
2510 " <td>North York</td>\n",
2511 " <td>Lawrence Manor, Lawrence Heights</td>\n",
2512 " <td>43.718518</td>\n",
2513 " <td>-79.464763</td>\n",
2514 " </tr>\n",
2515 " <tr>\n",
2516 " <th>4</th>\n",
2517 " <td>M7A</td>\n",
2518 " <td>Downtown Toronto</td>\n",
2519 " <td>Queen's Park, Ontario Provincial Government</td>\n",
2520 " <td>43.662301</td>\n",
2521 " <td>-79.389494</td>\n",
2522 " </tr>\n",
2523 " <tr>\n",
2524 " <th>...</th>\n",
2525 " <td>...</td>\n",
2526 " <td>...</td>\n",
2527 " <td>...</td>\n",
2528 " <td>...</td>\n",
2529 " <td>...</td>\n",
2530 " </tr>\n",
2531 " <tr>\n",
2532 " <th>98</th>\n",
2533 " <td>M8X</td>\n",
2534 " <td>Etobicoke</td>\n",
2535 " <td>The Kingsway, Montgomery Road, Old Mill North</td>\n",
2536 " <td>43.653654</td>\n",
2537 " <td>-79.506944</td>\n",
2538 " </tr>\n",
2539 " <tr>\n",
2540 " <th>99</th>\n",
2541 " <td>M4Y</td>\n",
2542 " <td>Downtown Toronto</td>\n",
2543 " <td>Church and Wellesley</td>\n",
2544 " <td>43.665860</td>\n",
2545 " <td>-79.383160</td>\n",
2546 " </tr>\n",
2547 " <tr>\n",
2548 " <th>100</th>\n",
2549 " <td>M7Y</td>\n",
2550 " <td>East Toronto</td>\n",
2551 " <td>Business reply mail Processing Centre, South C...</td>\n",
2552 " <td>43.662744</td>\n",
2553 " <td>-79.321558</td>\n",
2554 " </tr>\n",
2555 " <tr>\n",
2556 " <th>101</th>\n",
2557 " <td>M8Y</td>\n",
2558 " <td>Etobicoke</td>\n",
2559 " <td>Old Mill South, King's Mill Park, Sunnylea, Hu...</td>\n",
2560 " <td>43.636258</td>\n",
2561 " <td>-79.498509</td>\n",
2562 " </tr>\n",
2563 " <tr>\n",
2564 " <th>102</th>\n",
2565 " <td>M8Z</td>\n",
2566 " <td>Etobicoke</td>\n",
2567 " <td>Mimico NW, The Queensway West, South of Bloor,...</td>\n",
2568 " <td>43.628841</td>\n",
2569 " <td>-79.520999</td>\n",
2570 " </tr>\n",
2571 " </tbody>\n",
2572 "</table>\n",
2573 "<p>103 rows × 5 columns</p>\n",
2574 "</div>"
2575 ],
2576 "text/plain": [
2577 " Postal Code Borough \\\n",
2578 "0 M3A North York \n",
2579 "1 M4A North York \n",
2580 "2 M5A Downtown Toronto \n",
2581 "3 M6A North York \n",
2582 "4 M7A Downtown Toronto \n",
2583 ".. ... ... \n",
2584 "98 M8X Etobicoke \n",
2585 "99 M4Y Downtown Toronto \n",
2586 "100 M7Y East Toronto \n",
2587 "101 M8Y Etobicoke \n",
2588 "102 M8Z Etobicoke \n",
2589 "\n",
2590 " Neighbourhood Latitude Longitude \n",
2591 "0 Parkwoods 43.753259 -79.329656 \n",
2592 "1 Victoria Village 43.725882 -79.315572 \n",
2593 "2 Regent Park, Harbourfront 43.654260 -79.360636 \n",
2594 "3 Lawrence Manor, Lawrence Heights 43.718518 -79.464763 \n",
2595 "4 Queen's Park, Ontario Provincial Government 43.662301 -79.389494 \n",
2596 ".. ... ... ... \n",
2597 "98 The Kingsway, Montgomery Road, Old Mill North 43.653654 -79.506944 \n",
2598 "99 Church and Wellesley 43.665860 -79.383160 \n",
2599 "100 Business reply mail Processing Centre, South C... 43.662744 -79.321558 \n",
2600 "101 Old Mill South, King's Mill Park, Sunnylea, Hu... 43.636258 -79.498509 \n",
2601 "102 Mimico NW, The Queensway West, South of Bloor,... 43.628841 -79.520999 \n",
2602 "\n",
2603 "[103 rows x 5 columns]"
2604 ]
2605 },
2606 "execution_count": 121,
2607 "metadata": {},
2608 "output_type": "execute_result"
2609 }
2610 ],
2611 "source": [
2612 "df"
2613 ]
2614 },
2615 {
2616 "cell_type": "code",
2617 "execution_count": 113,
2618 "metadata": {},
2619 "outputs": [
2620 {
2621 "data": {
2622 "text/html": [
2623 "<div>\n",
2624 "<style scoped>\n",
2625 " .dataframe tbody tr th:only-of-type {\n",
2626 " vertical-align: middle;\n",
2627 " }\n",
2628 "\n",
2629 " .dataframe tbody tr th {\n",
2630 " vertical-align: top;\n",
2631 " }\n",
2632 "\n",
2633 " .dataframe thead th {\n",
2634 " text-align: right;\n",
2635 " }\n",
2636 "</style>\n",
2637 "<table border=\"1\" class=\"dataframe\">\n",
2638 " <thead>\n",
2639 " <tr style=\"text-align: right;\">\n",
2640 " <th></th>\n",
2641 " <th>Postal Code</th>\n",
2642 " <th>Borough</th>\n",
2643 " <th>Neighbourhood</th>\n",
2644 " <th>Latitude</th>\n",
2645 " <th>Longitude</th>\n",
2646 " <th>Cluster Labels</th>\n",
2647 " <th>1st Most Common Venue</th>\n",
2648 " <th>2nd Most Common Venue</th>\n",
2649 " <th>3rd Most Common Venue</th>\n",
2650 " <th>4th Most Common Venue</th>\n",
2651 " <th>5th Most Common Venue</th>\n",
2652 " <th>6th Most Common Venue</th>\n",
2653 " <th>7th Most Common Venue</th>\n",
2654 " <th>8th Most Common Venue</th>\n",
2655 " <th>9th Most Common Venue</th>\n",
2656 " <th>10th Most Common Venue</th>\n",
2657 " </tr>\n",
2658 " </thead>\n",
2659 " <tbody>\n",
2660 " <tr>\n",
2661 " <th>5</th>\n",
2662 " <td>M9A</td>\n",
2663 " <td>Etobicoke</td>\n",
2664 " <td>Islington Avenue, Humber Valley Village</td>\n",
2665 " <td>43.667856</td>\n",
2666 " <td>-79.532242</td>\n",
2667 " <td>NaN</td>\n",
2668 " <td>NaN</td>\n",
2669 " <td>NaN</td>\n",
2670 " <td>NaN</td>\n",
2671 " <td>NaN</td>\n",
2672 " <td>NaN</td>\n",
2673 " <td>NaN</td>\n",
2674 " <td>NaN</td>\n",
2675 " <td>NaN</td>\n",
2676 " <td>NaN</td>\n",
2677 " <td>NaN</td>\n",
2678 " </tr>\n",
2679 " <tr>\n",
2680 " <th>45</th>\n",
2681 " <td>M2L</td>\n",
2682 " <td>North York</td>\n",
2683 " <td>York Mills, Silver Hills</td>\n",
2684 " <td>43.757490</td>\n",
2685 " <td>-79.374714</td>\n",
2686 " <td>NaN</td>\n",
2687 " <td>NaN</td>\n",
2688 " <td>NaN</td>\n",
2689 " <td>NaN</td>\n",
2690 " <td>NaN</td>\n",
2691 " <td>NaN</td>\n",
2692 " <td>NaN</td>\n",
2693 " <td>NaN</td>\n",
2694 " <td>NaN</td>\n",
2695 " <td>NaN</td>\n",
2696 " <td>NaN</td>\n",
2697 " </tr>\n",
2698 " <tr>\n",
2699 " <th>95</th>\n",
2700 " <td>M1X</td>\n",
2701 " <td>Scarborough</td>\n",
2702 " <td>Upper Rouge</td>\n",
2703 " <td>43.836125</td>\n",
2704 " <td>-79.205636</td>\n",
2705 " <td>NaN</td>\n",
2706 " <td>NaN</td>\n",
2707 " <td>NaN</td>\n",
2708 " <td>NaN</td>\n",
2709 " <td>NaN</td>\n",
2710 " <td>NaN</td>\n",
2711 " <td>NaN</td>\n",
2712 " <td>NaN</td>\n",
2713 " <td>NaN</td>\n",
2714 " <td>NaN</td>\n",
2715 " <td>NaN</td>\n",
2716 " </tr>\n",
2717 " </tbody>\n",
2718 "</table>\n",
2719 "</div>"
2720 ],
2721 "text/plain": [
2722 " Postal Code Borough Neighbourhood \\\n",
2723 "5 M9A Etobicoke Islington Avenue, Humber Valley Village \n",
2724 "45 M2L North York York Mills, Silver Hills \n",
2725 "95 M1X Scarborough Upper Rouge \n",
2726 "\n",
2727 " Latitude Longitude Cluster Labels 1st Most Common Venue \\\n",
2728 "5 43.667856 -79.532242 NaN NaN \n",
2729 "45 43.757490 -79.374714 NaN NaN \n",
2730 "95 43.836125 -79.205636 NaN NaN \n",
2731 "\n",
2732 " 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n",
2733 "5 NaN NaN NaN \n",
2734 "45 NaN NaN NaN \n",
2735 "95 NaN NaN NaN \n",
2736 "\n",
2737 " 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n",
2738 "5 NaN NaN NaN \n",
2739 "45 NaN NaN NaN \n",
2740 "95 NaN NaN NaN \n",
2741 "\n",
2742 " 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n",
2743 "5 NaN NaN NaN \n",
2744 "45 NaN NaN NaN \n",
2745 "95 NaN NaN NaN "
2746 ]
2747 },
2748 "execution_count": 113,
2749 "metadata": {},
2750 "output_type": "execute_result"
2751 }
2752 ],
2753 "source": [
2754 "toronto_merged[toronto_merged['Cluster Labels'].isnull()]"
2755 ]
2756 },
2757 {
2758 "cell_type": "markdown",
2759 "metadata": {},
2760 "source": [
2761 "Plot the clusters in the map"
2762 ]
2763 },
2764 {
2765 "cell_type": "code",
2766 "execution_count": 115,
2767 "metadata": {},
2768 "outputs": [
2769 {
2770 "data": {
2771 "text/html": [
2772 "<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>"
2773 ],
2774 "text/plain": [
2775 "<folium.folium.Map at 0x1a065958388>"
2776 ]
2777 },
2778 "execution_count": 115,
2779 "metadata": {},
2780 "output_type": "execute_result"
2781 }
2782 ],
2783 "source": [
2784 "import matplotlib.cm as cm\n",
2785 "import matplotlib.colors as colors\n",
2786 "\n",
2787 "# create map\n",
2788 "map_clusters = folium.Map(location=[latitude, longitude], zoom_start=11)\n",
2789 "\n",
2790 "# set color scheme for the clusters\n",
2791 "x = np.arange(kclusters)\n",
2792 "ys = [i + x + (i*x)**2 for i in range(kclusters)]\n",
2793 "colors_array = cm.rainbow(np.linspace(0, 1, len(ys)))\n",
2794 "rainbow = [colors.rgb2hex(i) for i in colors_array]\n",
2795 "\n",
2796 "toronto_merged_nonan = toronto_merged.dropna(subset=['Cluster Labels'])\n",
2797 "\n",
2798 "# add markers to the map\n",
2799 "markers_colors = []\n",
2800 "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",
2801 " label = folium.Popup(str(poi) + ' Cluster ' + str(cluster), parse_html=True)\n",
2802 " folium.CircleMarker(\n",
2803 " [lat, lon],\n",
2804 " radius=5,\n",
2805 " popup=label,\n",
2806 " color=rainbow[int(cluster-1)],\n",
2807 " fill=True,\n",
2808 " fill_color=rainbow[int(cluster-1)],\n",
2809 " fill_opacity=0.7).add_to(map_clusters)\n",
2810 " \n",
2811 "map_clusters"
2812 ]
2813 },
2814 {
2815 "cell_type": "markdown",
2816 "metadata": {},
2817 "source": [
2818 "Cluster 1"
2819 ]
2820 },
2821 {
2822 "cell_type": "code",
2823 "execution_count": 116,
2824 "metadata": {},
2825 "outputs": [
2826 {
2827 "data": {
2828 "text/html": [
2829 "<div>\n",
2830 "<style scoped>\n",
2831 " .dataframe tbody tr th:only-of-type {\n",
2832 " vertical-align: middle;\n",
2833 " }\n",
2834 "\n",
2835 " .dataframe tbody tr th {\n",
2836 " vertical-align: top;\n",
2837 " }\n",
2838 "\n",
2839 " .dataframe thead th {\n",
2840 " text-align: right;\n",
2841 " }\n",
2842 "</style>\n",
2843 "<table border=\"1\" class=\"dataframe\">\n",
2844 " <thead>\n",
2845 " <tr style=\"text-align: right;\">\n",
2846 " <th></th>\n",
2847 " <th>Borough</th>\n",
2848 " <th>Cluster Labels</th>\n",
2849 " <th>1st Most Common Venue</th>\n",
2850 " <th>2nd Most Common Venue</th>\n",
2851 " <th>3rd Most Common Venue</th>\n",
2852 " <th>4th Most Common Venue</th>\n",
2853 " <th>5th Most Common Venue</th>\n",
2854 " <th>6th Most Common Venue</th>\n",
2855 " <th>7th Most Common Venue</th>\n",
2856 " <th>8th Most Common Venue</th>\n",
2857 " <th>9th Most Common Venue</th>\n",
2858 " <th>10th Most Common Venue</th>\n",
2859 " </tr>\n",
2860 " </thead>\n",
2861 " <tbody>\n",
2862 " <tr>\n",
2863 " <th>0</th>\n",
2864 " <td>North York</td>\n",
2865 " <td>0.0</td>\n",
2866 " <td>Park</td>\n",
2867 " <td>Food & Drink Shop</td>\n",
2868 " <td>Yoga Studio</td>\n",
2869 " <td>Donut Shop</td>\n",
2870 " <td>Diner</td>\n",
2871 " <td>Discount Store</td>\n",
2872 " <td>Distribution Center</td>\n",
2873 " <td>Dog Run</td>\n",
2874 " <td>Doner Restaurant</td>\n",
2875 " <td>Drugstore</td>\n",
2876 " </tr>\n",
2877 " <tr>\n",
2878 " <th>21</th>\n",
2879 " <td>York</td>\n",
2880 " <td>0.0</td>\n",
2881 " <td>Park</td>\n",
2882 " <td>Women's Store</td>\n",
2883 " <td>Pool</td>\n",
2884 " <td>Yoga Studio</td>\n",
2885 " <td>Doner Restaurant</td>\n",
2886 " <td>Dim Sum Restaurant</td>\n",
2887 " <td>Diner</td>\n",
2888 " <td>Discount Store</td>\n",
2889 " <td>Distribution Center</td>\n",
2890 " <td>Dog Run</td>\n",
2891 " </tr>\n",
2892 " <tr>\n",
2893 " <th>35</th>\n",
2894 " <td>East York</td>\n",
2895 " <td>0.0</td>\n",
2896 " <td>Park</td>\n",
2897 " <td>Convenience Store</td>\n",
2898 " <td>Yoga Studio</td>\n",
2899 " <td>Donut Shop</td>\n",
2900 " <td>Diner</td>\n",
2901 " <td>Discount Store</td>\n",
2902 " <td>Distribution Center</td>\n",
2903 " <td>Dog Run</td>\n",
2904 " <td>Doner Restaurant</td>\n",
2905 " <td>Dumpling Restaurant</td>\n",
2906 " </tr>\n",
2907 " <tr>\n",
2908 " <th>52</th>\n",
2909 " <td>North York</td>\n",
2910 " <td>0.0</td>\n",
2911 " <td>Park</td>\n",
2912 " <td>Yoga Studio</td>\n",
2913 " <td>Donut Shop</td>\n",
2914 " <td>Dim Sum Restaurant</td>\n",
2915 " <td>Diner</td>\n",
2916 " <td>Discount Store</td>\n",
2917 " <td>Distribution Center</td>\n",
2918 " <td>Dog Run</td>\n",
2919 " <td>Doner Restaurant</td>\n",
2920 " <td>Drugstore</td>\n",
2921 " </tr>\n",
2922 " <tr>\n",
2923 " <th>64</th>\n",
2924 " <td>York</td>\n",
2925 " <td>0.0</td>\n",
2926 " <td>Park</td>\n",
2927 " <td>Convenience Store</td>\n",
2928 " <td>Yoga Studio</td>\n",
2929 " <td>Donut Shop</td>\n",
2930 " <td>Diner</td>\n",
2931 " <td>Discount Store</td>\n",
2932 " <td>Distribution Center</td>\n",
2933 " <td>Dog Run</td>\n",
2934 " <td>Doner Restaurant</td>\n",
2935 " <td>Dumpling Restaurant</td>\n",
2936 " </tr>\n",
2937 " <tr>\n",
2938 " <th>66</th>\n",
2939 " <td>North York</td>\n",
2940 " <td>0.0</td>\n",
2941 " <td>Park</td>\n",
2942 " <td>Construction & Landscaping</td>\n",
2943 " <td>Convenience Store</td>\n",
2944 " <td>Yoga Studio</td>\n",
2945 " <td>Donut Shop</td>\n",
2946 " <td>Diner</td>\n",
2947 " <td>Discount Store</td>\n",
2948 " <td>Distribution Center</td>\n",
2949 " <td>Dog Run</td>\n",
2950 " <td>Doner Restaurant</td>\n",
2951 " </tr>\n",
2952 " <tr>\n",
2953 " <th>85</th>\n",
2954 " <td>Scarborough</td>\n",
2955 " <td>0.0</td>\n",
2956 " <td>Park</td>\n",
2957 " <td>Playground</td>\n",
2958 " <td>Coffee Shop</td>\n",
2959 " <td>Yoga Studio</td>\n",
2960 " <td>Doner Restaurant</td>\n",
2961 " <td>Dim Sum Restaurant</td>\n",
2962 " <td>Diner</td>\n",
2963 " <td>Discount Store</td>\n",
2964 " <td>Distribution Center</td>\n",
2965 " <td>Dog Run</td>\n",
2966 " </tr>\n",
2967 " <tr>\n",
2968 " <th>91</th>\n",
2969 " <td>Downtown Toronto</td>\n",
2970 " <td>0.0</td>\n",
2971 " <td>Park</td>\n",
2972 " <td>Trail</td>\n",
2973 " <td>Playground</td>\n",
2974 " <td>Yoga Studio</td>\n",
2975 " <td>Dessert Shop</td>\n",
2976 " <td>Dim Sum Restaurant</td>\n",
2977 " <td>Diner</td>\n",
2978 " <td>Discount Store</td>\n",
2979 " <td>Distribution Center</td>\n",
2980 " <td>Dog Run</td>\n",
2981 " </tr>\n",
2982 " </tbody>\n",
2983 "</table>\n",
2984 "</div>"
2985 ],
2986 "text/plain": [
2987 " Borough Cluster Labels 1st Most Common Venue \\\n",
2988 "0 North York 0.0 Park \n",
2989 "21 York 0.0 Park \n",
2990 "35 East York 0.0 Park \n",
2991 "52 North York 0.0 Park \n",
2992 "64 York 0.0 Park \n",
2993 "66 North York 0.0 Park \n",
2994 "85 Scarborough 0.0 Park \n",
2995 "91 Downtown Toronto 0.0 Park \n",
2996 "\n",
2997 " 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n",
2998 "0 Food & Drink Shop Yoga Studio Donut Shop \n",
2999 "21 Women's Store Pool Yoga Studio \n",
3000 "35 Convenience Store Yoga Studio Donut Shop \n",
3001 "52 Yoga Studio Donut Shop Dim Sum Restaurant \n",
3002 "64 Convenience Store Yoga Studio Donut Shop \n",
3003 "66 Construction & Landscaping Convenience Store Yoga Studio \n",
3004 "85 Playground Coffee Shop Yoga Studio \n",
3005 "91 Trail Playground Yoga Studio \n",
3006 "\n",
3007 " 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n",
3008 "0 Diner Discount Store Distribution Center \n",
3009 "21 Doner Restaurant Dim Sum Restaurant Diner \n",
3010 "35 Diner Discount Store Distribution Center \n",
3011 "52 Diner Discount Store Distribution Center \n",
3012 "64 Diner Discount Store Distribution Center \n",
3013 "66 Donut Shop Diner Discount Store \n",
3014 "85 Doner Restaurant Dim Sum Restaurant Diner \n",
3015 "91 Dessert Shop Dim Sum Restaurant Diner \n",
3016 "\n",
3017 " 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n",
3018 "0 Dog Run Doner Restaurant Drugstore \n",
3019 "21 Discount Store Distribution Center Dog Run \n",
3020 "35 Dog Run Doner Restaurant Dumpling Restaurant \n",
3021 "52 Dog Run Doner Restaurant Drugstore \n",
3022 "64 Dog Run Doner Restaurant Dumpling Restaurant \n",
3023 "66 Distribution Center Dog Run Doner Restaurant \n",
3024 "85 Discount Store Distribution Center Dog Run \n",
3025 "91 Discount Store Distribution Center Dog Run "
3026 ]
3027 },
3028 "execution_count": 116,
3029 "metadata": {},
3030 "output_type": "execute_result"
3031 }
3032 ],
3033 "source": [
3034 "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 0, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3035 ]
3036 },
3037 {
3038 "cell_type": "markdown",
3039 "metadata": {},
3040 "source": [
3041 "Cluster 2"
3042 ]
3043 },
3044 {
3045 "cell_type": "code",
3046 "execution_count": 117,
3047 "metadata": {},
3048 "outputs": [
3049 {
3050 "data": {
3051 "text/html": [
3052 "<div>\n",
3053 "<style scoped>\n",
3054 " .dataframe tbody tr th:only-of-type {\n",
3055 " vertical-align: middle;\n",
3056 " }\n",
3057 "\n",
3058 " .dataframe tbody tr th {\n",
3059 " vertical-align: top;\n",
3060 " }\n",
3061 "\n",
3062 " .dataframe thead th {\n",
3063 " text-align: right;\n",
3064 " }\n",
3065 "</style>\n",
3066 "<table border=\"1\" class=\"dataframe\">\n",
3067 " <thead>\n",
3068 " <tr style=\"text-align: right;\">\n",
3069 " <th></th>\n",
3070 " <th>Borough</th>\n",
3071 " <th>Cluster Labels</th>\n",
3072 " <th>1st Most Common Venue</th>\n",
3073 " <th>2nd Most Common Venue</th>\n",
3074 " <th>3rd Most Common Venue</th>\n",
3075 " <th>4th Most Common Venue</th>\n",
3076 " <th>5th Most Common Venue</th>\n",
3077 " <th>6th Most Common Venue</th>\n",
3078 " <th>7th Most Common Venue</th>\n",
3079 " <th>8th Most Common Venue</th>\n",
3080 " <th>9th Most Common Venue</th>\n",
3081 " <th>10th Most Common Venue</th>\n",
3082 " </tr>\n",
3083 " </thead>\n",
3084 " <tbody>\n",
3085 " <tr>\n",
3086 " <th>1</th>\n",
3087 " <td>North York</td>\n",
3088 " <td>1.0</td>\n",
3089 " <td>Hockey Arena</td>\n",
3090 " <td>Pizza Place</td>\n",
3091 " <td>Coffee Shop</td>\n",
3092 " <td>Portuguese Restaurant</td>\n",
3093 " <td>Yoga Studio</td>\n",
3094 " <td>Dim Sum Restaurant</td>\n",
3095 " <td>Diner</td>\n",
3096 " <td>Discount Store</td>\n",
3097 " <td>Distribution Center</td>\n",
3098 " <td>Dog Run</td>\n",
3099 " </tr>\n",
3100 " <tr>\n",
3101 " <th>2</th>\n",
3102 " <td>Downtown Toronto</td>\n",
3103 " <td>1.0</td>\n",
3104 " <td>Coffee Shop</td>\n",
3105 " <td>Bakery</td>\n",
3106 " <td>Pub</td>\n",
3107 " <td>Park</td>\n",
3108 " <td>Breakfast Spot</td>\n",
3109 " <td>Café</td>\n",
3110 " <td>Theater</td>\n",
3111 " <td>Yoga Studio</td>\n",
3112 " <td>Mexican Restaurant</td>\n",
3113 " <td>Shoe Store</td>\n",
3114 " </tr>\n",
3115 " <tr>\n",
3116 " <th>3</th>\n",
3117 " <td>North York</td>\n",
3118 " <td>1.0</td>\n",
3119 " <td>Clothing Store</td>\n",
3120 " <td>Accessories Store</td>\n",
3121 " <td>Coffee Shop</td>\n",
3122 " <td>Boutique</td>\n",
3123 " <td>Miscellaneous Shop</td>\n",
3124 " <td>Event Space</td>\n",
3125 " <td>Furniture / Home Store</td>\n",
3126 " <td>Women's Store</td>\n",
3127 " <td>Vietnamese Restaurant</td>\n",
3128 " <td>Convenience Store</td>\n",
3129 " </tr>\n",
3130 " <tr>\n",
3131 " <th>4</th>\n",
3132 " <td>Downtown Toronto</td>\n",
3133 " <td>1.0</td>\n",
3134 " <td>Coffee Shop</td>\n",
3135 " <td>Diner</td>\n",
3136 " <td>Yoga Studio</td>\n",
3137 " <td>Bar</td>\n",
3138 " <td>Beer Bar</td>\n",
3139 " <td>Smoothie Shop</td>\n",
3140 " <td>Sandwich Place</td>\n",
3141 " <td>Burrito Place</td>\n",
3142 " <td>Café</td>\n",
3143 " <td>Park</td>\n",
3144 " </tr>\n",
3145 " <tr>\n",
3146 " <th>6</th>\n",
3147 " <td>Scarborough</td>\n",
3148 " <td>1.0</td>\n",
3149 " <td>Print Shop</td>\n",
3150 " <td>Fast Food Restaurant</td>\n",
3151 " <td>Yoga Studio</td>\n",
3152 " <td>Dim Sum Restaurant</td>\n",
3153 " <td>Diner</td>\n",
3154 " <td>Discount Store</td>\n",
3155 " <td>Distribution Center</td>\n",
3156 " <td>Dog Run</td>\n",
3157 " <td>Doner Restaurant</td>\n",
3158 " <td>Donut Shop</td>\n",
3159 " </tr>\n",
3160 " <tr>\n",
3161 " <th>...</th>\n",
3162 " <td>...</td>\n",
3163 " <td>...</td>\n",
3164 " <td>...</td>\n",
3165 " <td>...</td>\n",
3166 " <td>...</td>\n",
3167 " <td>...</td>\n",
3168 " <td>...</td>\n",
3169 " <td>...</td>\n",
3170 " <td>...</td>\n",
3171 " <td>...</td>\n",
3172 " <td>...</td>\n",
3173 " <td>...</td>\n",
3174 " </tr>\n",
3175 " <tr>\n",
3176 " <th>97</th>\n",
3177 " <td>Downtown Toronto</td>\n",
3178 " <td>1.0</td>\n",
3179 " <td>Coffee Shop</td>\n",
3180 " <td>Café</td>\n",
3181 " <td>Hotel</td>\n",
3182 " <td>Restaurant</td>\n",
3183 " <td>Gym</td>\n",
3184 " <td>Japanese Restaurant</td>\n",
3185 " <td>American Restaurant</td>\n",
3186 " <td>Steakhouse</td>\n",
3187 " <td>Asian Restaurant</td>\n",
3188 " <td>Seafood Restaurant</td>\n",
3189 " </tr>\n",
3190 " <tr>\n",
3191 " <th>98</th>\n",
3192 " <td>Etobicoke</td>\n",
3193 " <td>1.0</td>\n",
3194 " <td>River</td>\n",
3195 " <td>Doner Restaurant</td>\n",
3196 " <td>Dessert Shop</td>\n",
3197 " <td>Dim Sum Restaurant</td>\n",
3198 " <td>Diner</td>\n",
3199 " <td>Discount Store</td>\n",
3200 " <td>Distribution Center</td>\n",
3201 " <td>Dog Run</td>\n",
3202 " <td>Yoga Studio</td>\n",
3203 " <td>Department Store</td>\n",
3204 " </tr>\n",
3205 " <tr>\n",
3206 " <th>99</th>\n",
3207 " <td>Downtown Toronto</td>\n",
3208 " <td>1.0</td>\n",
3209 " <td>Coffee Shop</td>\n",
3210 " <td>Sushi Restaurant</td>\n",
3211 " <td>Japanese Restaurant</td>\n",
3212 " <td>Gay Bar</td>\n",
3213 " <td>Restaurant</td>\n",
3214 " <td>Yoga Studio</td>\n",
3215 " <td>Bubble Tea Shop</td>\n",
3216 " <td>Dance Studio</td>\n",
3217 " <td>Mediterranean Restaurant</td>\n",
3218 " <td>Men's Store</td>\n",
3219 " </tr>\n",
3220 " <tr>\n",
3221 " <th>100</th>\n",
3222 " <td>East Toronto</td>\n",
3223 " <td>1.0</td>\n",
3224 " <td>Light Rail Station</td>\n",
3225 " <td>Yoga Studio</td>\n",
3226 " <td>Auto Workshop</td>\n",
3227 " <td>Smoke Shop</td>\n",
3228 " <td>Brewery</td>\n",
3229 " <td>Spa</td>\n",
3230 " <td>Farmers Market</td>\n",
3231 " <td>Fast Food Restaurant</td>\n",
3232 " <td>Burrito Place</td>\n",
3233 " <td>Restaurant</td>\n",
3234 " </tr>\n",
3235 " <tr>\n",
3236 " <th>102</th>\n",
3237 " <td>Etobicoke</td>\n",
3238 " <td>1.0</td>\n",
3239 " <td>Grocery Store</td>\n",
3240 " <td>Tanning Salon</td>\n",
3241 " <td>Convenience Store</td>\n",
3242 " <td>Discount Store</td>\n",
3243 " <td>Burrito Place</td>\n",
3244 " <td>Burger Joint</td>\n",
3245 " <td>Sandwich Place</td>\n",
3246 " <td>Kids Store</td>\n",
3247 " <td>Supplement Shop</td>\n",
3248 " <td>Bakery</td>\n",
3249 " </tr>\n",
3250 " </tbody>\n",
3251 "</table>\n",
3252 "<p>87 rows × 12 columns</p>\n",
3253 "</div>"
3254 ],
3255 "text/plain": [
3256 " Borough Cluster Labels 1st Most Common Venue \\\n",
3257 "1 North York 1.0 Hockey Arena \n",
3258 "2 Downtown Toronto 1.0 Coffee Shop \n",
3259 "3 North York 1.0 Clothing Store \n",
3260 "4 Downtown Toronto 1.0 Coffee Shop \n",
3261 "6 Scarborough 1.0 Print Shop \n",
3262 ".. ... ... ... \n",
3263 "97 Downtown Toronto 1.0 Coffee Shop \n",
3264 "98 Etobicoke 1.0 River \n",
3265 "99 Downtown Toronto 1.0 Coffee Shop \n",
3266 "100 East Toronto 1.0 Light Rail Station \n",
3267 "102 Etobicoke 1.0 Grocery Store \n",
3268 "\n",
3269 " 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n",
3270 "1 Pizza Place Coffee Shop Portuguese Restaurant \n",
3271 "2 Bakery Pub Park \n",
3272 "3 Accessories Store Coffee Shop Boutique \n",
3273 "4 Diner Yoga Studio Bar \n",
3274 "6 Fast Food Restaurant Yoga Studio Dim Sum Restaurant \n",
3275 ".. ... ... ... \n",
3276 "97 Café Hotel Restaurant \n",
3277 "98 Doner Restaurant Dessert Shop Dim Sum Restaurant \n",
3278 "99 Sushi Restaurant Japanese Restaurant Gay Bar \n",
3279 "100 Yoga Studio Auto Workshop Smoke Shop \n",
3280 "102 Tanning Salon Convenience Store Discount Store \n",
3281 "\n",
3282 " 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n",
3283 "1 Yoga Studio Dim Sum Restaurant Diner \n",
3284 "2 Breakfast Spot Café Theater \n",
3285 "3 Miscellaneous Shop Event Space Furniture / Home Store \n",
3286 "4 Beer Bar Smoothie Shop Sandwich Place \n",
3287 "6 Diner Discount Store Distribution Center \n",
3288 ".. ... ... ... \n",
3289 "97 Gym Japanese Restaurant American Restaurant \n",
3290 "98 Diner Discount Store Distribution Center \n",
3291 "99 Restaurant Yoga Studio Bubble Tea Shop \n",
3292 "100 Brewery Spa Farmers Market \n",
3293 "102 Burrito Place Burger Joint Sandwich Place \n",
3294 "\n",
3295 " 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n",
3296 "1 Discount Store Distribution Center Dog Run \n",
3297 "2 Yoga Studio Mexican Restaurant Shoe Store \n",
3298 "3 Women's Store Vietnamese Restaurant Convenience Store \n",
3299 "4 Burrito Place Café Park \n",
3300 "6 Dog Run Doner Restaurant Donut Shop \n",
3301 ".. ... ... ... \n",
3302 "97 Steakhouse Asian Restaurant Seafood Restaurant \n",
3303 "98 Dog Run Yoga Studio Department Store \n",
3304 "99 Dance Studio Mediterranean Restaurant Men's Store \n",
3305 "100 Fast Food Restaurant Burrito Place Restaurant \n",
3306 "102 Kids Store Supplement Shop Bakery \n",
3307 "\n",
3308 "[87 rows x 12 columns]"
3309 ]
3310 },
3311 "execution_count": 117,
3312 "metadata": {},
3313 "output_type": "execute_result"
3314 }
3315 ],
3316 "source": [
3317 "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 1, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3318 ]
3319 },
3320 {
3321 "cell_type": "markdown",
3322 "metadata": {},
3323 "source": [
3324 "Cluster 3"
3325 ]
3326 },
3327 {
3328 "cell_type": "code",
3329 "execution_count": 118,
3330 "metadata": {},
3331 "outputs": [
3332 {
3333 "data": {
3334 "text/html": [
3335 "<div>\n",
3336 "<style scoped>\n",
3337 " .dataframe tbody tr th:only-of-type {\n",
3338 " vertical-align: middle;\n",
3339 " }\n",
3340 "\n",
3341 " .dataframe tbody tr th {\n",
3342 " vertical-align: top;\n",
3343 " }\n",
3344 "\n",
3345 " .dataframe thead th {\n",
3346 " text-align: right;\n",
3347 " }\n",
3348 "</style>\n",
3349 "<table border=\"1\" class=\"dataframe\">\n",
3350 " <thead>\n",
3351 " <tr style=\"text-align: right;\">\n",
3352 " <th></th>\n",
3353 " <th>Borough</th>\n",
3354 " <th>Cluster Labels</th>\n",
3355 " <th>1st Most Common Venue</th>\n",
3356 " <th>2nd Most Common Venue</th>\n",
3357 " <th>3rd Most Common Venue</th>\n",
3358 " <th>4th Most Common Venue</th>\n",
3359 " <th>5th Most Common Venue</th>\n",
3360 " <th>6th Most Common Venue</th>\n",
3361 " <th>7th Most Common Venue</th>\n",
3362 " <th>8th Most Common Venue</th>\n",
3363 " <th>9th Most Common Venue</th>\n",
3364 " <th>10th Most Common Venue</th>\n",
3365 " </tr>\n",
3366 " </thead>\n",
3367 " <tbody>\n",
3368 " <tr>\n",
3369 " <th>32</th>\n",
3370 " <td>Scarborough</td>\n",
3371 " <td>2.0</td>\n",
3372 " <td>Pizza Place</td>\n",
3373 " <td>Playground</td>\n",
3374 " <td>Doner Restaurant</td>\n",
3375 " <td>Dessert Shop</td>\n",
3376 " <td>Dim Sum Restaurant</td>\n",
3377 " <td>Diner</td>\n",
3378 " <td>Discount Store</td>\n",
3379 " <td>Distribution Center</td>\n",
3380 " <td>Dog Run</td>\n",
3381 " <td>Donut Shop</td>\n",
3382 " </tr>\n",
3383 " <tr>\n",
3384 " <th>50</th>\n",
3385 " <td>North York</td>\n",
3386 " <td>2.0</td>\n",
3387 " <td>Pizza Place</td>\n",
3388 " <td>Department Store</td>\n",
3389 " <td>Event Space</td>\n",
3390 " <td>Ethiopian Restaurant</td>\n",
3391 " <td>Electronics Store</td>\n",
3392 " <td>Eastern European Restaurant</td>\n",
3393 " <td>Dumpling Restaurant</td>\n",
3394 " <td>Drugstore</td>\n",
3395 " <td>Donut Shop</td>\n",
3396 " <td>Doner Restaurant</td>\n",
3397 " </tr>\n",
3398 " </tbody>\n",
3399 "</table>\n",
3400 "</div>"
3401 ],
3402 "text/plain": [
3403 " Borough Cluster Labels 1st Most Common Venue 2nd Most Common Venue \\\n",
3404 "32 Scarborough 2.0 Pizza Place Playground \n",
3405 "50 North York 2.0 Pizza Place Department Store \n",
3406 "\n",
3407 " 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
3408 "32 Doner Restaurant Dessert Shop Dim Sum Restaurant \n",
3409 "50 Event Space Ethiopian Restaurant Electronics Store \n",
3410 "\n",
3411 " 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
3412 "32 Diner Discount Store Distribution Center \n",
3413 "50 Eastern European Restaurant Dumpling Restaurant Drugstore \n",
3414 "\n",
3415 " 9th Most Common Venue 10th Most Common Venue \n",
3416 "32 Dog Run Donut Shop \n",
3417 "50 Donut Shop Doner Restaurant "
3418 ]
3419 },
3420 "execution_count": 118,
3421 "metadata": {},
3422 "output_type": "execute_result"
3423 }
3424 ],
3425 "source": [
3426 "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 2, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3427 ]
3428 },
3429 {
3430 "cell_type": "markdown",
3431 "metadata": {},
3432 "source": [
3433 "Cluster 4"
3434 ]
3435 },
3436 {
3437 "cell_type": "code",
3438 "execution_count": 119,
3439 "metadata": {},
3440 "outputs": [
3441 {
3442 "data": {
3443 "text/html": [
3444 "<div>\n",
3445 "<style scoped>\n",
3446 " .dataframe tbody tr th:only-of-type {\n",
3447 " vertical-align: middle;\n",
3448 " }\n",
3449 "\n",
3450 " .dataframe tbody tr th {\n",
3451 " vertical-align: top;\n",
3452 " }\n",
3453 "\n",
3454 " .dataframe thead th {\n",
3455 " text-align: right;\n",
3456 " }\n",
3457 "</style>\n",
3458 "<table border=\"1\" class=\"dataframe\">\n",
3459 " <thead>\n",
3460 " <tr style=\"text-align: right;\">\n",
3461 " <th></th>\n",
3462 " <th>Borough</th>\n",
3463 " <th>Cluster Labels</th>\n",
3464 " <th>1st Most Common Venue</th>\n",
3465 " <th>2nd Most Common Venue</th>\n",
3466 " <th>3rd Most Common Venue</th>\n",
3467 " <th>4th Most Common Venue</th>\n",
3468 " <th>5th Most Common Venue</th>\n",
3469 " <th>6th Most Common Venue</th>\n",
3470 " <th>7th Most Common Venue</th>\n",
3471 " <th>8th Most Common Venue</th>\n",
3472 " <th>9th Most Common Venue</th>\n",
3473 " <th>10th Most Common Venue</th>\n",
3474 " </tr>\n",
3475 " </thead>\n",
3476 " <tbody>\n",
3477 " <tr>\n",
3478 " <th>57</th>\n",
3479 " <td>North York</td>\n",
3480 " <td>3.0</td>\n",
3481 " <td>Fabric Shop</td>\n",
3482 " <td>Baseball Field</td>\n",
3483 " <td>Yoga Studio</td>\n",
3484 " <td>Donut Shop</td>\n",
3485 " <td>Diner</td>\n",
3486 " <td>Discount Store</td>\n",
3487 " <td>Distribution Center</td>\n",
3488 " <td>Dog Run</td>\n",
3489 " <td>Doner Restaurant</td>\n",
3490 " <td>Drugstore</td>\n",
3491 " </tr>\n",
3492 " <tr>\n",
3493 " <th>101</th>\n",
3494 " <td>Etobicoke</td>\n",
3495 " <td>3.0</td>\n",
3496 " <td>Baseball Field</td>\n",
3497 " <td>Yoga Studio</td>\n",
3498 " <td>Donut Shop</td>\n",
3499 " <td>Diner</td>\n",
3500 " <td>Discount Store</td>\n",
3501 " <td>Distribution Center</td>\n",
3502 " <td>Dog Run</td>\n",
3503 " <td>Doner Restaurant</td>\n",
3504 " <td>Drugstore</td>\n",
3505 " <td>Farmers Market</td>\n",
3506 " </tr>\n",
3507 " </tbody>\n",
3508 "</table>\n",
3509 "</div>"
3510 ],
3511 "text/plain": [
3512 " Borough Cluster Labels 1st Most Common Venue 2nd Most Common Venue \\\n",
3513 "57 North York 3.0 Fabric Shop Baseball Field \n",
3514 "101 Etobicoke 3.0 Baseball Field Yoga Studio \n",
3515 "\n",
3516 " 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
3517 "57 Yoga Studio Donut Shop Diner \n",
3518 "101 Donut Shop Diner Discount Store \n",
3519 "\n",
3520 " 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
3521 "57 Discount Store Distribution Center Dog Run \n",
3522 "101 Distribution Center Dog Run Doner Restaurant \n",
3523 "\n",
3524 " 9th Most Common Venue 10th Most Common Venue \n",
3525 "57 Doner Restaurant Drugstore \n",
3526 "101 Drugstore Farmers Market "
3527 ]
3528 },
3529 "execution_count": 119,
3530 "metadata": {},
3531 "output_type": "execute_result"
3532 }
3533 ],
3534 "source": [
3535 "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 3, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3536 ]
3537 },
3538 {
3539 "cell_type": "markdown",
3540 "metadata": {},
3541 "source": [
3542 "Cluster 5"
3543 ]
3544 },
3545 {
3546 "cell_type": "code",
3547 "execution_count": 120,
3548 "metadata": {},
3549 "outputs": [
3550 {
3551 "data": {
3552 "text/html": [
3553 "<div>\n",
3554 "<style scoped>\n",
3555 " .dataframe tbody tr th:only-of-type {\n",
3556 " vertical-align: middle;\n",
3557 " }\n",
3558 "\n",
3559 " .dataframe tbody tr th {\n",
3560 " vertical-align: top;\n",
3561 " }\n",
3562 "\n",
3563 " .dataframe thead th {\n",
3564 " text-align: right;\n",
3565 " }\n",
3566 "</style>\n",
3567 "<table border=\"1\" class=\"dataframe\">\n",
3568 " <thead>\n",
3569 " <tr style=\"text-align: right;\">\n",
3570 " <th></th>\n",
3571 " <th>Borough</th>\n",
3572 " <th>Cluster Labels</th>\n",
3573 " <th>1st Most Common Venue</th>\n",
3574 " <th>2nd Most Common Venue</th>\n",
3575 " <th>3rd Most Common Venue</th>\n",
3576 " <th>4th Most Common Venue</th>\n",
3577 " <th>5th Most Common Venue</th>\n",
3578 " <th>6th Most Common Venue</th>\n",
3579 " <th>7th Most Common Venue</th>\n",
3580 " <th>8th Most Common Venue</th>\n",
3581 " <th>9th Most Common Venue</th>\n",
3582 " <th>10th Most Common Venue</th>\n",
3583 " </tr>\n",
3584 " </thead>\n",
3585 " <tbody>\n",
3586 " <tr>\n",
3587 " <th>11</th>\n",
3588 " <td>Etobicoke</td>\n",
3589 " <td>4.0</td>\n",
3590 " <td>Jewelry Store</td>\n",
3591 " <td>Yoga Studio</td>\n",
3592 " <td>Diner</td>\n",
3593 " <td>Discount Store</td>\n",
3594 " <td>Distribution Center</td>\n",
3595 " <td>Dog Run</td>\n",
3596 " <td>Doner Restaurant</td>\n",
3597 " <td>Donut Shop</td>\n",
3598 " <td>Drugstore</td>\n",
3599 " <td>Farmers Market</td>\n",
3600 " </tr>\n",
3601 " </tbody>\n",
3602 "</table>\n",
3603 "</div>"
3604 ],
3605 "text/plain": [
3606 " Borough Cluster Labels 1st Most Common Venue 2nd Most Common Venue \\\n",
3607 "11 Etobicoke 4.0 Jewelry Store Yoga Studio \n",
3608 "\n",
3609 " 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
3610 "11 Diner Discount Store Distribution Center \n",
3611 "\n",
3612 " 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
3613 "11 Dog Run Doner Restaurant Donut Shop \n",
3614 "\n",
3615 " 9th Most Common Venue 10th Most Common Venue \n",
3616 "11 Drugstore Farmers Market "
3617 ]
3618 },
3619 "execution_count": 120,
3620 "metadata": {},
3621 "output_type": "execute_result"
3622 }
3623 ],
3624 "source": [
3625 "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 4, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3626 ]
3627 }
3628 ],
3629 "metadata": {
3630 "kernelspec": {
3631 "display_name": "Python 3",
3632 "language": "python",
3633 "name": "python3"
3634 },
3635 "language_info": {
3636 "codemirror_mode": {
3637 "name": "ipython",
3638 "version": 3
3639 },
3640 "file_extension": ".py",
3641 "mimetype": "text/x-python",
3642 "name": "python",
3643 "nbconvert_exporter": "python",
3644 "pygments_lexer": "ipython3",
3645 "version": "3.7.6"
3646 }
3647 },
3648 "nbformat": 4,
3649 "nbformat_minor": 4
3650}