Wikipedia
testwiki
https://test.wikipedia.org/wiki/Main_Page
MediaWiki 1.47.0-wmf.13
first-letter
Media
Special
Talk
User
User talk
Wikipedia
Wikipedia talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
Thread
Thread talk
Summary
Summary talk
Test namespace 1
Test namespace 1 talk
Test namespace 2
Test namespace 2 talk
Draft
Draft talk
Campaign
Campaign talk
TimedText
TimedText talk
Module
Module talk
SecurePoll
SecurePoll talk
CNBanner
CNBanner talk
Translations
Translations talk
Event
Event talk
Topic
Newsletter
Newsletter talk
Wikipedia:Test
4
71460
754618
754502
2026-08-01T22:20:12Z
~2026-42828-85
75114
754618
wikitext
text/x-wiki
= Test =
801
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24.
2:6 - 7:12, 157 days, (7:13+ to fill out).
*7:13, 7:14, 7:15 (?)
*7:16, 7:17, 7:18, 7:19, 7:20 (?)
*7:21, 7:22, 7:23, 7:24, 7:25 (?)
*7:26 (?)
*7:27 (?)
*7:28 (?)
*7:29 (7:30)
''7:31''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
Current, 202 6711. ($#!+).
*202 6712. (ALDI Stores, Australia, Worldwide).
''2026713''
4a2f7xghnqmxwrbblnnu2688yvmsqmf
754620
754618
2026-08-01T22:20:29Z
~2026-42828-85
75114
754620
wikitext
text/x-wiki
= Test =
801 - Size
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24.
2:6 - 7:12, 157 days, (7:13+ to fill out).
*7:13, 7:14, 7:15 (?)
*7:16, 7:17, 7:18, 7:19, 7:20 (?)
*7:21, 7:22, 7:23, 7:24, 7:25 (?)
*7:26 (?)
*7:27 (?)
*7:28 (?)
*7:29 (7:30)
''7:31''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
Current, 202 6711. ($#!+).
*202 6712. (ALDI Stores, Australia, Worldwide).
''2026713''
mq78h198oo5bpg5iiukuh3r23u8zpfd
754621
754620
2026-08-01T22:20:44Z
~2026-42828-85
75114
754621
wikitext
text/x-wiki
= Test =
801 - Board Sizes
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24.
2:6 - 7:12, 157 days, (7:13+ to fill out).
*7:13, 7:14, 7:15 (?)
*7:16, 7:17, 7:18, 7:19, 7:20 (?)
*7:21, 7:22, 7:23, 7:24, 7:25 (?)
*7:26 (?)
*7:27 (?)
*7:28 (?)
*7:29 (7:30)
''7:31''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
Current, 202 6711. ($#!+).
*202 6712. (ALDI Stores, Australia, Worldwide).
''2026713''
lf2mrzu16olgqllmi6kzvo093kh9ht4
754622
754621
2026-08-01T22:21:04Z
~2026-42828-85
75114
754622
wikitext
text/x-wiki
= Test =
801 - Board Sizes
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24.
2:6 - 7:12, 157 days, (7:13+ to fill out).
*7:13, 7:14, 7:15 (?)
*7:16, 7:17, 7:18, 7:19, 7:20 (?)
*7:21, 7:22, 7:23, 7:24, 7:25 (?)
*7:26 (?)
*7:27 (?)
*7:28 (?)
*7:29 (?)
*7:30 (7:31)
''8:1''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
Current, 202 6711. ($#!+).
*202 6712. (ALDI Stores, Australia, Worldwide).
''2026713''
gbimlvmy4nkyfnogqa8gy55k9cexb9b
754623
754622
2026-08-01T22:21:19Z
~2026-42828-85
75114
754623
wikitext
text/x-wiki
= Test =
801 - Level Board Sizes
Candy Crush Saga Wiki: Tasty Sugar Track Edits Is Out Of Control (TST) and continue until least Next Year, Most Edits were made on 6/23, No New Episodes Will Be Released on 6/24.
2:6 - 7:12, 157 days, (7:13+ to fill out).
*7:13, 7:14, 7:15 (?)
*7:16, 7:17, 7:18, 7:19, 7:20 (?)
*7:21, 7:22, 7:23, 7:24, 7:25 (?)
*7:26 (?)
*7:27 (?)
*7:28 (?)
*7:29 (?)
*7:30 (7:31)
''8:1''
*202 6525, Pot with Fork and Spoon, Bags with Sunglasses.
*202 6526, Baskets, Tobacco Stuff or Socks.
*202 6527, Food Shopping like Cola Bottles, Cans, Cordial and Others.
*202 6528, Socks, Pairs of Shoes, Dressing Gowns.
*202 6529, Towels, Cubes with Things.
*202 6530, Cloths, Flowers Frisun or Soap.
*202 6531, Food Shopping like Party Pies, Waters and Others.
*202 6601, Pairs of Boots, Pillow or Podiatrist.
*202 6602, Plates or Pans, Grated Cheese or Baskets.
*202 6603, Forks, Pans and Other Kitchen Tools.
*202 6604, Cups, Cordial Jug or Strawberry Milk.
*202 6605, Food Shopping like Cans of Coca Cola, Waters, Cordials or Pile of Sauce.
*202 6606, Purses, Lu Papers or Paper Towels.
*202 6607, Candles, Statues or Pizza Boxes.
*202 6608, Cups, Blankets and Others.
*202 6609, Food Shoppibg like Cola Bottles, Sour Cream and Onion Chips or Cans.
*202 6610, Towels, Cloths, Soap or Containers.
*202 6611, Nachos, Apple N Raspberry Codrial or Stationary.
*202 6612, Basket, Electric Bed with Instructions or Paint.
*202 6613, Aerobar, Birthday Cake or Packet of Candles.
*202 6614, Plates, Blankets or even Vacuum Cleaner.
*202 6615, Towels, Cloths or Dressing Gowns.
*202 6616, Smiths Chips, Heater Vents, Stuff for Lasagna or Cloths.
*202 6617, Pans, Table Spoons or Lids.
*202 6618, Food Shopping like Cans of Coca Cola, Waters, Milk and Others.
*202 6619, Chocolate Milk, Cups of Tea or Extra Mints.
*202 6620, Kitkats, Pens or Domino's Pizza.
*202 6621, Blankets and Pillows or Vacuum Cleaner.
*202 6622, Tea Towels, Cans of Coca Cola or Carlton Draught.
*202 6623, Food Shopping like Bottles of Cola, Waters or New Pyjamas.
*202 6624, Staples, Socks, Hats and Others.
*202 6625, Kitchen Bowls, Pans and Others.
*202 6626, Food Shopping like Colas, Milk or Rainbow Paddlepop.
*202 6627, Tablemats, Sunglasses or Garden Plant.
*202 6628, Boots, Sleep Medicine or Pillow.
*202 6629, Sewing Machine, Tobacco Stuff or Pan.
*202 6630, Food Shopping like Cans of Cocacola, Bottles, Kitkat or M&Ms.
*202 6701, BBQ Chips, Biskits or Grated Cheese.
*202 6702, Lighters, Plates or Cloths.
*202 6703, Hot Dogs, Cola Cans or Lasagna.
*202 6704, Mop, Battery Packs or Doorhandle.
*202 6705, Video Cameras, Internet or McDonalds Bag?.
*202 6706, Pans, Freshmint, or Hotdog Roll.
*202 6707, Food Shopping like Cans of Coca Cola, Cola Bottles, Waters, Shopping Bag or Grated Cheese.
*202 6708, Ktimes, Nutrigrain or Mueslibars.
*202 6709, Saladas, Socks, Vegemite or Textures.
*202 6710, Baskets, Favourites or Cordial Jug.
Current, 202 6711. ($#!+).
*202 6712. (ALDI Stores, Australia, Worldwide).
''2026713''
f2l18j1d146cmc3bv1ftdhnk6axxpfz
User:Revi C.
2
74051
754627
622553
2026-08-01T23:37:11Z
Pathoschild
469
global user pages ([[m:Synchbot|requested by Revi C.]])
754627
wikitext
text/x-wiki
__NOINDEX__<div class="mw-content-ltr" lang="en" dir="ltr">{{#babel:ko|en-3|}} [[File:Revi wikimedia image.jpg|thumb|center|middle|If you are here to talk about CommonsDelinker removing a deleted image, please [[:c:User talk:Revi C.|go here]].]]
Hello! I am [[:m:User:Revi C.|revi]]. I edit to [[m:SWMT|revert vandals]], do Wikidata stuff<!--(I am a Wikidata Admin! <small>([{{fullurl:wikidata:Special:ListUsers/Revi C.|limit=1}} Verify])</small>)-->, or do [[:c:COM:FR|Commons Filemoving stuff]] (I am Commons Admin too! <small>([{{fullurl:c:Special:ListUsers/Revi C.|limit=1}} Verify])</small>). Come to [[:m:User:Revi C.|my Meta userpage]] or [[:c:User:Revi C.|my Commons userpage]] for more information. Thank you.</div>
s7l31vm7btg9p7hwj4hy4wj4v6hxgyh
User talk:Revi C.
3
74673
754626
622552
2026-08-01T23:01:59Z
Pathoschild
469
global user pages ([[m:Synchbot|requested by Revi C.]])
754626
wikitext
text/x-wiki
__NOINDEX__<div class="mw-content-ltr" lang="en" dir="ltr">[[File:Revi logo (pink).png|thumb|center|<span style="color:red">PLEASE DO NOT LEAVE MESSAGE HERE!</span>]]
''' <span style="color:red"> BEFORE YOU BLOCK MY ACCOUNT: IF MY EDIT SUMMARY INCLUDE PREFIX </span>''(Script)''<span style="color:red">, DON'T BLOCK ME, JUST TELL ME TO SLOW DOWN AT COMMONS' TALK PAGE. IT IS AN AUTOMATED SCRIPT BEING USED ON COMMONS TO MOVE FILES.</span>
Instead, please leave your message following site:
<br />
[[File:Wikidata-logo-en.svg|45px|link=d:User talk:Revi C.]] [[d:User talk:Revi C.]] for Wikidata (Interwiki links) stuff <!--(I am {{int:Group-sysop}} there)-->
<br />
[[File:Commons-logo.svg|45px|link=commons:User talk:Revi C.]] [[commons:User talk:Revi C.]] for renaming stuff or [[User:CommonsDelinker|CommonsDelinker]] action (I am {{int:Group-sysop}} there)
<br />
[[File:Wikimedia Community Logo optimized.svg|45px|link=m:User talk:Revi C.]] [[meta:User talk:Revi C.]] for other stuff (User right notification, revert message, etc...)
Messages left on this page may be reverted or moved without any response.</div>
esxe13mcstpjlux1bt2hqwxr2v8t8mn
Template:InfoNeeded
10
86720
754642
258107
2026-08-02T07:40:15Z
Minorax
44057
754642
wikitext
text/x-wiki
[[File:Crystal Clear app help index.svg|20px|alt=|link=]]<noinclude>
[[Category:Wikipedia-specific image insertion templates]]
</noinclude>
hkxo85r4kird0x6jq0b1s5s983nc7c7
Hi
0
92934
754567
754430
2026-08-01T20:00:34Z
Enbi
72574
754567
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :D
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
ol2qslfsrsnw94096no8vg5v9plfu1f
754568
754567
2026-08-01T20:00:38Z
Enbi
72574
Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754571
754568
2026-08-01T20:02:50Z
Enbi
72574
754571
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :D
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
ol2qslfsrsnw94096no8vg5v9plfu1f
754572
754571
2026-08-01T20:02:53Z
Enbi
72574
Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754574
754572
2026-08-01T20:04:51Z
Enbi
72574
754574
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :D
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
ol2qslfsrsnw94096no8vg5v9plfu1f
754575
754574
2026-08-01T20:04:55Z
Enbi
72574
Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754577
754575
2026-08-01T20:06:27Z
Enbi
72574
754577
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :D
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
ol2qslfsrsnw94096no8vg5v9plfu1f
754578
754577
2026-08-01T20:06:32Z
Enbi
72574
Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754581
754578
2026-08-01T20:07:25Z
Enbi
72574
754581
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :3
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
0334y4750wmyxjr0mr7pgh9wevisf8s
754582
754581
2026-08-01T20:07:29Z
Enbi
72574
Reverting test edits by by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754584
754582
2026-08-01T20:08:50Z
Enbi
72574
754584
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :33
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
fwurllzillhtbfo5d4yps87qf6pxffy
754585
754584
2026-08-01T20:08:58Z
Enbi
72574
Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754587
754585
2026-08-01T20:09:09Z
Enbi
72574
754587
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]].
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
hfcrfms10vbbc50rw2c1kcrsnsy86hd
754588
754587
2026-08-01T20:09:14Z
Enbi
72574
Reverting test edits by by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754590
754588
2026-08-01T20:10:04Z
Enbi
72574
754590
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]].
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
hfcrfms10vbbc50rw2c1kcrsnsy86hd
754591
754590
2026-08-01T20:10:20Z
Enbi
72574
754591
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]].
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious
tb27slmaiyf1skw5rwwl9l2nles70nd
754592
754591
2026-08-01T20:11:52Z
Enbi
72574
Blanked the page
754592
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
754593
754592
2026-08-01T20:13:47Z
Enbi
72574
754593
wikitext
text/x-wiki
sorry
pvddyccdgjkb8vfzns7albocpfq8rnc
754594
754593
2026-08-01T20:14:04Z
Enbi
72574
Blanked the page
754594
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
754595
754594
2026-08-01T20:14:07Z
Enbi
72574
Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754598
754595
2026-08-01T20:17:52Z
Enbi
72574
754598
wikitext
text/x-wiki
om]</nowiki>
[[Category:Obvious Vandalism]]
n3gvs1y931pro4gm60sn9q4pq61f1rp
754599
754598
2026-08-01T20:17:55Z
Enbi
72574
Reverting non-constructive edits by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754601
754599
2026-08-01T20:23:19Z
Enbi
72574
Blanked the page
754601
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
754602
754601
2026-08-01T20:23:22Z
Enbi
72574
Reverting test edits by by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754604
754602
2026-08-01T20:23:41Z
Enbi
72574
Replaced content with "Vandalism]]"
754604
wikitext
text/x-wiki
Vandalism]]
gtfmeknv6vq3ahzrhs0iueb0ljefuzo
754605
754604
2026-08-01T20:23:50Z
Enbi
72574
Reverting incorrect English variants by [[Special:Contributions/Enbi|Enbi]] (Fortress-Test)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754607
754605
2026-08-01T21:06:42Z
Enbi
72574
Blanked the page
754607
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
754608
754607
2026-08-01T21:06:49Z
Enbi
72574
Reverting edits (Fortress-Beta)
754346
wikitext
text/x-wiki
{{Codeblock}}
Hi is an informal greeting. It is the informal version of [[Hello]]. :0
<nowiki>[http://bit.ly/3WdO9B1 example.com]</nowiki>
[[Category:Obvious Vandalism]]
polq5o63cnijkcsv3wmt4ck9oesg315
754609
754608
2026-08-01T21:07:03Z
Enbi
72574
Blanked the page
754609
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Page
0
115230
754562
724049
2026-08-01T16:04:21Z
PCendrer
75068
754562
wikitext
text/x-wiki
palabrotas muy feas
gnly3ko230nowda83n8fc0c47tz4bu3
S
0
115236
754641
728091
2026-08-02T07:08:08Z
PCendrer
75068
754641
wikitext
text/x-wiki
seza
[[Category:Test 3]]
d
4eosinif08rcfmhcow93bw5ya5ynrkd
Rick Martin
0
121881
754628
690162
2026-08-02T00:06:05Z
InternetArchiveBot
34092
Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5
754628
wikitext
text/x-wiki
{{Short description|Canadian ice hockey player}}{{other people}}
{{Infobox ice hockey player
| image =
| image_size = 230px
| caption = Rick Martin, Buffalo Sabres
| birth_place = [[Verdun, Quebec]], Canada
| birth_date = {{birth date|1951|7|26}}
| death_date = {{death date and age|2011|3|13|1951|7|26}}
| death_place = [[Clarence, New York]], U.S.
| weight_lb = 179
| height_ft = 5
| height_in = 11
| position = [[Winger (ice hockey)|Left Wing]]
| shoots = Left
| played_for = [[Buffalo Sabres]]<br>[[Los Angeles Kings]]
| draft = 5th overall
| draft_year = 1971
| draft_team = [[Buffalo Sabres]]
| career_start = 1971
| career_end = 1982
}}
'''Richard Lionel Martin''' ({{IPAc-en|m|ɑːr|ˈ|t|æ|n}}; {{IPA-fr|maʁtɛ̃|lang}}; July 26, 1951{{spaced ndash}}March 13, 2011) was a [[Canadians|Canadian]] professional [[ice hockey]] [[winger (ice hockey)|winger]] who played in the [[National Hockey League|NHL]] with the [[Buffalo Sabres]] and [[Los Angeles Kings]] for 11 seasons between 1971 and 1982. He was most famous for playing on the Sabres' [[The French Connection (ice hockey)|French Connection line]] with [[Gilbert Perreault]] and [[René Robert|Rene Robert]].
==Playing career==
Martin was drafted fifth overall by the [[Buffalo Sabres]] in the [[1971 NHL Amateur Draft]] after a [[junior hockey|junior]] career with the [[Montreal Junior Canadiens]] of the [[Ontario Hockey League|Ontario Hockey Association]] (OHA). He played 685 career NHL games, scoring 384 goals and 317 assists for 701 points. His best season was the [[1974–75 NHL season]] when he scored 52 goals and 95 points in only 68 games. Martin scored at least 44 goals five times in his NHL career. Martin was selected to play in seven consecutive [[National Hockey League All-Star Game]]s ([[25th National Hockey League All-Star Game|1971–72]], through [[1978 NHL All-Star Game|1977–78]]) and was selected as the official [[NHL All-Star Team|NHL All-Star First Team]] left wing in [[1973–74 NHL season|1973–74]] and [[1974–75 NHL season|1974–75]] and the official NHL All-Star Second Team left wing in 1975–76 and 1976–77.<ref name=His>{{cite web|url=http://downloads.sabres.nhl.com/other/history.pdf|title=History|access-date=2007-07-24|year=2006|publisher=Buffalo Sabres and the National Hockey League|archive-date=2013-06-19|archive-url=https://web.archive.org/web/20130619221123/http://downloads.sabres.nhl.com/other/history.pdf|url-status=dead}} {{Webarchive|url=https://web.archive.org/web/20130619221123/http://downloads.sabres.nhl.com/other/history.pdf |date=2013-06-19 }}</ref> Martin holds the Buffalo Sabres franchise career records for [[hat trick]]s, four-goal games, 40-goal seasons, consecutive 40-goal seasons, 50-goal seasons (tied with [[Danny Gare]]), consecutive 50-goal seasons.<ref name=TRB>{{cite web|url=http://downloads.sabres.nhl.com/other/record_book.pdf|title=The Record Book|access-date=2007-07-24|year=2006|publisher=Buffalo Sabres and the National Hockey League|archive-date=2016-03-04|archive-url=https://web.archive.org/web/20160304001459/http://downloads.sabres.nhl.com/other/record_book.pdf|url-status=dead}} {{Webarchive|url=https://web.archive.org/web/20160304001459/http://downloads.sabres.nhl.com/other/record_book.pdf |date=2016-03-04 }}</ref><ref>{{cite news|title=Rick Martin, Part of Famed N.H.L. Line, Dies at 59 After Car Accident|url=https://www.nytimes.com/2011/03/16/sports/hockey/16martin.html|newspaper=[[The New York Times]]|date=March 15, 2011|access-date=March 22, 2011}}</ref>
Rick Martin is #11 All Time in Career "Goals per Game" Average (.56) in NHL regular season history.
Martin was involved in probably one of the three most frightening injuries on Buffalo home ice (the others being when [[Clint Malarchuk|Clint Malarchuk's]] and [[Richard Zednik|Richard Zednik's]] in separate incidents each had their [[jugular vein]] lacerated). During a 1977 game [[Dave Farrish]] of the [[New York Rangers]] hooked Martin around the neck from behind and kicked Martin's feet out from under him, causing Martin to hit his head on the ice. He was knocked unconscious, and went into convulsions. After that play, helmets became a much more common sight on the heads of his Sabre team-mates.
On November 8, 1980, his career was dealt a devastating blow. In a game against the [[Washington Capitals]] in the [[Buffalo Memorial Auditorium|Aud]], Martin was racing in on a breakaway. Capitals forward [[Ryan Walter]] managed to trip Martin and no penalty was called. Capitals goalie [[Mike Palmateer]], already way out of his crease, knocked Martin back down by kicking his knee, causing severe [[cartilage]] damage that all but ended Martin's career.<ref>{{cite web|url=http://www.hockeydraftcentral.com/1971/71005.html|title=Rick Martin|access-date=2011-03-11|publisher=Hockey Draft Central}}</ref>
Martin underwent surgery in Toronto and on March 10, 1981, [[Scotty Bowman]] traded Martin and [[Don Luce]] to the Kings for a pair of draft picks, one of which the Sabres used to get goalie [[Tom Barrasso]] in [[1983 NHL Entry Draft|1983]]. Martin played four games for the [[Los Angeles Kings]] before hanging up the skates. In 1989 he, along with the other two members of the French Connection, were inducted into the Buffalo Sabres Hall of Fame.<ref>{{cite web |url=http://www.sabresalumni.com/history/halloffame.php |title=Buffalo Sabres Hall of Fame |url-status=dead |access-date=20 July 2012 |archive-url=https://web.archive.org/web/20120618013818/http://www.sabresalumni.com/history/halloffame.php |archive-date=June 18, 2012 }} {{Webarchive|url=https://web.archive.org/web/20120618013818/http://www.sabresalumni.com/history/halloffame.php |date=18 June 2012 }}</ref> His number 7 was retired along with [[René Robert|Rene Robert]]'s #14 on November 15, 1995, flanking the #11 of [[Gilbert Perreault]] under a French Connection banner. On Oct. 25, 2005, Martin was inducted into the Greater Buffalo Sports Hall of Fame.<ref>{{cite news|title=Rick Martin Through the Years|url=http://galleries.buffalonews.com/photo.php?gname=gallery_1300045777.txt&item=8|newspaper=[[The Buffalo News]]|date=March 13, 2011|access-date=March 19, 2011|url-status=dead|archive-url=https://web.archive.org/web/20110317102843/http://galleries.buffalonews.com/photo.php?gname=gallery_1300045777.txt&item=8|archive-date=March 17, 2011}} {{Webarchive|url=https://web.archive.org/web/20110317102843/http://galleries.buffalonews.com/photo.php?gname=gallery_1300045777.txt&item=8 |date=March 17, 2011 }}</ref> In 2010, in commemoration of the Sabres' 40th season, ''[[The Buffalo News]]'' ranked Martin number 4 out of the top 40 Sabres of all time, while he was voted #5 by fans.<ref>{{cite news|title=Sabres Top 40 for 40 Seasons|url=http://galleries.buffalonews.com/photo.php?gname=gallery_1285003304.txt&item=4|newspaper=[[The Buffalo News]]|date=October 6, 2010|access-date=March 19, 2011|url-status=dead|archive-url=https://web.archive.org/web/20110720091737/http://galleries.buffalonews.com/photo.php?gname=gallery_1285003304.txt&item=4|archive-date=July 20, 2011}} {{Webarchive|url=https://web.archive.org/web/20110720091737/http://galleries.buffalonews.com/photo.php?gname=gallery_1285003304.txt&item=4 |date=July 20, 2011 }}</ref> After his death in 2011, the Sabres honored his memory by painting the number 7, the number Martin wore for most of his career with Buffalo, behind each goal at the [[HSBC Arena (Buffalo)|HSBC Arena]] for the remainder of the [[2010–11 Buffalo Sabres season|2010-11 season]].<ref>{{cite web|url=http://sabres.nhl.com/club/recap.htm?id=2010021071|title=Sabres 8, Thrashers 2|access-date=2011-03-22|year=2011|publisher=Buffalo Sabres|url-status=dead|archive-url=https://web.archive.org/web/20110321084925/http://sabres.nhl.com/club/recap.htm?id=2010021071|archive-date=2011-03-21}} {{Webarchive|url=https://web.archive.org/web/20110321084925/http://sabres.nhl.com/club/recap.htm?id=2010021071 |date=2011-03-21 }}</ref>
==Achievements==
*1st Team All Star (1973–74)
*1st Team All Star (1974–75)
*2nd Team All Star (1975–76)
*2nd Team All Star (1976–77)
*7 Straight NHL All Star Game Appearances (1972 - 1978)
*3rd All Time in Hat Tricks (21) among Left Wingers (Modern Era)
*11th All Time in Career Goals Per Game Average in NHL History
*Gold Championship Canada Cup 1976 (Team Canada)
*5 "Top 10" finishes in Goals
*2 "Top 10" finishes in Points
*5 "Top 10" finishes in Even Strength Goals
*3 "Top 10" finishes in Game Winning Goals
*5 "Top 10" finishes in Power Play Goals
*5 "Top 10" finishes in Goals Per Game Average
*2 "Top 10" finishes in Points Per Game Average
*6 Team Scoring Records (Buffalo Sabres)
* #7 Team Jersey Retired (Buffalo Sabres)
*Buffalo Sabres Hall Of Famer
==Personal life==
Rick and his wife were owners of Globalquest Solutions and Globalquest Staffing Solutions in Williamsville, New York.<ref>{{cite news|title=Globalquest adding up to 10 to staff|url=http://www.bizjournals.com/albany/stories/2001/08/06/daily21.html|newspaper=The Business Review|date=August 7, 2001|access-date=March 19, 2011}}</ref>
Martin owned a bar/restaurant called Slapshot on Niagara Falls Boulevard in Niagara Falls, N.Y.
Rick Martin died on March 13, 2011, in [[Clarence, New York]], from a [[myocardial infarction|heart attack]] while driving, a complication of [[Hypertensive heart disease|hypertensive arteriosclerotic cardiovascular disease]].<ref name="Buffalo News story with obit">{{cite news|last=Watson|first=Stephen T.|title=Memorial plans for Martin announced by Sabres|url=http://www.buffalonews.com/sports/sabres-nhl/article366694.ece|newspaper=[[The Buffalo News]]|date=March 14, 2011|access-date=March 14, 2011}}</ref> He was 59 years old. He was survived by his wife Mikey, who has since passed on December 16, 2017, and his sons Cory, Josh, and Erick.<ref name=sabres.com>{{cite web|title=RICK MARTIN: 1951-2011|url=http://sabres.nhl.com/club/news.htm?id=555923|access-date=13 March 2011|archive-date=17 March 2011|archive-url=https://web.archive.org/web/20110317000126/http://sabres.nhl.com/club/news.htm?id=555923|url-status=dead}}</ref><ref name="Buffalo News Obituaries">{{cite web|title=Rick MARTIN Obituary: View Rick Martin's Obituary By Buffalo News|url=http://www.legacy.com/obituaries/buffalonews/obituary.aspx?n=rick-martin&pid=149347695|access-date=March 23, 2011}}</ref><ref>{{cite news|title=Video: Rick Martin memorial service|url=http://blogs.buffalonews.com/sabres/2011/03/video-rick-martin-memorial-service.html|newspaper=[[The Buffalo News]]|date=March 24, 2011|access-date=March 24, 2011|archive-date=July 20, 2011|archive-url=https://web.archive.org/web/20110720093219/http://blogs.buffalonews.com/sabres/2011/03/video-rick-martin-memorial-service.html|url-status=dead}} {{Webarchive|url=https://web.archive.org/web/20110720093219/http://blogs.buffalonews.com/sabres/2011/03/video-rick-martin-memorial-service.html |date=July 20, 2011 }}</ref> Later analysis revealed that Martin had stage 2 [[chronic traumatic encephalopathy]], a disease normally associated with [[enforcer (ice hockey)|enforcers]]; the damage was believed to stem from a severe concussion Martin sustained in 1977, and it had no effect on his cognitive abilities. Martin is the first non-enforcer to have been diagnosed with the disease, which can only be diagnosed posthumously.<ref>Golen, Jimmy (October 5, 2011). [http://www.wivb.com/dpp/sports/sabres_and_nhl/Brain-study-finds-damage-in-Rick-Martin Brain study finds damage in Rick Martin] {{Webarchive|url=https://web.archive.org/web/20111007004419/http://www.wivb.com/dpp/sports/sabres_and_nhl/Brain-study-finds-damage-in-Rick-Martin |date=2011-10-07 }}. ''Associated Press''. Retrieved October 5, 2011.</ref>
==Career statistics==
===Regular season and playoffs===
{| border="0" cellpadding="1" cellspacing="0" style="text-align:center; width:60em"
|- bgcolor="#e0e0e0"
! colspan="3" bgcolor="#ffffff" |
! rowspan="99" bgcolor="#ffffff" |
! colspan="5" | [[regular season|Regular season]]
! rowspan="99" bgcolor="#ffffff" |
! colspan="5" | [[Playoffs]]
|- bgcolor="#e0e0e0"
! [[Season (sports)|Season]]
! Team
! League
! GP
! [[Goal (ice hockey)|G]]
! [[Assist (ice hockey)|A]]
! [[Point (ice hockey)|Pts]]
! [[Penalty (ice hockey)|PIM]]
! GP
! G
! A
! Pts
! PIM
|-
| 1967–68
| Thetford Mines Canadiens
| QJHL
| 40
| 38
| 35
| 73
| —
| 7
| 2
| 0
| 2
| 4
|- bgcolor="#f0f0f0"
| [[1968–69 OHA season|1968–69]]
| [[Montreal Junior Canadiens]]
| [[Ontario Hockey League|OHA-Jr.]]
| 52
| 22
| 21
| 43
| 27
| 14
| 3
| 0
| 3
| 2
|-
| [[1969 Memorial Cup|1968–69]]
| Montreal Junior Canadiens
| [[Memorial Cup|M-Cup]]
| —
| —
| —
| —
| —
| 6
| 2
| 1
| 3
| 12
|- bgcolor="#f0f0f0"
| [[1969–70 OHA season|1969–70]]
| Montreal Junior Canadiens
| OHA-Jr.
| 34
| 23
| 32
| 55
| 10
| 16
| 14
| 20
| 34
| 12
|-
| [[1970 Memorial Cup|1969–70]]
| Montreal Junior Canadiens
| M-Cup
| —
| —
| —
| —
| —
| 12
| 14
| 13
| 27
| 8
|- bgcolor="#f0f0f0"
| [[1970–71 OHA season|1970–71]]
| Montreal Junior Canadiens
| OHA-Jr.
| 60
| 71
| 50
| 121
| 106
| 11
| 17
| 7
| 24
| 10
|-
| [[1971–72 NHL season|1971–72]]
| [[Buffalo Sabres]]
| [[National Hockey League|NHL]]
| 73
| 44
| 30
| 74
| 39
| —
| —
| —
| —
| —
|- bgcolor="#f0f0f0"
| [[1972–73 NHL season|1972–73]]
| Buffalo Sabres
| NHL
| 75
| 37
| 36
| 73
| 79
| 6
| 3
| 2
| 5
| 12
|-
| [[1973–74 NHL season|1973–74]]
| Buffalo Sabres
| NHL
| 78
| 52
| 34
| 86
| 38
| —
| —
| —
| —
| —
|- bgcolor="#f0f0f0"
| [[1974–75 NHL season|1974–75]]
| Buffalo Sabres
| NHL
| 68
| 52
| 43
| 95
| 72
| 17
| 7
| 8
| 15
| 20
|-
| [[1975–76 NHL season|1975–76]]
| Buffalo Sabres
| NHL
| 80
| 49
| 37
| 86
| 67
| 9
| 4
| 7
| 11
| 12
|- bgcolor="#f0f0f0"
| [[1976–77 NHL season|1976–77]]
| Buffalo Sabres
| NHL
| 66
| 36
| 29
| 65
| 58
| 6
| 2
| 1
| 3
| 9
|-
| [[1977–78 NHL season|1977–78]]
| Buffalo Sabres
| NHL
| 65
| 28
| 35
| 63
| 16
| 7
| 2
| 4
| 6
| 13
|- bgcolor="#f0f0f0"
| [[1978–79 NHL season|1978–79]]
| Buffalo Sabres
| NHL
| 73
| 32
| 21
| 53
| 35
| 3
| 0
| 3
| 3
| 0
|-
| [[1979–80 NHL season|1979–80]]
| Buffalo Sabres
| NHL
| 80
| 45
| 34
| 79
| 54
| 14
| 6
| 4
| 10
| 8
|- bgcolor="#f0f0f0"
| [[1980–81 NHL season|1980–81]]
| Buffalo Sabres
| NHL
| 23
| 7
| 14
| 21
| 20
| —
| —
| —
| —
| —
|-
| 1980–81
| [[Los Angeles Kings]]
| NHL
| 1
| 1
| 1
| 2
| 0
| 1
| 0
| 0
| 0
| 0
|- bgcolor="#f0f0f0"
| [[1981–82 NHL season|1981–82]]
| Los Angeles Kings
| NHL
| 3
| 1
| 3
| 4
| 2
| —
| —
| —
| —
| —
|- bgcolor="#e0e0e0"
! colspan="3" | NHL totals
! 685
! 384
! 317
! 701
! 477
! 63
! 24
! 29
! 53
! 74
|}
===International===
{| border="0" cellpadding="1" cellspacing="0" style="text-align:center; width:50em"
|- ALIGN="center" bgcolor="#e0e0e0"
! Year
! Team
! Event
! rowspan="99" bgcolor="#ffffff" |
! GP
! G
! A
! Pts
! PIM
|-
| [[1976 Canada Cup|1976]]
| [[Canada men's national ice hockey team|Canada]]
| [[Canada Cup|CC]]
| 4
| 3
| 2
| 5
| 0
|}
==References==
{{reflist}}
==External links==
*{{icehockeystats|legends=13552}}
*[https://web.archive.org/web/20110715184617/http://sports.rightpundits.com/?p=5976%2F Mikey Martin, Rick Martin's Wife]
{{s-start}}
{{succession box | before = [[Gilbert Perreault]] | title = [[List of Buffalo Sabres draft picks|Buffalo Sabres first round draft pick]] | years = [[1971 NHL Amateur Draft|1971]] | after = [[Jim Schoenfeld]]}}
{{s-end}}
{{DEFAULTSORT:Martin, Rick}}
[[Category:1951 births]]
[[Category:2011 deaths]]
[[Category:Buffalo Sabres draft picks]]
[[Category:Buffalo Sabres players]]
[[Category:Canadian ice hockey left wingers]]
[[Category:Ice hockey people from Quebec]]
[[Category:Ice hockey players players with chronic traumatic encephalopathy]]
[[Category:Los Angeles Kings players]]
[[Category:Moncton Golden Flames players]]
[[Category:Montreal Junior Canadiens players]]
[[Category:National Hockey League first round draft picks]]
[[Category:National Hockey League players with retired numbers]]
[[Category:People from Verdun, Quebec]]
[[Category:Sportspeople from Montreal]]
tkuychr02iug1xgl5tlmlevhoq19qfu
CAPTCHA test
0
167162
754566
750574
2026-08-01T17:59:52Z
OutsideNormality
57920
this is an edit via the API
754566
wikitext
text/x-wiki
Hello world!
oohjaetg7omy0s2yj35hjuuup48ugoy
User:Novem Linguae/rater/app.js
2
168001
754651
754373
2026-08-02T10:01:49Z
Novem Linguae
49714
754651
javascript
text/javascript
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports={
"name": "rater",
"version": "2.7.2",
"description": "Wikipedia userscript that helps assess pages for WikiProjects",
"homepage": "https://github.com/evad37/rater",
"browser": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint:es5": "jshint index.js",
"lint:es6": "eslint index.js \"rater-src/**\"",
"lint:fix": "eslint index.js \"rater-src/**\" --fix",
"lint": "npm run lint:es6 && npm run lint:es5",
"build:bundle": "browserify rater-src/App.js --debug -t babelify --outfile dist/rater.js",
"build:minify": "uglifyjs dist/rater.js --compress -b ascii_only=true,beautify=false --output dist/rater.min.js",
"build:concat": "concat-cli -f \"comment-top.js\" dist/rater.min.js \"comment-bottom.js\" -o dist/rater.min.js",
"build": "npm run lint && npm run build:bundle && npm run build:minify && npm run build:concat"
},
"author": {
"name": "Evad37",
"url": "https://en.wikipedia.org/wiki/User:Evad37"
},
"repository": {
"type": "git",
"url": "https://github.com/evad37/rater.git"
},
"license": "(MIT OR CC-BY-4.0)",
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"babelify": "^10.0.0",
"browserify": "^16.5.0",
"concat-cli": "^4.0.0",
"eslint": "^6.8.0",
"jshint": "^2.11.0",
"uglify-js": "^3.8.0"
}
}
},{}],2:[function(require,module,exports){
"use strict";
var _setup = _interopRequireDefault(require("./setup"));
var _autostart = _interopRequireDefault(require("./autostart"));
var _css = _interopRequireDefault(require("./css.js"));
var _api = require("./api");
var _windowManager = _interopRequireDefault(require("./windowManager"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
// <nowiki>
(function App() {
var stylesheet;
var _showMainWindow = function showMainWindow(data) {
if (!data || !data.success) {
return;
}
if (stylesheet) {
stylesheet.disabled = false;
} else {
stylesheet = mw.util.addCSS(_css["default"]);
}
// Add css class to body to enable background scrolling
document.getElementsByTagName("body")[0].classList.add("rater-mainWindow-open");
// Open the window
_windowManager["default"].openWindow("main", data).closed.then(function (result) {
// Disable/remove the css styles, so as to not interfere with other scripts/content/OOUI windows
if (stylesheet) {
stylesheet.disabled = true;
}
document.getElementsByTagName("body")[0].classList.remove("rater-mainWindow-open");
// Restart if needed
if (result && result.restart) {
_windowManager["default"].removeWindows(["main"]).then(_setup["default"]).then(_showMainWindow, showSetupError);
return;
}
// Show notification when saved successfully
if (result && result.success) {
var $message = $("<span>").append($("<strong>").text("Ratings saved successfully."));
if (result.upgradedStub) {
$message.append($("<br>"),
// TODO: There should be a link that will edit the article for you
$("<span>").text("Note that the article appears to be tagged as a stub."));
}
mw.notify($message, {
autoHide: true,
autoHideSeconds: "long",
tag: "Rater-saved"
});
}
});
};
var showSetupError = function showSetupError(code, jqxhr) {
return OO.ui.alert((0, _api.makeErrorMsg)(code, jqxhr), {
title: "Rater failed to open"
});
};
// Invocation by portlet link
mw.util.addPortletLink("p-cactions", "#", "Rater", "ca-rater", "Rate quality and importance", "5");
$("#ca-rater").click(function (event) {
event.preventDefault();
(0, _setup["default"])().then(_showMainWindow, showSetupError);
});
// Invocation by auto-start (do not show message on error)
(0, _autostart["default"])().then(_showMainWindow);
})();
// </nowiki>
},{"./api":15,"./autostart":16,"./css.js":19,"./setup":22,"./windowManager":24}],3:[function(require,module,exports){
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parseTemplates = exports.getWithRedirectTo = exports.Template = void 0;
var _api = _interopRequireDefault(require("./api"));
var _util = require("./util");
var _config = _interopRequireDefault(require("./config"));
var cache = _interopRequireWildcard(require("./cache"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
// <nowiki>
/** Template
*
* @class
* Represents the wikitext of template transclusion. Used by #parseTemplates.
* @prop {String} name Name of the template
* @prop {String} wikitext Full wikitext of the transclusion
* @prop {Object[]} parameters Parameters used in the translcusion, in order, of form:
{
name: {String|Number} parameter name, or position for unnamed parameters,
value: {String} Wikitext passed to the parameter (whitespace trimmed),
wikitext: {String} Full wikitext (including leading pipe, parameter name/equals sign (if applicable), value, and any whitespace)
}
* @constructor
* @param {String} wikitext Wikitext of a template transclusion, starting with '{{' and ending with '}}'.
*/
var Template = exports.Template = function Template(wikitext) {
this.wikitext = wikitext;
this.parameters = [];
// Spacing around pipes, equals signs, end braces (defaults)
this.pipeStyle = " |";
this.equalsStyle = "=";
this.endBracesStyle = "}}";
};
Template.prototype.addParam = function (name, val, wikitext) {
this.parameters.push({
"name": name,
"value": val,
"wikitext": "|" + wikitext
});
};
/**
* Get a parameter data by parameter name
*/
Template.prototype.getParam = function (paramName) {
return this.parameters.find(function (p) {
return p.name == paramName;
});
};
Template.prototype.setName = function (name) {
this.name = name.trim();
};
Template.prototype.getTitle = function () {
return mw.Title.newFromText("Template:" + this.name);
};
/**
* parseTemplates
*
* Parses templates from wikitext.
* Based on SD0001's version at <https://en.wikipedia.org/wiki/User:SD0001/parseAllTemplates.js>.
* Returns an array containing the template details:
* var templates = parseTemplates("Hello {{foo |Bar|baz=qux |2=loremipsum|3=}} world");
* console.log(templates[0]); // --> object
{
name: "foo",
wikitext:"{{foo |Bar|baz=qux | 2 = loremipsum |3=}}",
parameters: [
{
name: 1,
value: 'Bar',
wikitext: '|Bar'
},
{
name: 'baz',
value: 'qux',
wikitext: '|baz=qux '
},
{
name: '2',
value: 'loremipsum',
wikitext: '| 2 = loremipsum '
},
{
name: '3',
value: '',
wikitext: '|3='
}
],
getParam: function(paramName) {
return this.parameters.find(function(p) { return p.name == paramName; });
}
}
*
*
* @param {String} wikitext
* @param {Boolean} recursive Set to `true` to also parse templates that occur within other templates,
* rather than just top-level templates.
* @return {Template[]} templates
*/
var _parseTemplates = exports.parseTemplates = function parseTemplates(wikitext, recursive) {
/* eslint-disable no-control-regex */
if (!wikitext) {
return [];
}
var strReplaceAt = function strReplaceAt(string, index, _char) {
return string.slice(0, index) + _char + string.slice(index + 1);
};
var result = [];
var processTemplateText = function processTemplateText(startIdx, endIdx) {
var text = wikitext.slice(startIdx, endIdx);
var template = new Template("{{" + text.replace(/\x01/g, "|") + "}}");
// swap out pipe in links with \x01 control character
// [[File: ]] can have multiple pipes, so might need multiple passes
while (/(\[\[[^\]]*?)\|(.*?\]\])/g.test(text)) {
text = text.replace(/(\[\[[^\]]*?)\|(.*?\]\])/g, "$1\x01$2");
}
// Figure out most-used spacing styles for pipes/equals
template.pipeStyle = (0, _util.mostFrequent)(text.match(/[\s\n]*\|[\s\n]*/g)) || " |";
template.equalsStyle = (0, _util.mostFrequent)(text.replace(/(=[^|]*)=+/g, "$1").match(/[\s\n]*=[\s\n]*/g)) || "=";
// Figure out end-braces style
var endSpacing = text.match(/[\s\n]*$/);
template.endBracesStyle = (endSpacing ? endSpacing[0] : "") + "}}";
var chunks = text.split("|").map(function (chunk) {
// change '\x01' control characters back to pipes
return chunk.replace(/\x01/g, "|");
});
template.setName(chunks[0]);
var parameterChunks = chunks.slice(1);
var unnamedIdx = 1;
parameterChunks.forEach(function (chunk) {
var indexOfEqualTo = chunk.indexOf("=");
var indexOfOpenBraces = chunk.indexOf("{{");
var isWithoutEquals = !chunk.includes("=");
var hasBracesBeforeEquals = chunk.includes("{{") && indexOfOpenBraces < indexOfEqualTo;
var isUnnamedParam = isWithoutEquals || hasBracesBeforeEquals;
var pName, pNum, pVal;
if (isUnnamedParam) {
// Get the next number not already used by either an unnamed parameter, or by a
// named parameter like `|1=val`
while (template.getParam(unnamedIdx)) {
unnamedIdx++;
}
pNum = unnamedIdx;
pVal = chunk.trim();
} else {
pName = chunk.slice(0, indexOfEqualTo).trim();
pVal = chunk.slice(indexOfEqualTo + 1).trim();
}
template.addParam(pName || pNum, pVal, chunk);
});
result.push(template);
};
var n = wikitext.length;
// number of unclosed braces
var numUnclosed = 0;
// are we inside a comment, or between nowiki tags, or in a {{{parameter}}}?
var inComment = false;
var inNowiki = false;
var inParameter = false;
var startIdx, endIdx;
for (var i = 0; i < n; i++) {
if (!inComment && !inNowiki && !inParameter) {
if (wikitext[i] === "{" && wikitext[i + 1] === "{" && wikitext[i + 2] === "{" && wikitext[i + 3] !== "{") {
inParameter = true;
i += 2;
} else if (wikitext[i] === "{" && wikitext[i + 1] === "{") {
if (numUnclosed === 0) {
startIdx = i + 2;
}
numUnclosed += 2;
i++;
} else if (wikitext[i] === "}" && wikitext[i + 1] === "}") {
if (numUnclosed === 2) {
endIdx = i;
processTemplateText(startIdx, endIdx);
}
numUnclosed -= 2;
i++;
} else if (wikitext[i] === "|" && numUnclosed > 2) {
// swap out pipes in nested templates with \x01 character
wikitext = strReplaceAt(wikitext, i, "\x01");
} else if (/^<!--/.test(wikitext.slice(i, i + 4))) {
inComment = true;
i += 3;
} else if (/^<nowiki ?>/.test(wikitext.slice(i, i + 9))) {
inNowiki = true;
i += 7;
}
} else {
// we are in a comment or nowiki or {{{parameter}}}
if (wikitext[i] === "|") {
// swap out pipes with \x01 character
wikitext = strReplaceAt(wikitext, i, "\x01");
} else if (/^-->/.test(wikitext.slice(i, i + 3))) {
inComment = false;
i += 2;
} else if (/^<\/nowiki ?>/.test(wikitext.slice(i, i + 10))) {
inNowiki = false;
i += 8;
} else if (wikitext[i] === "}" && wikitext[i + 1] === "}" && wikitext[i + 2] === "}") {
inParameter = false;
i += 2;
}
}
}
if (recursive) {
var subtemplates = (0, _util.filterAndMap)(result, function (template) {
return /\{\{(?:.|\n)*\}\}/.test(template.wikitext.slice(2, -2));
}, function (template) {
return _parseTemplates(template.wikitext.slice(2, -2), true);
});
return result.concat.apply(result, subtemplates);
}
return result;
}; /* eslint-enable no-control-regex */
/**
* @param {Template|Template[]} templates
* @return {Promise<Template>|Promise<Template[]>}
*/
var getWithRedirectTo = exports.getWithRedirectTo = function getWithRedirectTo(templates) {
var templatesArray = Array.isArray(templates) ? templates : [templates];
if (templatesArray.length === 0) {
return $.Deferred().resolve([]);
}
return _api["default"].get({
"action": "query",
"format": "json",
"titles": (0, _util.filterAndMap)(templatesArray, function (template) {
return template.getTitle() !== null;
}, function (template) {
return template.getTitle().getPrefixedText();
}),
"redirects": 1
}).then(function (result) {
if (!result || !result.query) {
return $.Deferred().reject("Empty response");
}
if (result.query.redirects) {
result.query.redirects.forEach(function (redirect) {
var i = templatesArray.findIndex(function (template) {
var title = template.getTitle();
return title && title.getPrefixedText() === redirect.from;
});
if (i !== -1) {
templatesArray[i].redirectTarget = mw.Title.newFromText(redirect.to);
}
});
}
return Array.isArray(templates) ? templatesArray : templatesArray[0];
});
};
Template.prototype.getDataForParam = function (key, paraName) {
if (!this.paramData) {
return null;
}
// If alias, switch from alias to preferred parameter name
var para = this.paramAliases[paraName] || paraName;
if (!this.paramData[para]) {
return;
}
var data = this.paramData[para][key];
// Data might actually be an object with key "en"
if (data && data.en && !Array.isArray(data)) {
return data.en;
}
return data;
};
Template.prototype.isShellTemplate = function () {
var mainText = this.redirectTarget ? this.redirectTarget.getMainText() : this.getTitle().getMainText();
return _config["default"].shellTemplates.includes(mainText);
};
Template.prototype.setParamDataAndSuggestions = function () {
var self = this;
var paramDataSet = $.Deferred();
if (self.paramData) {
return paramDataSet.resolve();
}
var prefixedText = self.redirectTarget ? self.redirectTarget.getPrefixedText() : self.getTitle().getPrefixedText();
var cachedInfo = cache.read(prefixedText + "-params");
if (cachedInfo && cachedInfo.value && cachedInfo.staleDate && cachedInfo.value.paramData != null && cachedInfo.value.parameterSuggestions != null && cachedInfo.value.paramAliases != null) {
self.notemplatedata = cachedInfo.value.notemplatedata;
self.paramData = cachedInfo.value.paramData;
self.parameterSuggestions = cachedInfo.value.parameterSuggestions;
self.paramAliases = cachedInfo.value.paramAliases;
paramDataSet.resolve();
if (!(0, _util.isAfterDate)(cachedInfo.staleDate)) {
// Just use the cached data
return paramDataSet;
} // else: Use the cache data for now, but also fetch new data from API
}
_api["default"].get({
action: "templatedata",
titles: prefixedText,
redirects: 1,
includeMissingTitles: 1
}).then(function (response) {
return response;
}, function /*error*/ () {
return null;
} // Ignore errors, will use default data
).then(function (result) {
// Figure out page id (beacuse action=templatedata doesn't have an indexpageids option)
var id = result && $.map(result.pages, function (_value, key) {
return key;
});
if (!result || !result.pages[id] || result.pages[id].notemplatedata || !result.pages[id].params) {
// No TemplateData, so use defaults (guesses)
self.notemplatedata = true;
self.templatedataApiError = !result;
self.paramData = _config["default"].defaultParameterData;
} else {
self.paramData = result.pages[id].params;
}
self.paramAliases = {};
$.each(self.paramData, function (paraName, paraData) {
// Extract aliases for easier reference later on
if (paraData.aliases && paraData.aliases.length) {
paraData.aliases.forEach(function (alias) {
self.paramAliases[alias] = paraName;
});
}
// Extract allowed values array from description
if (paraData.description && /\[.*'.+?'.*?\]/.test(paraData.description.en)) {
try {
var allowedVals = JSON.parse(paraData.description.en.replace(/^.*\[/, "[").replace(/"/g, "\\\"").replace(/'/g, "\"").replace(/,\s*]/, "]").replace(/].*$/, "]"));
self.paramData[paraName].allowedValues = allowedVals;
} catch (e) {
console.warn("[Rater] Could not parse allowed values in description:\n " + paraData.description.en + "\n Check TemplateData for parameter |" + paraName + "= in " + self.getTitle().getPrefixedText());
}
}
});
// Make suggestions for combobox
var allParamsArray = !self.notemplatedata && result.pages[id].paramOrder || $.map(self.paramData, function (_val, key) {
return key;
});
self.parameterSuggestions = allParamsArray.filter(function (paramName) {
return paramName && paramName !== "class" && paramName !== "importance";
}).map(function (paramName) {
var optionObject = {
data: paramName
};
var label = self.getDataForParam(label, paramName);
if (label) {
optionObject.label = label + " (|" + paramName + "=)";
}
return optionObject;
});
if (self.templatedataApiError) {
// Don't save defaults/guesses to cache;
return true;
}
cache.write(prefixedText + "-params", {
notemplatedata: self.notemplatedata,
paramData: self.paramData,
parameterSuggestions: self.parameterSuggestions,
paramAliases: self.paramAliases
}, 1);
return true;
}).then(paramDataSet.resolve, paramDataSet.reject);
return paramDataSet;
};
var makeListAs = function makeListAs(subjectTitle) {
var name = subjectTitle.getMainText().replace(/\s\(.*\)/, "");
if (name.indexOf(" ") === -1) {
return name;
}
var generationalSuffix = "";
if (/ (?:[JS]r.?|[IVX]+)$/.test(name)) {
generationalSuffix = name.slice(name.lastIndexOf(" "));
name = name.slice(0, name.lastIndexOf(" "));
if (name.indexOf(" ") === -1) {
return name + generationalSuffix;
}
}
var lastName = name.slice(name.lastIndexOf(" ") + 1).replace(/,$/, "");
var otherNames = name.slice(0, name.lastIndexOf(" "));
return lastName + ", " + otherNames + generationalSuffix;
};
Template.prototype.addMissingParams = function () {
var thisTemplate = this;
// Autofill listas parameter for WP:BIO
var isBiographyBanner = this.getTitle().getMainText() === "WikiProject Biography" || this.redirectTarget && this.redirectTarget.getMainText() === "WikiProject Biography";
if (isBiographyBanner && !this.getParam("listas")) {
var subjectTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getSubjectPage();
this.parameters.push({
name: "listas",
value: makeListAs(subjectTitle),
autofilled: true
});
}
// Make sure required/suggested parameters are present
$.each(thisTemplate.paramData, function (paraName, paraData) {
if ((paraData.required || paraData.suggested) && !thisTemplate.getParam(paraName)) {
// Check if already present in an alias, if any
if (paraData.aliases.length) {
var aliases = thisTemplate.parameters.filter(function (p) {
var isAlias = paraData.aliases.includes(p.name);
var isEmpty = !p.value;
return isAlias && !isEmpty;
});
if (aliases.length) {
// At least one non-empty alias, so do nothing
return;
}
}
// No non-empty aliases, so add this to the parameters list (with
// value set parameter to either the autovaule, or as null).
// Also set that it was autofilled.
thisTemplate.parameters.push({
name: paraName,
value: paraData.autovalue || null,
autofilled: true
});
}
});
return thisTemplate;
};
Template.prototype.setClassesAndImportances = function () {
var _this = this;
var parsed = $.Deferred();
// Don't re-parse if already parsed; no need to parse shell templates or banners without ratings
if (this.isShellTemplate()) {
this.classes = _toConsumableArray(_config["default"].bannerDefaults.classes);
return parsed.resolve();
} else if (this.classes && this.importances || this.withoutRatings) {
return parsed.resolve();
}
var mainText = this.getTitle().getMainText();
// Some projects have hardcoded values, to avoid standard classes or to prevent API issues (timeout and/or node count exceeded)
var redirectTargetOrMainText = this.redirectTarget ? this.redirectTarget.getMainText() : mainText;
if (_config["default"].customBanners[redirectTargetOrMainText]) {
this.classes = _config["default"].customBanners[redirectTargetOrMainText].classes;
this.importances = _config["default"].customBanners[redirectTargetOrMainText].importances;
return parsed.resolve();
}
// Otherwise try reading from cached data
var cachedRatings = cache.read(mainText + "-ratings");
if (cachedRatings && cachedRatings.value && cachedRatings.staleDate && cachedRatings.value.classes != null && cachedRatings.value.importances != null) {
this.classes = cachedRatings.value.classes;
this.importances = cachedRatings.value.importances;
parsed.resolve();
if (!(0, _util.isAfterDate)(cachedRatings.staleDate)) {
// Just use the cached data
return parsed;
} // else: Use the cache data for now, but also fetch new data from API
}
var wikitextToParse = "";
_config["default"].bannerDefaults.extendedClasses.forEach(function (classname, index) {
wikitextToParse += "{{" + mainText + "|class=" + classname + "|importance=" + (_config["default"].bannerDefaults.extendedImportances[index] || "") + "}}/n";
});
return _api["default"].get({
action: "parse",
title: "Talk:Wikipedia",
text: wikitextToParse,
prop: "categorieshtml"
}).then(function (result) {
var catsHtml = result.parse.categorieshtml["*"];
var extendedClasses = _config["default"].bannerDefaults.extendedClasses.filter(function (cl) {
return catsHtml.indexOf(cl + "-Class") !== -1;
});
_this.classes = [].concat(_toConsumableArray(_config["default"].bannerDefaults.classes), _toConsumableArray(extendedClasses));
_this.importances = _config["default"].bannerDefaults.extendedImportances.filter(function (imp) {
return catsHtml.indexOf(imp + "-importance") !== -1;
});
cache.write(mainText + "-ratings", {
classes: _this.classes,
importances: _this.importances
}, 1);
return true;
});
};
// </nowiki>
},{"./api":15,"./cache":17,"./config":18,"./util":23}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("../../config"));
var _BannerWidget = _interopRequireDefault(require("./BannerWidget"));
var _util = require("../../util");
var _ParameterWidget = _interopRequireDefault(require("./ParameterWidget"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
// <nowiki>
var BannerListWidget = function BannerListWidget(config) {
config = config || {};
// Call parent constructor
BannerListWidget.parent.call(this, config);
OO.ui.mixin.GroupElement.call(this, {
$group: this.$element
});
this.$element.addClass("rater-bannerListWidget").css({
"padding": "20px 10px 16px 10px"
});
// Prefs
this.preferences = config.preferences;
this.oresClass = config.oresClass;
this.changed = false;
// Events
this.aggregate({
"remove": "bannerRemove"
});
this.connect(this, {
"bannerRemove": "onBannerRemove"
});
this.aggregate({
"changed": "bannerChanged"
});
this.connect(this, {
"bannerChanged": "setChanged"
});
this.aggregate({
"biographyBannerChange": "biographyBannerChanged"
});
this.connect(this, {
"biographyBannerChanged": "syncShellTemplateWithBiographyBanner"
});
this.aggregate({
"updatedSize": "bannerUpdatedSize"
});
this.connect(this, {
"bannerUpdatedSize": "onUpdatedSize"
});
};
OO.inheritClass(BannerListWidget, OO.ui.Widget);
OO.mixinClass(BannerListWidget, OO.ui.mixin.GroupElement);
/*
methods from mixin:
- addItems( items, [index] ) : OO.ui.Element (CHAINABLE)
- clearItems( ) : OO.ui.Element (CHAINABLE)
- findItemFromData( data ) : OO.ui.Element|null
- findItemsFromData( data ) : OO.ui.Element[]
- removeItems( items ) : OO.ui.Element (CHAINABLE)
*/
BannerListWidget.prototype.onUpdatedSize = function () {
// Emit an "updatedSize" event so the parent window can update size, if needed
this.emit("updatedSize");
};
BannerListWidget.prototype.setChanged = function () {
this.changed = true;
};
BannerListWidget.prototype.onBannerRemove = function (banner) {
this.removeItems([banner]);
this.setChanged();
};
BannerListWidget.prototype.syncShellTemplateWithBiographyBanner = function (biographyBanner) {
biographyBanner = biographyBanner || this.items.find(function (banner) {
return banner.mainText === "WikiProject Biography" || banner.redirectTargetMainText === "WikiProject Biography";
});
if (!biographyBanner) return;
var bannerShellTemplate = this.items.find(function (banner) {
return banner.mainText === _config["default"].shellTemplates[0] || banner.redirectTargetMainText === _config["default"].shellTemplates[0];
});
if (!bannerShellTemplate) {
return;
}
var paramsToSync = [{
name: "living",
normalise: true
}, {
name: "blpo",
normalise: true
}, {
name: "activepol",
normalise: true
}, {
name: "listas",
normalise: false
}];
paramsToSync.forEach(function (paramToSync) {
var _map = [biographyBanner, bannerShellTemplate].map(function (banner) {
return banner.parameterList.getParameterItems().find(function (parameter) {
return parameter.name === paramToSync.name || banner.paramAliases[parameter.name] === paramToSync.name;
});
}),
_map2 = _slicedToArray(_map, 2),
biographyParam = _map2[0],
shellParam = _map2[1];
if (!biographyParam) return;
var paramSyncValue = paramToSync.normalise ? (0, _util.normaliseYesNo)(biographyParam.value) : biographyParam.value;
biographyParam["delete"]();
if (!shellParam && paramSyncValue) {
var index = bannerShellTemplate.addParameterLayout.isVisible() ? -1 // Insert at the very end
: bannerShellTemplate.parameterList.items.length - 1; // Insert prior to the "add parameter" button
bannerShellTemplate.parameterList.addItems([new _ParameterWidget["default"]({
"name": paramToSync.name,
"value": paramSyncValue,
"autofilled": true
}, bannerShellTemplate.paramData && bannerShellTemplate.paramData[paramToSync.name])], index);
} else if (!biographyParam.autofilled && paramSyncValue) {
shellParam.setValue(paramSyncValue);
shellParam.setAutofilled();
}
});
};
BannerListWidget.prototype.addShellTemplateIfNeeeded = function () {
var _this = this;
if (!this.items.some(function (banner) {
return banner.isShellTemplate;
})) {
_BannerWidget["default"].newFromTemplateName(_config["default"].shellTemplates[0], {
withoutRatings: true
}, {
preferences: this.preferences,
isArticle: this.pageInfo.isArticle
}).then(function (shellBannerWidget) {
OO.ui.mixin.GroupElement.prototype.addItems.call(_this, [shellBannerWidget], 0);
// Autofill ratings (if able to)
_this.autofillClassRatings({
forBannerShell: true
});
// emit updatedSize event
_this.onUpdatedSize();
});
}
return this;
};
BannerListWidget.prototype.addItems = function (items, index) {
if (items.length === 0) {
return this;
}
// Call mixin method to do the adding
OO.ui.mixin.GroupElement.prototype.addItems.call(this, items, index);
// Autofill ratings (if able to, and if enabled in preferences)
if (!this.items.some(function (banner) {
return banner.isShellTemplate;
})) {
this.autofillClassRatings();
}
this.autofillImportanceRatings();
// emit updatedSize event
this.onUpdatedSize();
return this;
};
BannerListWidget.prototype.autofillClassRatings = function (config) {
config = config || {};
// Only autofill if set in preferences
if (!this.preferences.autofillClassFromOthers && !this.preferences.autofillClassFromOres && !config.forBannerShell) {
return;
}
// Check what banners already have
var uniqueClassRatings = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.items, function (banner) {
if (banner.isShellTemplate || !banner.hasClassRatings) {
return false;
}
var classItem = banner.classDropdown.getMenu().findSelectedItem();
return classItem && classItem.getData();
}, function (banner) {
return banner.classDropdown.getMenu().findSelectedItem().getData();
}));
// Can't autofill if there isn't either a single value, or no value
if (uniqueClassRatings.length > 1) {
return;
}
// Determine what to autofill with
var autoClass;
if (uniqueClassRatings.length === 1 && (this.preferences.autofillClassFromOthers || config.forBannerShell)) {
autoClass = uniqueClassRatings[0];
} else if (uniqueClassRatings.length === 0 && this.preferences.autofillClassFromOres && this.oresClass) {
// Don't autofill above C-class
switch (this.oresClass) {
case "Stub":
case "Start":
case "C":
case "List":
autoClass = this.oresClass;
}
} else {
// nothing to do
return;
}
// Do the autofilling
this.items.forEach(function (banner) {
if (!banner.hasClassRatings && !banner.isShellTemplate) {
return;
}
var classItem = banner.classDropdown.getMenu().findSelectedItem();
if (classItem && classItem.getData() && !config.forBannerShell) {
return;
}
if (config.forBannerShell && !banner.isShellTemplate && classItem.getData() === autoClass) {
banner.classDropdown.getMenu().selectItemByData(null);
return;
}
banner.classDropdown.getMenu().selectItemByData(autoClass);
banner.classDropdown.setAutofilled(true);
});
};
BannerListWidget.prototype.autofillImportanceRatings = function () {
if (!this.preferences.autofillImportance) {
return;
}
var isRegularArticle = this.pageInfo && this.pageInfo.isArticle && !this.pageInfo.redirect && !this.pageInfo.isDisambig;
if (!isRegularArticle) {
return;
}
// TODO: Should try to find a smarter, banner-specific way of determining importance.
// Maybe do something with ORES's "drafttopic" model.
var autoImportance = "Low";
this.items.forEach(function (banner) {
if (!banner.hasImportanceRatings) {
return;
}
var importanceItem = banner.importanceDropdown.getMenu().findSelectedItem();
if (importanceItem && importanceItem.getData()) {
return;
}
banner.importanceDropdown.getMenu().selectItemByData(autoImportance);
banner.importanceDropdown.setAutofilled(true);
});
};
BannerListWidget.prototype.setPreferences = function (prefs) {
this.preferences = prefs;
this.items.forEach(function (banner) {
return banner.setPreferences(prefs);
});
this.autofillClassRatings();
this.autofillImportanceRatings();
};
BannerListWidget.prototype.makeWikitext = function () {
var bannersWikitext = (0, _util.filterAndMap)(this.items, function (banner) {
return !banner.isShellTemplate;
}, function (banner) {
return banner.makeWikitext();
}).join("\n");
var shellTemplate = this.items.find(function (banner) {
return banner.isShellTemplate;
});
if (!shellTemplate) {
return bannersWikitext;
}
var shellParam1 = new _ParameterWidget["default"]({
name: "1",
value: "\n" + bannersWikitext + "\n" + (shellTemplate.nonStandardTemplates ? shellTemplate.nonStandardTemplates + "\n" : "")
});
shellTemplate.parameterList.addItems([shellParam1]);
var shellWikitext = shellTemplate.makeWikitext();
shellTemplate.parameterList.removeItems([shellParam1]);
return shellWikitext;
};
var _default = exports["default"] = BannerListWidget; // </nowiki>
},{"../../config":18,"../../util":23,"./BannerWidget":5,"./ParameterWidget":9}],5:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _ParameterListWidget = _interopRequireDefault(require("./ParameterListWidget"));
var _ParameterWidget = _interopRequireDefault(require("./ParameterWidget"));
var _DropdownParameterWidget = _interopRequireDefault(require("./DropdownParameterWidget"));
var _SuggestionLookupTextInputWidget = _interopRequireDefault(require("./SuggestionLookupTextInputWidget"));
var _util = require("../../util");
var _Template = require("../../Template");
var _HorizontalLayoutWidget = _interopRequireDefault(require("./HorizontalLayoutWidget"));
var _config = _interopRequireDefault(require("../../config"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
// <nowiki>
function BannerWidget(template, config) {
var _this = this;
// Configuration initialization
config = config || {};
// Call parent constructor
BannerWidget["super"].call(this, config);
this.$overlay = config.$overlay;
/* --- PREFS --- */
this.preferences = config.preferences;
/* --- PROPS --- */
this.paramData = template.paramData;
this.paramAliases = template.paramAliases || {};
this.parameterSuggestions = template.parameterSuggestions;
this.name = template.name;
this.wikitext = template.wikitext;
this.pipeStyle = template.pipeStyle;
this.equalsStyle = template.equalsStyle;
this.endBracesStyle = template.endBracesStyle;
this.mainText = template.getTitle().getMainText();
this.redirectTargetMainText = template.redirectTarget && template.redirectTarget.getMainText();
this.isShellTemplate = template.isShellTemplate();
this.changed = template.parameters.some(function (parameter) {
return parameter.autofilled;
}); // initially false, unless some parameters were autofilled
this.hasClassRatings = template.classes && template.classes.length;
this.hasImportanceRatings = template.importances && template.importances.length;
this.inactiveProject = template.inactiveProject;
/* --- TITLE AND RATINGS --- */
this.removeButton = new OO.ui.ButtonWidget({
icon: "trash",
label: "Remove banner",
title: "Remove banner",
flags: "destructive",
$element: $("<div style=\"width:100%\">")
});
this.clearButton = new OO.ui.ButtonWidget({
icon: "cancel",
label: "Clear parameters",
title: "Clear parameters",
flags: "destructive",
$element: $("<div style=\"width:100%\">")
});
this.removeButton.$element.find("a").css("width", "100%");
this.clearButton.$element.find("a").css("width", "100%");
this.titleButtonsGroup = new OO.ui.ButtonGroupWidget({
items: [this.removeButton, this.clearButton],
$element: $("<span style='width:100%;'>")
});
this.mainLabelPopupButton = new OO.ui.PopupButtonWidget({
label: "{{".concat(template.getTitle().getMainText(), "}}").concat(this.inactiveProject ? " (inactive)" : ""),
$element: $("<span style='display:inline-block;width:48%;margin-right:0;padding-right:8px'>"),
$overlay: this.$overlay,
indicator: "down",
framed: false,
popup: {
$content: this.titleButtonsGroup.$element,
width: 200,
padded: false,
align: "force-right",
anchor: false
}
});
this.mainLabelPopupButton.$element.children("a").first().css({
"font-size": "110%"
}).find("span.oo-ui-labelElement-label").css({
"white-space": "normal"
});
// Rating dropdowns
if (this.isShellTemplate) {
this.classDropdown = new _DropdownParameterWidget["default"]({
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">Class</span>"),
menu: {
items: [new OO.ui.MenuOptionWidget({
data: null,
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(".concat(config.isArticle ? "no class" : "auto-detect", ")</span>"))
})].concat(_toConsumableArray(_config["default"].bannerDefaults.classes.map(function (classname) {
return new OO.ui.MenuOptionWidget({
data: classname,
label: classname
});
})))
},
$overlay: this.$overlay
});
var shellClassParam = template.parameters.find(function (parameter) {
return parameter.name === "class";
});
this.classDropdown.getMenu().selectItemByData(shellClassParam && (0, _util.classMask)(shellClassParam.value));
} else if (this.hasClassRatings) {
this.classDropdown = new _DropdownParameterWidget["default"]({
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">Class</span>"),
menu: {
items: [new OO.ui.MenuOptionWidget({
data: null,
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(".concat(config.isArticle ? "inherit from shell" : "auto-detect", ")</span>"))
})].concat(_toConsumableArray(template.classes.map(function (classname) {
return new OO.ui.MenuOptionWidget({
data: classname,
label: classname
});
})))
},
$overlay: this.$overlay
});
var classParam = template.parameters.find(function (parameter) {
return parameter.name === "class";
});
this.classDropdown.getMenu().selectItemByData(classParam && (0, _util.classMask)(classParam.value));
}
if (this.hasImportanceRatings) {
this.importanceDropdown = new _DropdownParameterWidget["default"]({
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">Importance</span>"),
menu: {
items: [new OO.ui.MenuOptionWidget({
data: null,
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(".concat(config.isArticle ? "no importance" : "auto-detect", ")</span>"))
})].concat(_toConsumableArray(template.importances.map(function (importance) {
return new OO.ui.MenuOptionWidget({
data: importance,
label: importance
});
})))
},
$overlay: this.$overlay
});
var importanceParam = template.parameters.find(function (parameter) {
return parameter.name === "importance";
});
this.importanceDropdown.getMenu().selectItemByData(importanceParam && (0, _util.importanceMask)(importanceParam.value));
}
this.titleLayout = new OO.ui.HorizontalLayout({
items: [this.mainLabelPopupButton]
});
if (this.hasClassRatings || this.isShellTemplate) {
this.titleLayout.addItems([this.classDropdown]);
}
if (this.hasImportanceRatings) {
this.titleLayout.addItems([this.importanceDropdown]);
}
/* --- PARAMETERS LIST --- */
var parameterWidgets = (0, _util.filterAndMap)(template.parameters, function (param) {
if (_this.isShellTemplate) {
if (param.name == "1") {
_this.shellParam1Value = param.value;
return false;
}
return param.name !== "class";
}
return param.name !== "class" && param.name !== "importance";
}, function (param) {
return new _ParameterWidget["default"](param, template.paramData[param.name], {
$overlay: _this.$overlay
});
});
this.parameterList = new _ParameterListWidget["default"]({
items: parameterWidgets,
preferences: this.preferences
});
/* --- ADD PARAMETER SECTION --- */
this.addParameterNameInput = new _SuggestionLookupTextInputWidget["default"]({
suggestions: template.parameterSuggestions,
placeholder: "parameter name",
$element: $("<div style='display:inline-block;width:40%'>"),
validate: function (val) {
var _this$getAddParameter = this.getAddParametersInfo(val),
validName = _this$getAddParameter.validName,
name = _this$getAddParameter.name,
value = _this$getAddParameter.value;
return !name && !value ? true : validName;
}.bind(this),
allowSuggestionsWhenEmpty: true,
$overlay: this.$overlay
});
this.updateAddParameterNameSuggestions();
this.addParameterValueInput = new _SuggestionLookupTextInputWidget["default"]({
placeholder: "parameter value",
$element: $("<div style='display:inline-block;width:40%'>"),
validate: function (val) {
var _this$getAddParameter2 = this.getAddParametersInfo(null, val),
validValue = _this$getAddParameter2.validValue,
name = _this$getAddParameter2.name,
value = _this$getAddParameter2.value;
return !name && !value ? true : validValue;
}.bind(this),
allowSuggestionsWhenEmpty: true,
$overlay: this.$overlay
});
this.addParameterButton = new OO.ui.ButtonWidget({
label: "Add",
icon: "add",
flags: "progressive"
}).setDisabled(true);
this.addParameterControls = new _HorizontalLayoutWidget["default"]({
items: [this.addParameterNameInput, new OO.ui.LabelWidget({
label: "="
}), this.addParameterValueInput, this.addParameterButton]
});
this.addParameterLayout = new OO.ui.FieldLayout(this.addParameterControls, {
label: "Add parameter:",
align: "top"
}).toggle(false);
// A hack to make messages appear on their own line
this.addParameterLayout.$element.find(".oo-ui-fieldLayout-messages").css({
"clear": "both",
"padding-top": 0
});
/* --- OVERALL LAYOUT/DISPLAY --- */
// Display the layout elements, and a rule
this.$element.addClass("rater-bannerWidget").append(this.titleLayout.$element, this.parameterList.$element, this.addParameterLayout.$element);
if (!this.isShellTemplate) {
this.$element.append($("<hr>"));
}
if (this.isShellTemplate) {
this.$element.css({
"background": "#eee",
"border-radius": "10px",
"padding": "0 10px 5px",
"margin-bottom": "12px",
"font-size": "92%"
});
}
/* --- EVENT HANDLING --- */
if (this.hasClassRatings) {
this.classDropdown.connect(this, {
"change": "onClassChange"
});
}
if (this.hasImportanceRatings) {
this.importanceDropdown.connect(this, {
"change": "onImportanceChange"
});
}
this.parameterList.connect(this, {
"change": "onParameterChange",
"addParametersButtonClick": "showAddParameterInputs",
"updatedSize": "onUpdatedSize"
});
this.addParameterButton.connect(this, {
"click": "onParameterAdd"
});
this.addParameterNameInput.connect(this, {
"change": "onAddParameterNameChange",
"enter": "onAddParameterNameEnter",
"choose": "onAddParameterNameEnter"
});
this.addParameterValueInput.connect(this, {
"change": "onAddParameterValueChange",
"enter": "onAddParameterValueEnter",
"choose": "onAddParameterValueEnter"
});
this.removeButton.connect(this, {
"click": "onRemoveButtonClick"
});
this.clearButton.connect(this, {
"click": "onClearButtonClick"
});
/* --- APPLY PREF -- */
if (this.preferences.bypassRedirects) {
this.bypassRedirect();
}
}
OO.inheritClass(BannerWidget, OO.ui.Widget);
/**
* @param {String} templateName
* @param {Object} [data]
* @param {Boolean} data.withoutRatings
* @param {Boolean} data.isWrapper
* @param {Object} config
* @returns {Promise<BannerWidget>}
*/
BannerWidget.newFromTemplateName = function (templateName, data, config) {
var template = new _Template.Template();
template.name = templateName;
if (data && data.withoutRatings) {
template.withoutRatings = true;
}
return (0, _Template.getWithRedirectTo)(template).then(function (template) {
return $.when(template.setClassesAndImportances(), template.setParamDataAndSuggestions()).then(function () {
// Add missing required/suggested values
template.addMissingParams();
// Return the now-modified template
return template;
});
}).then(function (template) {
return new BannerWidget(template, config);
});
};
BannerWidget.prototype.onUpdatedSize = function () {
// Emit an "updatedSize" event so the parent window can update size, if needed
this.emit("updatedSize");
};
BannerWidget.prototype.setChanged = function () {
this.changed = true;
this.emit("changed");
if (this.mainText === "WikiProject Biography" || this.redirectTargetMainText === "WikiProject Biography") {
// Emit event so BannerListWidget can update the banner shell template (if present)
this.emit("biographyBannerChange");
}
};
BannerWidget.prototype.onParameterChange = function () {
this.setChanged();
this.updateAddParameterNameSuggestions();
};
BannerWidget.prototype.onClassChange = function () {
this.setChanged();
this.classChanged = true;
var classItem = this.classDropdown.getMenu().findSelectedItem();
if (classItem && classItem.getData() == null) {
// clear selection
this.classDropdown.getMenu().selectItem();
}
};
BannerWidget.prototype.onImportanceChange = function () {
this.setChanged();
this.importanceChanged = true;
var importanceItem = this.importanceDropdown.getMenu().findSelectedItem();
if (importanceItem && importanceItem.getData() == null) {
// clear selection
this.importanceDropdown.getMenu().selectItem();
}
};
BannerWidget.prototype.showAddParameterInputs = function () {
this.addParameterLayout.toggle(true);
this.addParameterNameInput.focus();
this.onUpdatedSize();
};
BannerWidget.prototype.getAddParametersInfo = function (nameInputVal, valueInputVal) {
var name = nameInputVal && nameInputVal.trim() || this.addParameterNameInput.getValue().trim();
var paramAlreadyIncluded = name === "class" || name === "importance" || name === "1" && this.isShellTemplate || this.parameterList.getParameterItems().some(function (paramWidget) {
return paramWidget.name === name;
});
var value = valueInputVal && valueInputVal.trim() || this.addParameterValueInput.getValue().trim();
var autovalue = name && this.paramData[name] && this.paramData[name].autovalue || null;
return {
validName: !!(name && !paramAlreadyIncluded),
validValue: !!(value || autovalue),
isAutovalue: !!(!value && autovalue),
isAlreadyIncluded: !!(name && paramAlreadyIncluded),
name: name,
value: value,
autovalue: autovalue
};
};
BannerWidget.prototype.onAddParameterNameChange = function () {
var _this$getAddParameter3 = this.getAddParametersInfo(),
validName = _this$getAddParameter3.validName,
validValue = _this$getAddParameter3.validValue,
isAutovalue = _this$getAddParameter3.isAutovalue,
isAlreadyIncluded = _this$getAddParameter3.isAlreadyIncluded,
name = _this$getAddParameter3.name,
autovalue = _this$getAddParameter3.autovalue;
// Set value input placeholder as the autovalue
this.addParameterValueInput.$input.attr("placeholder", autovalue || "");
// Set suggestions, if the parameter has a list of allowed values
var allowedValues = this.paramData[name] && this.paramData[name].allowedValues && this.paramData[name].allowedValues.map(function (val) {
return {
data: val,
label: val
};
});
this.addParameterValueInput.setSuggestions(allowedValues || []);
// Set button disabled state based on validity
this.addParameterButton.setDisabled(!validName || !validValue);
// Show notice if autovalue will be used
this.addParameterLayout.setNotices(validName && isAutovalue ? ["Parameter value will be autofilled"] : []);
// Show error is the banner already has the parameter set
this.addParameterLayout.setErrors(isAlreadyIncluded ? ["Parameter is already present"] : []);
};
BannerWidget.prototype.onAddParameterNameEnter = function () {
this.addParameterValueInput.focus();
};
BannerWidget.prototype.onAddParameterValueChange = function () {
var _this$getAddParameter4 = this.getAddParametersInfo(),
validName = _this$getAddParameter4.validName,
validValue = _this$getAddParameter4.validValue,
isAutovalue = _this$getAddParameter4.isAutovalue;
this.addParameterButton.setDisabled(!validName || !validValue);
this.addParameterLayout.setNotices(validName && isAutovalue ? ["Parameter value will be autofilled"] : []);
};
BannerWidget.prototype.onAddParameterValueEnter = function () {
// Make sure button state has been updated
this.onAddParameterValueChange();
// Do nothing if button is disabled (i.e. name and/or value are invalid)
if (this.addParameterButton.isDisabled()) {
return;
}
// Add parameter
this.onParameterAdd();
};
BannerWidget.prototype.onParameterAdd = function () {
var _this$getAddParameter5 = this.getAddParametersInfo(),
validName = _this$getAddParameter5.validName,
validValue = _this$getAddParameter5.validValue,
name = _this$getAddParameter5.name,
value = _this$getAddParameter5.value,
autovalue = _this$getAddParameter5.autovalue;
if (!validName || !validValue) {
// Error should already be shown via onAddParameter...Change methods
return;
}
var newParameter = new _ParameterWidget["default"]({
"name": name,
"value": value || autovalue
}, this.paramData[name], {
$overlay: this.$overlay
});
this.parameterList.addItems([newParameter]);
this.addParameterNameInput.setValue("");
this.addParameterValueInput.setValue("");
this.addParameterNameInput.$input.focus();
};
BannerWidget.prototype.updateAddParameterNameSuggestions = function () {
var paramsInUse = {};
this.parameterList.getParameterItems().forEach(function (paramWidget) {
return paramsInUse[paramWidget.name] = true;
});
this.addParameterNameInput.setSuggestions(this.parameterSuggestions.filter(function (suggestion) {
return !paramsInUse[suggestion.data];
}));
};
BannerWidget.prototype.onRemoveButtonClick = function () {
this.emit("remove");
};
BannerWidget.prototype.onClearButtonClick = function () {
this.parameterList.clearItems(this.parameterList.getParameterItems());
if (this.hasClassRatings) {
this.classDropdown.getMenu().selectItem();
}
if (this.hasImportanceRatings) {
this.importanceDropdown.getMenu().selectItem();
}
};
BannerWidget.prototype.bypassRedirect = function () {
if (!this.redirectTargetMainText) {
return;
}
// Store the bypassed name
this.bypassedName = this.name;
// Update title label
this.mainLabelPopupButton.setLabel("{{".concat(this.redirectTargetMainText, "}}").concat(this.inactiveProject ? " (inactive)" : ""));
// Update properties
this.name = this.redirectTargetMainText;
this.mainText = this.redirectTargetMainText;
this.redirectTargetMainText = null;
this.setChanged();
};
BannerWidget.prototype.makeWikitext = function () {
if (!this.changed && this.wikitext) {
return this.wikitext;
}
var pipe = this.pipeStyle;
var equals = this.equalsStyle;
var classItem = (this.hasClassRatings || this.isShellTemplate) && this.classDropdown.getMenu().findSelectedItem();
var classVal = classItem && classItem.getData();
var importanceItem = this.hasImportanceRatings && this.importanceDropdown.getMenu().findSelectedItem();
var importanceVal = importanceItem && importanceItem.getData();
return ("{{" + this.name + ((this.hasClassRatings || this.isShellTemplate) && classVal != null ? "".concat(pipe, "class").concat(equals).concat(classVal || "") : "") + (this.hasImportanceRatings && importanceVal != null ? "".concat(pipe, "importance").concat(equals).concat(importanceVal || "") : "") + this.parameterList.getParameterItems().map(function (parameter) {
return parameter.makeWikitext(pipe, equals);
}).join("") + this.endBracesStyle).replace(/\n+}}$/, "\n}}"); // avoid empty line at end like [[Special:Diff/925982142]]
};
BannerWidget.prototype.setPreferences = function (prefs) {
this.preferences = prefs;
if (this.preferences.bypassRedirects) {
this.bypassRedirect();
}
this.parameterList.setPreferences(prefs);
};
var _default = exports["default"] = BannerWidget; // </nowiki>
},{"../../Template":3,"../../config":18,"../../util":23,"./DropdownParameterWidget":6,"./HorizontalLayoutWidget":7,"./ParameterListWidget":8,"./ParameterWidget":9,"./SuggestionLookupTextInputWidget":11}],6:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
function DropdownParameterWidget(config) {
// Configuration initialization
config = $.extend({
$element: $("<span style='display:inline-block;width:24%'>")
}, config || {});
// Call parent constructor
DropdownParameterWidget["super"].call(this, config);
this.$overlay = config.$overlay;
this.$element.addClass("rater-dropdownParameterWidget");
// Autofilled icon
this.autofilled = !!config.autofilled;
this.autofilledIcon = new OO.ui.IconWidget({
icon: "robot",
title: "Autofilled by Rater",
flags: "progressive",
$element: $("<span style='margin: 0 -5px 0 5px;min-width: 16px;width: 16px;left:unset;'>")
}).toggle(this.autofilled);
this.$element.find(".oo-ui-indicatorElement-indicator").before(this.autofilledIcon.$element);
// Events
this.menu.connect(this, {
"choose": "onDropdownMenuChoose",
"select": "onDropdownMenuSelect"
});
}
OO.inheritClass(DropdownParameterWidget, OO.ui.DropdownWidget);
DropdownParameterWidget.prototype.setAutofilled = function (setAutofill) {
this.autofilledIcon.toggle(!!setAutofill);
this.$element.find(".oo-ui-dropdownWidget-handle").css({
"border": setAutofill ? "1px dashed #36c" : ""
});
this.autofilled = !!setAutofill;
};
DropdownParameterWidget.prototype.onDropdownMenuChoose = function () {
this.setAutofilled(false);
this.emit("change");
};
DropdownParameterWidget.prototype.onDropdownMenuSelect = function () {
this.emit("change");
};
DropdownParameterWidget.prototype.getValue = function () {
var selectedItem = this.menu.findSelectedItem();
return selectedItem && selectedItem.getData();
};
var _default = exports["default"] = DropdownParameterWidget; // </nowiki>
},{}],7:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
// <nowiki>
/**
* A HorizontalLayout that is also a widget, and can thus be placed within
* field layouts.
*
* @class
* @param {*} config configuration for OO.ui.HorizontalLayout
*/
function HorizontalLayoutWidget(config) {
// Configuration initialization
config = config || {};
// Call parent constructor
HorizontalLayoutWidget["super"].call(this, {});
this.layout = new OO.ui.HorizontalLayout(_objectSpread(_objectSpread({}, config), {}, {
$element: this.$element
}));
}
OO.inheritClass(HorizontalLayoutWidget, OO.ui.Widget);
var _default = exports["default"] = HorizontalLayoutWidget; // </nowiki>
},{}],8:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
/**
* @cfg {OO.ui.Element[]} items Items to be added
* @cfg {Number} displayLimit The most to show at once. If the number of items
* is more than this, then only the first (displayLimit - 1) items are shown.
*/
var ParameterListWidget = function ParameterListWidget(config) {
config = config || {};
// Call parent constructor
ParameterListWidget.parent.call(this, config);
OO.ui.mixin.GroupElement.call(this, {
$group: this.$element
});
this.addItems(config.items);
this.$element.addClass("rater-parameterListWidget");
this.preferences = config.preferences;
// Hide some parameters (initially), if more than set display limit -- which is the
// one more than collapseParamsLowerLimit, to prevent only one param being hidden
// (mostly: may occasionally occur if params were auto-filled).
var displayLimit = this.preferences.collapseParamsLowerLimit + 1;
if (displayLimit && this.items.length > displayLimit) {
var hideFromNumber = displayLimit - 1; // One-indexed
var hideFromIndex = hideFromNumber - 1; // Zero-indexed
var hiddenCount = 0;
for (var i = hideFromIndex; i < this.items.length; i++) {
if (!this.items[i].autofilled) {
// Don't hide auto-filled params
this.items[i].toggle(false);
hiddenCount++;
}
}
if (hiddenCount > 0) {
// Add button to show the hidden params
this.showMoreParametersButton = new OO.ui.ButtonWidget({
label: "Show " + hiddenCount + " more " + (hiddenCount === 1 ? "parameter" : "parameters"),
framed: false,
$element: $("<span style='margin-bottom:0'>")
});
this.addItems([this.showMoreParametersButton]);
}
}
// Add the button that allows user to add more parameters
this.addParametersButton = new OO.ui.ButtonWidget({
label: "Add parameter",
icon: "add",
framed: false,
$element: $("<span style='margin-bottom:0'>")
});
this.addItems([this.addParametersButton]);
/* --- Events --- */
// Handle delete events from ParameterWidgets
this.aggregate({
"delete": "parameterDelete"
});
this.connect(this, {
parameterDelete: "onParameterDelete"
});
// Handle change events from ParameterWidgets
this.aggregate({
change: "parameterChange"
});
this.connect(this, {
parameterChange: "onParameterChange"
});
// Handle updatedSize events from ParameterWidgets
this.aggregate({
"updatedSize": "parameterUpdatedSize"
});
this.connect(this, {
"parameterUpdatedSize": "onUpdatedSize"
});
// Handle button clicks
if (this.showMoreParametersButton) {
this.showMoreParametersButton.connect(this, {
"click": "onShowMoreParametersButtonClick"
});
}
this.addParametersButton.connect(this, {
"click": "onAddParametersButtonClick"
});
};
OO.inheritClass(ParameterListWidget, OO.ui.Widget);
OO.mixinClass(ParameterListWidget, OO.ui.mixin.GroupElement);
/*
methods from mixin:
- addItems( items, [index] ) : OO.ui.Element (CHAINABLE)
- clearItems( ) : OO.ui.Element (CHAINABLE)
- findItemFromData( data ) : OO.ui.Element|null
- findItemsFromData( data ) : OO.ui.Element[]
- removeItems( items ) : OO.ui.Element (CHAINABLE)
*/
ParameterListWidget.prototype.onUpdatedSize = function () {
// Emit an "updatedSize" event so the parent window can update size, if needed
this.emit("updatedSize");
};
ParameterListWidget.prototype.addItems = function (items, index) {
if (items.length === 0) {
return this;
}
// Call mixin method to do the adding
OO.ui.mixin.GroupElement.prototype.addItems.call(this, items, index);
// emit updatedSize event
this.onUpdatedSize();
return this;
};
ParameterListWidget.prototype.onParameterDelete = function (parameter) {
this.removeItems([parameter]);
this.emit("change");
};
ParameterListWidget.prototype.onParameterChange = function () {
this.emit("change");
};
ParameterListWidget.prototype.getParameterItems = function () {
return this.items.filter(function (item) {
return item.constructor.name === "ParameterWidget";
});
};
ParameterListWidget.prototype.onShowMoreParametersButtonClick = function () {
this.removeItems([this.showMoreParametersButton]);
this.items.forEach(function (parameterWidget) {
return parameterWidget.toggle(true);
});
this.onUpdatedSize();
};
ParameterListWidget.prototype.onAddParametersButtonClick = function () {
this.removeItems([this.addParametersButton]);
this.emit("addParametersButtonClick");
};
ParameterListWidget.prototype.makeWikitext = function (pipeStyle, equalsStyle) {
return this.getParameterItems().map(function (parameter) {
return parameter.makeWikitext(pipeStyle, equalsStyle);
}).join("");
};
ParameterListWidget.prototype.setPreferences = function (prefs) {
this.preferences = prefs;
var params = this.getParameterItems();
// Unhide some parameters of the collapseParamsLowerLimit has increased.
// (Not hiding any if it decreased, since it's a *lower* limit of what needs to be shown.)
if (params.length <= this.preferences.collapseParamsLowerLimit) {
return;
}
var hiddenParams = params.filter(function (param) {
return !param.isVisible();
});
var visibleParamsCount = params.length - hiddenParams.length;
if (hiddenParams === 0 || visibleParamsCount >= this.preferences.collapseParamsLowerLimit) {
return;
}
var numToUnhide = Math.min(this.preferences.collapseParamsLowerLimit - visibleParamsCount, hiddenParams.length);
for (var i = 0; i < numToUnhide; i++) {
hiddenParams[i].toggle(true);
}
var stillHiddenCount = hiddenParams.length - numToUnhide;
if (stillHiddenCount === 0) {
this.removeItems([this.showMoreParametersButton]);
} else {
this.showMoreParametersButton.setLabel("Show " + stillHiddenCount + " more " + (stillHiddenCount === 1 ? "paramter" : "paramters"));
}
};
var _default = exports["default"] = ParameterListWidget; // </nowiki>
},{}],9:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _util = require("../../util");
var _HorizontalLayoutWidget = _interopRequireDefault(require("./HorizontalLayoutWidget"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
// <nowiki>
function ParameterWidget(parameter, paramData, config) {
// Configuration initialization
config = config || {};
// Call parent constructor
ParameterWidget["super"].call(this, config);
this.$overlay = config.$overlay;
this.name = parameter.name;
this.value = parameter.value;
this.autofilled = parameter.autofilled;
this.isInvalid = parameter.value == null;
this.paramData = paramData || {};
this.allowedValues = this.paramData.allowedValues || [];
this.isRequired = this.paramData.required;
this.isSuggested = this.paramData.suggested;
// Make a checkbox if only 1 or 2 allowed values
switch (this.allowedValues.length) {
/* eslint-disable no-fallthrough */
case 1:
this.allowedValues[1] = null;
/* fall-through */
case 2:
var isFirstAllowedVal = this.allowedValues.indexOf(parameter.value) === 0 || this.allowedValues.map(_util.normaliseYesNo).indexOf((0, _util.normaliseYesNo)(parameter.value)) === 0;
var isSecondAllowedVal = this.allowedValues.indexOf(parameter.value || null) === 1 || this.allowedValues.map(_util.normaliseYesNo).indexOf(parameter.value ? (0, _util.normaliseYesNo)(parameter.value) : null) === 1;
var isIndeterminate = !isFirstAllowedVal && !isSecondAllowedVal;
this.checkbox = new OO.ui.CheckboxInputWidget({
selected: isIndeterminate ? undefined : isFirstAllowedVal,
indeterminate: isIndeterminate ? true : undefined,
$element: $("<label style='margin:0 0 0 5px'>")
});
break;
default:
// No checkbox
} /* eslint-enable no-fallthrough */
/* --- EDIT PARAMETER LAYOUT --- */
this.input = new OO.ui.ComboBoxInputWidget({
value: this.value,
// label: parameter.name + " =",
// labelPosition: "before",
options: (0, _util.filterAndMap)(this.allowedValues, function (val) {
return val !== null;
}, function (val) {
return {
data: val,
label: val
};
}),
$element: $("<div style='margin-bottom:0;'>"),
$overlay: this.$overlay
});
// Reduce the excessive whitespace/height
this.input.$element.find("input").css({
"padding-top": 0,
"padding-bottom": "2px",
"height": "24px"
});
// Fix label positioning within the reduced height
this.input.$element.find("span.oo-ui-labelElement-label").css({
"line-height": "normal"
});
// Also reduce height of dropdown button (if options are present)
this.input.$element.find("a.oo-ui-buttonElement-button").css({
"padding-top": 0,
"height": "24px",
"min-height": "0"
});
this.confirmButton = new OO.ui.ButtonWidget({
icon: "check",
label: "Done",
framed: false,
flags: "progressive",
$element: $("<span style='margin-right:0'>")
});
this.cancelButton = new OO.ui.ButtonWidget({
icon: "undo",
label: "Cancel",
framed: false
});
this.deleteButton = new OO.ui.ButtonWidget({
icon: this.isRequired ? "restore" : "trash",
label: this.isRequired ? "Required parameter" : "Delete",
framed: false,
flags: "destructive",
disabled: this.isRequired
});
this.editButtonControls = new OO.ui.ButtonGroupWidget({
items: [this.confirmButton, this.cancelButton, this.deleteButton],
$element: $("<span style='font-size:92%'>")
});
this.editButtonControls.$element.find("a span:first-child").css({
"min-width": "unset",
"width": "16px",
"margin-right": 0
});
this.editLayoutControls = new _HorizontalLayoutWidget["default"]({
items: [this.input, this.editButtonControls]
//$element: $("<div style='width: 48%;margin:0;'>")
});
this.editLayout = new OO.ui.FieldLayout(this.editLayoutControls, {
label: this.name + " =",
align: "top",
help: this.paramData.description && this.paramData.description.en || false,
helpInline: true
}).toggle();
this.editLayout.$element.find("label.oo-ui-inline-help").css({
"margin": "-10px 0 5px 10px"
});
/* --- READ (COLLAPSED) DISPLAY OF PARAMETER --- */
this.invalidIcon = new OO.ui.IconWidget({
icon: "block",
title: "Invalid parameter: no value specified!",
flags: "destructive",
$element: $("<span style='margin: 0 5px 0 -5px; min-width: 16px; width: 16px;'>")
}).toggle(this.isInvalid);
this.fullLabel = new OO.ui.LabelWidget({
label: this.name + (this.value ? " = " + this.value : " "),
$element: $("<label style='margin: 0;'>")
});
this.autofilledIcon = new OO.ui.IconWidget({
icon: "robot",
title: "Autofilled by Rater",
flags: "progressive",
$element: $("<span style='margin: 0 -5px 0 5px;min-width: 16px;width: 16px;'>")
}).toggle(this.autofilled);
this.editButton = new OO.ui.ButtonWidget({
icon: "edit",
framed: false,
$element: $("<span style='margin-bottom: 0;'>")
});
this.editButton.$element.find("a").css({
"border-radius": "0 10px 10px 0",
"margin-left": "5px"
});
this.editButton.$element.find("a span").first().css({
"min-width": "unset",
"width": "16px"
});
this.readLayout = new OO.ui.HorizontalLayout({
items: [this.invalidIcon, this.fullLabel, this.autofilledIcon, this.editButton],
$element: $("<span style='margin:0;width:unset;'>")
});
if (this.checkbox) {
this.readLayout.addItems([this.checkbox], 2);
}
/* --- CONTAINER FOR BOTH LAYOUTS --- */
this.$element = $("<div>").addClass("rater-parameterWidget").css({
"width": "unset",
"display": "inline-block",
"border": this.autofilled ? "1px dashed #36c" : "1px solid #ddd",
"border-radius": "10px",
"padding-left": "10px",
"margin": "0 8px 8px 0",
"background": this.isInvalid ? "#fddd" : "#fffe"
}).append(this.readLayout.$element, this.editLayout.$element);
this.editButton.connect(this, {
"click": "onEditClick"
});
this.confirmButton.connect(this, {
"click": "onConfirmClick"
});
this.cancelButton.connect(this, {
"click": "onCancelClick"
});
this.deleteButton.connect(this, {
"click": "onDeleteClick"
});
if (this.checkbox) {
this.checkbox.connect(this, {
"change": "onCheckboxChange"
});
}
}
OO.inheritClass(ParameterWidget, OO.ui.Widget);
ParameterWidget.prototype.onUpdatedSize = function () {
// Emit an "updatedSize" event so the parent window can update size, if needed
this.emit("updatedSize");
};
ParameterWidget.prototype.onEditClick = function () {
this.readLayout.toggle(false);
this.editLayout.toggle(true);
this.$element.css({
"background": "#fffe"
});
this.input.focus();
this.onUpdatedSize();
};
ParameterWidget.prototype.onConfirmClick = function () {
this.setValue(this.input.getValue());
this.readLayout.toggle(true);
this.editLayout.toggle(false);
this.onUpdatedSize();
};
ParameterWidget.prototype.onCancelClick = function () {
this.input.setValue(this.value);
this.readLayout.toggle(true);
this.editLayout.toggle(false);
this.onUpdatedSize();
};
ParameterWidget.prototype.onDeleteClick = function () {
this["delete"]();
};
ParameterWidget.prototype.onCheckboxChange = function (isSelected, isIndeterminate) {
if (isIndeterminate) {
return;
}
if (isSelected) {
this.setValue(this.allowedValues[0]);
} else {
this.setValue(this.allowedValues[1]);
}
};
ParameterWidget.prototype["delete"] = function () {
this.emit("delete");
};
ParameterWidget.prototype.setValue = function (val) {
// Turn off autofill stylings/icon
this.autofilled = false;
this.autofilledIcon.toggle(false);
this.$element.css({
"border": "1px solid #ddd"
});
// Update the stored value
this.value = val;
// Update the input value for edit mode
this.input.setValue(this.value);
// Update validity
this.isInvalid = this.value == null;
this.invalidIcon.toggle(this.isInvalid);
this.$element.css({
"background": this.isInvalid ? "#fddd" : "#fffe"
});
// Updated the label for read mode
this.fullLabel.setLabel(this.name + (this.value ? " = " + this.value : ""));
// Update the checkbox (if there is one)
if (this.checkbox) {
var isFirstAllowedVal = this.allowedValues.indexOf(val) === 0 || this.allowedValues.map(_util.normaliseYesNo).indexOf((0, _util.normaliseYesNo)(val)) === 0;
var isSecondAllowedVal = this.allowedValues.indexOf(val || null) === 1 || this.allowedValues.map(_util.normaliseYesNo).indexOf(val ? (0, _util.normaliseYesNo)(val) : null) === 1;
var isIndeterminate = !isFirstAllowedVal && !isSecondAllowedVal;
this.checkbox.setIndeterminate(isIndeterminate, true);
if (!isIndeterminate) {
var isSelected = isFirstAllowedVal;
this.checkbox.setSelected(isSelected, true);
}
}
// Emit a change event
this.emit("change");
};
ParameterWidget.prototype.setAutofilled = function () {
this.autofilled = true;
this.autofilledIcon.toggle(true);
this.$element.css({
"border": "1px dashed #36c"
});
};
ParameterWidget.prototype.makeWikitext = function (pipeStyle, equalsStyle) {
if (this.isInvalid) {
return "";
}
return pipeStyle + this.name + equalsStyle + (this.value || "");
};
ParameterWidget.prototype.focusInput = function () {
return this.input.focus();
};
var _default = exports["default"] = ParameterWidget; // </nowiki>
},{"../../util":23,"./HorizontalLayoutWidget":7}],10:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("../../config"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
// <nowiki>
function PrefsFormWidget(config) {
// Configuration initialization
config = config || {};
// Call parent constructor
PrefsFormWidget["super"].call(this, config);
this.$element.addClass("rater-prefsFormWidget");
this.layout = new OO.ui.FieldsetLayout({
label: "Preferences",
$element: this.$element
});
this.preferences = {
"autostart": {
input: new OO.ui.ToggleSwitchWidget(),
label: "Autostart Rater"
},
"autostartRedirects": {
input: new OO.ui.ToggleSwitchWidget(),
label: "Autostart on redirects"
},
"autostartNamespaces": {
input: new mw.widgets.NamespacesMultiselectWidget(),
label: "Autostart in these namespaces"
},
"bypassRedirects": {
input: new OO.ui.ToggleSwitchWidget(),
label: "Bypass redirects to banners"
},
"autofillClassFromOthers": {
input: new OO.ui.ToggleSwitchWidget(),
label: "Autofill class from other banners"
},
"autofillClassFromOres": {
input: new OO.ui.ToggleSwitchWidget(),
label: "Autofill class based on ORES prediction"
},
"autofillImportance": {
input: new OO.ui.ToggleSwitchWidget(),
label: "Autofill low importance"
},
"collapseParamsLowerLimit": {
input: new OO.ui.NumberInputWidget({
"min": 1
}),
label: "Minimum number of parameters to show uncollapsed"
},
"watchlist": {
input: new OO.ui.ButtonSelectWidget({
items: [new OO.ui.ButtonOptionWidget({
data: "preferences",
label: "Default",
title: "Uses the same setting as if you manually edited the page, as per Special:Preferences"
}), new OO.ui.ButtonOptionWidget({
data: "watch",
label: "Always",
title: "Always add pages Rater edits to your watchlist"
}), new OO.ui.ButtonOptionWidget({
data: "nochange",
label: "Never",
title: "Never add pages Rater edit to your watchlist"
})]
}).selectItemByData("preferences"),
label: "Add edited pages to watchlist"
},
"resetCache": {
input: new OO.ui.ButtonWidget({
label: "Reset cache",
title: "Remove cached data, including list of WikiProjects and template parameters",
flags: ["destructive"]
})
}
};
for (var prefName in this.preferences) {
this.layout.addItems([new OO.ui.FieldLayout(this.preferences[prefName].input, {
label: this.preferences[prefName].label,
align: "right"
})]);
}
this.preferences.resetCache.input.connect(this, {
"click": "onResetCacheClick"
});
}
OO.inheritClass(PrefsFormWidget, OO.ui.Widget);
PrefsFormWidget.prototype.setPrefValues = function (prefs) {
var _this = this;
var _loop = function _loop() {
var value = prefs[prefName];
var input = _this.preferences[prefName] && _this.preferences[prefName].input;
switch (input && input.constructor.name) {
case "OoUiButtonSelectWidget":
input.selectItemByData(value);
break;
case "OoUiNumberInputWidget":
case "OoUiToggleSwitchWidget":
input.setValue(value);
break;
case "MwWidgetsNamespacesMultiselectWidget":
input.clearItems();
value.forEach(function (ns) {
return input.addTag(ns.toString(), ns === 0 ? "(Main)" : _config["default"].mw.wgFormattedNamespaces[ns]);
});
break;
}
};
for (var prefName in prefs) {
_loop();
}
};
PrefsFormWidget.prototype.getPrefs = function () {
var prefs = {};
for (var prefName in this.preferences) {
var input = this.preferences[prefName].input;
var value = void 0;
switch (input.constructor.name) {
case "OoUiButtonSelectWidget":
value = input.findSelectedItem().getData();
break;
case "OoUiToggleSwitchWidget":
value = input.getValue();
break;
case "OoUiNumberInputWidget":
value = Number(input.getValue()); // widget uses strings, not numbers!
break;
case "MwWidgetsNamespacesMultiselectWidget":
value = input.getValue().map(Number); // widget uses strings, not numbers!
break;
}
prefs[prefName] = value;
}
return prefs;
};
PrefsFormWidget.prototype.onResetCacheClick = function () {
var _this2 = this;
OO.ui.confirm("After reseting cache, Rater will close and restart. Any changes made will be discarded.").then(function (confirmed) {
if (confirmed) {
_this2.emit("resetCache");
}
});
};
var _default = exports["default"] = PrefsFormWidget; // </nowiki>
},{"../../config":18}],11:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
var SuggestionLookupTextInputWidget = function SuggestionLookupTextInputWidget(config) {
OO.ui.TextInputWidget.call(this, config);
OO.ui.mixin.LookupElement.call(this, config);
this.suggestions = Array.isArray(config.suggestions) ? config.suggestions : [];
this.$element.addClass("rater-suggestionLookupTextInputWidget");
};
OO.inheritClass(SuggestionLookupTextInputWidget, OO.ui.TextInputWidget);
OO.mixinClass(SuggestionLookupTextInputWidget, OO.ui.mixin.LookupElement);
// Set suggestion. param: Object[] with objects of the form { data: ... , label: ... }
SuggestionLookupTextInputWidget.prototype.setSuggestions = function (suggestions) {
if (!Array.isArray(suggestions)) {
if (suggestions != null) {
console.warn("[Rater] SuggestionLookupTextInputWidget.prototype.setSuggestions called with a non-array value:", suggestions);
}
return;
}
this.suggestions = suggestions;
};
// Returns data, as a resolution to a promise, to be passed to #getLookupMenuOptionsFromData
SuggestionLookupTextInputWidget.prototype.getLookupRequest = function () {
var deferred = $.Deferred().resolve(new RegExp("\\b" + mw.util.escapeRegExp(this.getValue()), "i"));
return deferred.promise({
abort: function abort() {}
});
};
// ???
SuggestionLookupTextInputWidget.prototype.getLookupCacheDataFromResponse = function (response) {
return response || [];
};
// Is passed data from #getLookupRequest, returns an array of menu item widgets
SuggestionLookupTextInputWidget.prototype.getLookupMenuOptionsFromData = function (pattern) {
var labelMatchesInputVal = function labelMatchesInputVal(suggestionItem) {
return pattern.test(suggestionItem.label) || !suggestionItem.label && pattern.test(suggestionItem.data);
};
var makeMenuOptionWidget = function makeMenuOptionWidget(optionItem) {
return new OO.ui.MenuOptionWidget({
data: optionItem.data,
label: optionItem.label || optionItem.data
});
};
return this.suggestions.filter(labelMatchesInputVal).map(makeMenuOptionWidget);
};
// Extend onLookupMenuChoose method to emit an choose event
SuggestionLookupTextInputWidget.prototype.onLookupMenuChoose = function (item) {
// Get data
var itemData = item.getData();
// Simplify item data if it is an object with a name property
if (itemData && itemData.name) {
item.setData(itemData.name);
}
// First blur the input, to prevent the menu popping back up
this.$input.blur();
OO.ui.mixin.LookupElement.prototype.onLookupMenuChoose.call(this, item);
this.emit("choose", itemData);
};
var _default = exports["default"] = SuggestionLookupTextInputWidget; // </nowiki>
},{}],12:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("../../config"));
var _SuggestionLookupTextInputWidget = _interopRequireDefault(require("./SuggestionLookupTextInputWidget"));
var _getBanners = require("../../getBanners");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
// <nowiki>
function TopBarWidget(config) {
var _this = this;
// Configuration initialization
config = $.extend({
expanded: false,
framed: false,
padded: false
}, config || {});
// Call parent constructor
TopBarWidget["super"].call(this, config);
this.$overlay = config.$overlay;
// Search box
this.searchBox = new _SuggestionLookupTextInputWidget["default"]({
placeholder: "Add a WikiProject...",
$element: $("<div style='display:inline-block; margin:0 -1px; width:calc(100% - 55px);'>"),
$overlay: this.$overlay
});
(0, _getBanners.getBannerNames)().then(function (banners) {
return [].concat(_toConsumableArray(banners.withRatings.map(function (bannerName) {
return {
label: bannerName.replace("WikiProject ", ""),
data: {
name: bannerName
}
};
})), _toConsumableArray(banners.withoutRatings.map(function (bannerName) {
return {
label: bannerName.replace("WikiProject ", ""),
data: {
name: bannerName,
withoutRatings: true
}
};
})), _toConsumableArray(banners.wrappers.map(function (bannerName) {
return {
label: bannerName.replace("WikiProject ", "") + " [template wrapper]",
data: {
name: bannerName,
wrapper: true
}
};
})), _toConsumableArray(banners.notWPBM.map(function (bannerName) {
return {
label: bannerName.replace("WikiProject ", ""),
data: {
name: bannerName
}
};
})), _toConsumableArray(banners.inactive.map(function (bannerName) {
return {
label: bannerName.replace("WikiProject ", "") + " [inactive]",
data: {
name: bannerName,
withoutRatings: true
}
};
})), _toConsumableArray(banners.wir.map(function (bannerName) {
return {
label: bannerName + " [Women In Red meetup/initiative]",
data: {
name: bannerName,
withoutRatings: true
}
};
})));
}).then(function (bannerOptions) {
return _this.searchBox.setSuggestions(bannerOptions);
});
// Add button
this.addBannerButton = new OO.ui.ButtonWidget({
icon: "add",
title: "Add",
flags: "progressive",
$element: $("<span style='float:right;margin: 0;transform: translateX(-12px);'>")
});
var $searchContainer = $("<div style='display:inline-block; flex-shrink:1; flex-grow:100; min-width:250px; width:50%;'>").append(this.searchBox.$element, this.addBannerButton.$element);
// Set all classes/importances
// in the style of a popup button with a menu (is actually a dropdown with a hidden label, because that makes the coding easier.)
this.setAllDropDown = new OO.ui.DropdownWidget({
icon: "tag",
label: "Set all...",
invisibleLabel: true,
menu: {
items: [new OO.ui.MenuSectionOptionWidget({
label: "Classes"
}), new OO.ui.MenuOptionWidget({
data: {
"class": null
},
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(no class)</span>")
})].concat(_toConsumableArray(_config["default"].bannerDefaults.classes.map(function (classname) {
return new OO.ui.MenuOptionWidget({
data: {
"class": classname
},
label: classname
});
})), [new OO.ui.MenuSectionOptionWidget({
label: "Importances"
}), new OO.ui.MenuOptionWidget({
data: {
importance: null
},
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">(no importance)</span>")
})], _toConsumableArray(_config["default"].bannerDefaults.importances.map(function (importance) {
return new OO.ui.MenuOptionWidget({
data: {
importance: importance
},
label: importance
});
})))
},
$element: $("<span style=\"width:auto;display:inline-block;float:left;margin:0\" title='Set all...'>"),
$overlay: this.$overlay
});
// Remove all banners button
this.removeAllButton = new OO.ui.ButtonWidget({
icon: "trash",
title: "Remove all",
flags: "destructive"
});
// Clear all parameters button
this.clearAllButton = new OO.ui.ButtonWidget({
icon: "cancel",
title: "Clear all",
flags: "destructive"
});
// Group the buttons together
this.menuButtons = new OO.ui.ButtonGroupWidget({
items: [this.removeAllButton, this.clearAllButton],
$element: $("<span style='flex:1 0 auto;'>")
});
// Include the dropdown in the group
this.menuButtons.$element.prepend(this.setAllDropDown.$element);
// Put everything into a layout
this.$element.addClass("rater-topBarWidget").css({
"position": "fixed",
"width": "100%",
"background": "#ccc",
"display": "flex",
"flex-wrap": "wrap",
"justify-content": "space-around",
"margin": "-2px 0 0 0"
}).append($searchContainer, this.menuButtons.$element);
/* --- Event handling --- */
this.searchBox.connect(this, {
"enter": "onSearchSelect",
"choose": "onSearchSelect"
});
this.addBannerButton.connect(this, {
"click": "onSearchSelect"
});
this.setAllDropDown.getMenu().connect(this, {
"choose": "onRatingChoose"
});
this.removeAllButton.connect(this, {
"click": "onRemoveAllClick"
});
this.clearAllButton.connect(this, {
"click": "onClearAllClick"
});
}
OO.inheritClass(TopBarWidget, OO.ui.PanelLayout);
TopBarWidget.prototype.onSearchSelect = function (data) {
this.emit("searchSelect", data);
};
TopBarWidget.prototype.onRatingChoose = function (item) {
var data = item.getData();
if (data["class"] || data["class"] === null) {
this.emit("setClasses", data["class"]);
}
if (data.importance || data.importance === null) {
this.emit("setImportances", data.importance);
}
};
TopBarWidget.prototype.onRemoveAllClick = function () {
this.emit("removeAll");
};
TopBarWidget.prototype.onClearAllClick = function () {
this.emit("clearAll");
};
TopBarWidget.prototype.setDisabled = function (disable) {
[this.searchBox, this.addBannerButton, this.setAllDropDown, this.removeAllButton, this.clearAllButton].forEach(function (widget) {
return widget.setDisabled(disable);
});
};
var _default = exports["default"] = TopBarWidget; // </nowiki>
},{"../../config":18,"../../getBanners":20,"./SuggestionLookupTextInputWidget":11}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _api = require("../api");
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
// <nowiki>
/* var incrementProgressByInterval = function() {
var incrementIntervalDelay = 100;
var incrementIntervalAmount = 0.1;
var incrementIntervalMaxval = 98;
return window.setInterval(
incrementProgress,
incrementIntervalDelay,
incrementIntervalAmount,
incrementIntervalMaxval
);
}; */
var LoadDialog = function LoadDialog(config) {
LoadDialog["super"].call(this, config);
};
OO.inheritClass(LoadDialog, OO.ui.Dialog);
LoadDialog["static"].name = "loadDialog";
LoadDialog["static"].title = "Loading Rater...";
// Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.
LoadDialog.prototype.initialize = function () {
var _this$content$$elemen;
// Call the parent method.
LoadDialog["super"].prototype.initialize.call(this);
// Create a layout
this.content = new OO.ui.PanelLayout({
padded: true,
expanded: false
});
// Create content
this.progressBar = new OO.ui.ProgressBarWidget({
progress: 1
});
this.setuptasks = [new OO.ui.LabelWidget({
label: "Loading your Rater preferences...",
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: "Loading list of project banners...",
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: "Loading talkpage wikitext...",
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: "Parsing talkpage templates...",
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: "Getting templates' parameter data...",
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: "Checking subject page...",
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: "Retrieving quality prediction...",
$element: $("<p style=\"display:block\">")
}).toggle()];
this.closeButton = new OO.ui.ButtonWidget({
label: "Close"
}).toggle();
this.setupPromises = [];
// Append content to layout
(_this$content$$elemen = this.content.$element).append.apply(_this$content$$elemen, [this.progressBar.$element, new OO.ui.LabelWidget({
label: "Initialising:",
$element: $("<strong style=\"display:block\">")
}).$element].concat(_toConsumableArray(this.setuptasks.map(function (widget) {
return widget.$element;
})), [this.closeButton.$element]));
// Append layout to dialog
this.$body.append(this.content.$element);
// Connect events to handlers
this.closeButton.connect(this, {
"click": "onCloseButtonClick"
});
};
LoadDialog.prototype.onCloseButtonClick = function () {
// Close this dialog, without passing any data
this.close();
};
// Override the getBodyHeight() method to specify a custom height (or don't to use the automatically generated height).
LoadDialog.prototype.getBodyHeight = function () {
return this.content.$element.outerHeight(true);
};
LoadDialog.prototype.incrementProgress = function (amount, maximum) {
var priorProgress = this.progressBar.getProgress();
var incrementedProgress = Math.min(maximum || 100, priorProgress + amount);
this.progressBar.setProgress(incrementedProgress);
};
LoadDialog.prototype.addTaskPromiseHandlers = function (taskPromises) {
var _this = this;
var onTaskDone = function onTaskDone(index) {
// Add "Done!" to label
var widget = _this.setuptasks[index];
widget.setLabel(widget.getLabel() + " Done!");
// Increment status bar. Show a smooth transition by
// using small steps over a short duration.
var totalIncrement = 100 / _this.setuptasks.length; // percent
var totalTime = 400; // milliseconds
var totalSteps = 10;
var incrementPerStep = totalIncrement / totalSteps;
for (var step = 0; step < totalSteps; step++) {
window.setTimeout(_this.incrementProgress.bind(_this), totalTime * step / totalSteps, incrementPerStep);
}
};
var onTaskError = function onTaskError(index, code, info) {
var widget = _this.setuptasks[index];
widget.setLabel(widget.getLabel() + " Failed. " + (0, _api.makeErrorMsg)(code, info));
_this.closeButton.toggle(true);
_this.updateSize();
};
taskPromises.forEach(function (promise, index) {
promise.then(function () {
return onTaskDone(index);
}, function (code, info) {
return onTaskError(index, code, info);
});
});
};
// Use getSetupProcess() to set up the window with data passed to it at the time
// of opening
LoadDialog.prototype.getSetupProcess = function (data) {
var _this2 = this;
data = data || {};
return LoadDialog["super"].prototype.getSetupProcess.call(this, data).next(function () {
var showOresTask = !!data.ores;
_this2.setuptasks[6].toggle(showOresTask);
var taskPromises = data.ores ? data.promises : data.promises.slice(0, -1);
data.isOpened.then(function () {
return _this2.addTaskPromiseHandlers(taskPromises);
});
}, this);
};
// Prevent window from closing too quickly, using getHoldProcess()
LoadDialog.prototype.getHoldProcess = function (data) {
data = data || {};
if (data.success) {
// Wait a bit before processing the close, which happens automatically
return LoadDialog["super"].prototype.getHoldProcess.call(this, data).next(800);
}
// No need to wait if closed manually
return LoadDialog["super"].prototype.getHoldProcess.call(this, data);
};
// Use the getTeardownProcess() method to perform actions whenever the dialog is closed.
LoadDialog.prototype.getTeardownProcess = function (data) {
var _this3 = this;
return LoadDialog["super"].prototype.getTeardownProcess.call(this, data).first(function () {
// Perform cleanup: reset labels
_this3.setuptasks.forEach(function (setuptask) {
var currentLabel = setuptask.getLabel();
setuptask.setLabel(currentLabel.slice(0, currentLabel.indexOf("...") + 3));
});
}, this);
};
var _default = exports["default"] = LoadDialog; // </nowiki>
},{"../api":15}],14:[function(require,module,exports){
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _BannerWidget = _interopRequireDefault(require("./Components/BannerWidget"));
var _BannerListWidget = _interopRequireDefault(require("./Components/BannerListWidget"));
var _config = _interopRequireDefault(require("../config"));
var _api = _interopRequireWildcard(require("../api"));
var _PrefsFormWidget = _interopRequireDefault(require("./Components/PrefsFormWidget"));
var _prefs = require("../prefs");
var _Template = require("../Template");
var _TopBarWidget = _interopRequireDefault(require("./Components/TopBarWidget"));
var _util = require("../util");
var cache = _interopRequireWildcard(require("../cache"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
// <nowiki>
function MainWindow(config) {
MainWindow["super"].call(this, config);
}
OO.inheritClass(MainWindow, OO.ui.ProcessDialog);
MainWindow["static"].name = "main";
MainWindow["static"].title = $("<span>").css({
"font-weight": "normal"
}).append($("<a>").css({
"font-weight": "bold"
}).attr({
"href": mw.util.getUrl("WP:RATER"),
"target": "_blank"
}).text("Rater"), " (", $("<a>").attr({
"href": mw.util.getUrl("WT:RATER"),
"target": "_blank"
}).text("talk"), ") ", $("<span>").css({
"font-size": "90%"
}).text("v" + _config["default"].script.version));
MainWindow["static"].size = "large";
MainWindow["static"].actions = [
// Primary (top right):
{
label: "X",
// not using an icon since color becomes inverted, i.e. white on light-grey
title: "Close (and discard any changes)",
flags: "primary",
modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs"
},
// Safe (top left)
{
action: "showPrefs",
flags: "safe",
icon: "settings",
title: "Preferences",
modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs"
},
// Others (bottom)
{
action: "save",
accessKey: "s",
label: new OO.ui.HtmlSnippet("<span style='padding:0 1em;'>Save</span>"),
flags: ["primary", "progressive"],
modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs"
}, {
action: "preview",
accessKey: "p",
label: "Show preview",
modes: ["edit", "diff"] // available when current mode isn't "preview" or "prefs"
}, {
action: "changes",
accessKey: "v",
label: "Show changes",
modes: ["edit", "preview"] // available when current mode isn't "diff" or "prefs"
}, {
action: "back",
label: "Back",
modes: ["diff", "preview"] // available when current mode is "diff" or "prefs"
},
// "prefs" mode only
{
action: "savePrefs",
label: "Update",
flags: ["primary", "progressive"],
modes: "prefs"
}, {
action: "closePrefs",
label: "Cancel",
flags: "safe",
modes: "prefs"
}];
// Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.
MainWindow.prototype.initialize = function () {
// Call the parent method.
MainWindow["super"].prototype.initialize.call(this);
/* --- PREFS --- */
this.preferences = _config["default"].defaultPrefs;
/* --- TOP BAR --- */
this.topBar = new _TopBarWidget["default"]({
$overlay: this.$overlay
});
this.$head.css({
"height": "73px"
}).append(this.topBar.$element);
/* --- FOOTER --- */
this.oresLabel = new OO.ui.LabelWidget({
$element: $("<span style='float:right; padding: 10px; max-width: 50%; text-align: center;'>"),
label: $("<span>").append($("<a>").attr({
"href": mw.util.getUrl("mw:ORES"),
"target": "_blank"
}).append($("<img>").css({
"vertical-align": "text-bottom;"
}).attr({
"src": "//upload.wikimedia.org/wikipedia/commons/thumb/5/51/Objective_Revision_Evaluation_Service_logo.svg/40px-Objective_Revision_Evaluation_Service_logo.svg.png",
"title": "Machine predicted quality from ORES",
"alt": "ORES logo",
"width": "20px",
"height": "20px"
})), " ", $("<span class='oresPrediction'>"))
}).toggle(false);
this.pagetypeLabel = new OO.ui.LabelWidget({
$element: $("<span style='float:right; padding: 10px; max-width: 33.33%; text-align: center;'>")
}).toggle(false);
this.$foot.prepend(this.oresLabel.$element, this.pagetypeLabel.$element);
/* --- CONTENT AREA --- */
// Banners added dynamically upon opening, so just need a layout with an empty list
this.bannerList = new _BannerListWidget["default"]({
preferences: this.preferences
});
this.editLayout = new OO.ui.PanelLayout({
padded: false,
expanded: false,
$content: this.bannerList.$element
});
// Preferences, filled in with current prefs upon loading.
// TODO: Make this into a component, add fields and inputs
this.prefsForm = new _PrefsFormWidget["default"]();
this.prefsLayout = new OO.ui.PanelLayout({
padded: true,
expanded: false,
$content: this.prefsForm.$element
});
// Preview, Show changes
this.parsedContentContainer = new OO.ui.FieldsetLayout({
label: "Preview"
});
this.parsedContentWidget = new OO.ui.LabelWidget({
label: "",
$element: $("<div>")
});
this.parsedContentContainer.addItems([new OO.ui.FieldLayout(this.parsedContentWidget, {
align: "top"
})]);
this.parsedContentLayout = new OO.ui.PanelLayout({
padded: true,
expanded: false,
$content: this.parsedContentContainer.$element
});
this.contentArea = new OO.ui.StackLayout({
items: [this.editLayout, this.prefsLayout, this.parsedContentLayout],
padded: false,
expanded: false
});
this.$body.css({
"top": "73px"
}).append(this.contentArea.$element);
/* --- EVENT HANDLING --- */
this.topBar.connect(this, {
"searchSelect": "onSearchSelect",
"setClasses": "onSetClasses",
"setImportances": "onSetImportances",
"removeAll": "onRemoveAll",
"clearAll": "onClearAll"
});
this.bannerList.connect(this, {
"updatedSize": "onBannerListUpdateSize"
});
// Handle certain keyboard events. Requires something in the Rater window to be focused,
// so add a tabindex to the body and it's parent container.
this.$body.attr("tabindex", "999").parent().attr("tabindex", "999").keydown(function (event) {
var scrollAmount;
switch (event.which) {
case 33:
// page up
scrollAmount = this.$body.scrollTop() - this.$body.height() * 0.9;
break;
case 34:
// page down
scrollAmount = this.$body.scrollTop() + this.$body.height() * 0.9;
break;
default:
return;
}
this.$body.scrollTop(scrollAmount);
event.preventDefault();
}.bind(this));
this.prefsForm.connect(this, {
"resetCache": "onResetCache"
});
};
MainWindow.prototype.onBannerListUpdateSize = function () {
// Get the current scroll amount
var scrollAmount = this.$body.scrollTop();
// Update size (which resets the scroll to 0)
this.updateSize();
// Scroll to where it was before
this.$body.scrollTop(scrollAmount);
};
MainWindow.prototype.makeDraggable = function () {
var $frameEl = this.$element.find(".oo-ui-window-frame");
var $handleEl = this.$element.find(".oo-ui-processDialog-location").css({
"cursor": "move"
});
// Position for css translate transformations, relative to initial position
// (which is centered on viewport when scrolled to top)
var position = {
x: 0,
y: 0
};
var constrain = function constrain(val, minVal, maxVal) {
if (val < minVal) return minVal;
if (val > maxVal) return maxVal;
return val;
};
var constrainX = function constrainX(val) {
// Don't too far horizontally (leave at least 100px visible)
var limit = window.innerWidth / 2 + $frameEl.outerWidth() / 2 - 100;
return constrain(val, -1 * limit, limit);
};
var constrainY = function constrainY(val) {
// Can't take title bar off the viewport, since it's the drag handle
var minLimit = -1 * (window.innerHeight - $frameEl.outerHeight()) / 2;
// Don't go too far down the page: (whole page height) - (initial position)
var maxLimit = (document.documentElement || document).scrollHeight - window.innerHeight / 2;
return constrain(val, minLimit, maxLimit);
};
var pointerdown = false;
var dragFrom = {};
var onDragStart = function onDragStart(event) {
pointerdown = true;
dragFrom.x = event.clientX;
dragFrom.y = event.clientY;
};
var onDragMove = function onDragMove(event) {
if (!pointerdown || dragFrom.x == null || dragFrom.y === null) {
return;
}
var dx = event.clientX - dragFrom.x;
var dy = event.clientY - dragFrom.y;
dragFrom.x = event.clientX;
dragFrom.y = event.clientY;
position.x = constrainX(position.x + dx);
position.y = constrainY(position.y + dy);
$frameEl.css("transform", "translate(".concat(position.x, "px, ").concat(position.y, "px)"));
};
var onDragEnd = function onDragEnd() {
pointerdown = false;
delete dragFrom.x;
delete dragFrom.y;
// Make sure final positions are whole numbers
position.x = Math.round(position.x);
position.y = Math.round(position.y);
$frameEl.css("transform", "translate(".concat(position.x, "px, ").concat(position.y, "px)"));
};
// Use pointer events if available; otherwise use mouse events
var pointer = "PointerEvent" in window ? "pointer" : "mouse";
$handleEl.on(pointer + "enter.raterMainWin", function () {
return $frameEl.css("will-change", "transform");
}); // Tell browser to optimise transform
$handleEl.on(pointer + "leave.raterMainWin", function () {
if (!pointerdown) $frameEl.css("will-change", "");
}); // Remove optimisation if not dragging
$handleEl.on(pointer + "down.raterMainWin", onDragStart);
$("body").on(pointer + "move.raterMainWin", onDragMove);
$("body").on(pointer + "up.raterMainWin", onDragEnd);
};
// Override the getBodyHeight() method to specify a custom height
MainWindow.prototype.getBodyHeight = function () {
var currentlayout = this.contentArea.getCurrentItem();
var layoutHeight = currentlayout && currentlayout.$element.outerHeight(true);
var contentHeight = currentlayout && currentlayout.$element.children(":first-child").outerHeight(true);
return Math.max(200, layoutHeight, contentHeight);
};
// Use getSetupProcess() to set up the window with data passed to it at the time
// of opening
MainWindow.prototype.getSetupProcess = function (data) {
var _this = this;
data = data || {};
return MainWindow["super"].prototype.getSetupProcess.call(this, data).next(function () {
_this.makeDraggable();
// Set up preferences
_this.setPreferences(data.preferences);
_this.prefsForm.setPrefValues(data.preferences);
// Set subject page info
_this.subjectPage = data.subjectPage;
_this.pageInfo = {
redirect: data.redirectTarget,
isDisambig: data.disambig,
hasStubtag: data.stubtag,
isArticle: data.isArticle
};
// Set up edit mode banners
_this.actions.setMode("edit");
_this.bannerList.oresClass = data.isArticle && data.isList ? "List" : data.ores && data.ores.prediction;
_this.bannerList.pageInfo = _this.pageInfo;
_this.bannerList.addItems(data.banners.map(function (bannerTemplate) {
return new _BannerWidget["default"](bannerTemplate, {
preferences: _this.preferences,
$overlay: _this.$overlay,
isArticle: _this.pageInfo.isArticle
});
}));
var shellTemplateBanner = _this.bannerList.items.find(function (banner) {
return banner.isShellTemplate;
});
if (shellTemplateBanner && shellTemplateBanner.shellParam1Value) {
shellTemplateBanner.nonStandardTemplates = _this.bannerList.items.reduce(function (bannersList, curBanner) {
return bannersList.replace(curBanner.wikitext, "");
}, shellTemplateBanner.shellParam1Value).trim().replace(/\n+/g, "\n");
}
_this.bannerList.addShellTemplateIfNeeeded().syncShellTemplateWithBiographyBanner();
// Show page type, or ORES prediction, if available
if (_this.pageInfo.redirect) {
_this.pagetypeLabel.setLabel("Redirect page").toggle(true);
} else if (_this.pageInfo.isDisambig) {
_this.pagetypeLabel.setLabel("Disambiguation page").toggle(true);
} else if (_this.pageInfo.isArticle && data.isGA) {
_this.pagetypeLabel.setLabel("Good article").toggle(true);
} else if (_this.pageInfo.isArticle && data.isFA) {
_this.pagetypeLabel.setLabel("Featured article").toggle(true);
} else if (_this.pageInfo.isArticle && data.isFL) {
_this.pagetypeLabel.setLabel("Featured list").toggle(true);
} else if (_this.pageInfo.isArticle && data.isList) {
_this.pagetypeLabel.setLabel("List article").toggle(true);
} else if (data.ores) {
_this.oresClass = data.ores.prediction;
_this.oresLabel.toggle(true).$element.find(".oresPrediction").append("Prediction: ", $("<strong>").text(data.ores.prediction), " (" + data.ores.probability + ")");
} else if (_this.pageInfo.isArticle) {
_this.pagetypeLabel.setLabel("Article page").toggle(true);
} else {
_this.pagetypeLabel.setLabel(_this.subjectPage.getNamespacePrefix().slice(0, -1) + " page").toggle(true);
}
// Set props for use in making wikitext and edit summaries
_this.talkWikitext = data.talkWikitext;
_this.existingBannerNames = data.banners.map(function (bannerTemplate) {
return bannerTemplate.name;
});
_this.talkpage = data.talkpage;
// Force a size update to ensure eveything fits okay
_this.updateSize();
}, this);
};
// Set up the window it is ready: attached to the DOM, and opening animation completed
MainWindow.prototype.getReadyProcess = function (data) {
var _this2 = this;
data = data || {};
return MainWindow["super"].prototype.getReadyProcess.call(this, data).next(function () {
return _this2.topBar.searchBox.focus();
});
};
// Use the getActionProcess() method to do things when actions are clicked
MainWindow.prototype.getActionProcess = function (action) {
var _this3 = this;
if (action === "showPrefs") {
this.actions.setMode("prefs");
this.contentArea.setItem(this.prefsLayout);
this.topBar.setDisabled(true);
this.updateSize();
} else if (action === "savePrefs") {
var updatedPrefs = this.prefsForm.getPrefs();
return new OO.ui.Process().next((0, _prefs.setPrefs)(updatedPrefs).then(
// Success
function () {
_this3.setPreferences(updatedPrefs);
_this3.actions.setMode("edit");
_this3.contentArea.setItem(_this3.editLayout);
_this3.topBar.setDisabled(false);
_this3.updateSize();
},
// Failure
function (code, err) {
return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("Could not save preferences."), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err)))));
}));
} else if (action === "clearCache") {
return new OO.ui.Process().next(function () {
cache.clearAllItems();
_this3.close({
restart: true
});
});
} else if (action === "closePrefs") {
this.actions.setMode("edit");
this.contentArea.setItem(this.editLayout);
this.topBar.setDisabled(false);
this.prefsForm.setPrefValues(this.preferences);
this.updateSize();
} else if (action === "save") {
return new OO.ui.Process().next(_api["default"].editWithRetry(this.talkpage.getPrefixedText(), {
rvsection: 0
}, function (revision) {
return {
section: 0,
text: _this3.transformTalkWikitext(revision.content),
summary: _this3.makeEditSummary(),
watchlist: _this3.preferences.watchlist
};
})["catch"](function (code, err) {
return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("Could not save your changes."), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err)))));
})).next(function () {
return _this3.close({
success: true,
upgradedStub: _this3.pageInfo.hasStubtag && _this3.isRatedAndNotStub()
});
});
} else if (action === "preview") {
return new OO.ui.Process().next(_api["default"].post({
action: "parse",
contentmodel: "wikitext",
text: this.transformTalkWikitext(this.talkWikitext) + "\n<hr>\n" + "'''Edit summary:''' " + this.makeEditSummary(),
title: this.talkpage.getPrefixedText(),
pst: 1
}).then(function (result) {
if (!result || !result.parse || !result.parse.text || !result.parse.text["*"]) {
return $.Deferred().reject("Empty result");
}
var previewHtmlSnippet = new OO.ui.HtmlSnippet(result.parse.text["*"]);
_this3.parsedContentWidget.setLabel(previewHtmlSnippet);
_this3.parsedContentContainer.setLabel("Preview:");
_this3.actions.setMode("preview");
_this3.contentArea.setItem(_this3.parsedContentLayout);
_this3.topBar.setDisabled(true);
_this3.updateSize();
})["catch"](function (code, err) {
return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("Could not show changes."), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err)))));
}));
} else if (action === "changes") {
return new OO.ui.Process().next(_api["default"].post({
action: "compare",
format: "json",
fromtext: this.talkWikitext,
fromcontentmodel: "wikitext",
totext: this.transformTalkWikitext(this.talkWikitext),
tocontentmodel: "wikitext",
prop: "diff"
}).then(function (result) {
if (!result || !result.compare || !result.compare["*"]) {
return $.Deferred().reject("Empty result");
}
var $diff = $("<table>").addClass("diff").css("width", "100%").append($("<tr>").append($("<th>").attr({
"colspan": "2",
"scope": "col"
}).css("width", "50%").text("Latest revision"), $("<th>").attr({
"colspan": "2",
"scope": "col"
}).css("width", "50%").text("New text")), result.compare["*"], $("<tfoot>").append($("<tr>").append($("<td colspan='4'>").append($("<strong>").text("Edit summary: "), _this3.makeEditSummary()))));
_this3.parsedContentWidget.setLabel($diff);
_this3.parsedContentContainer.setLabel("Changes:");
_this3.actions.setMode("diff");
_this3.contentArea.setItem(_this3.parsedContentLayout);
_this3.topBar.setDisabled(true);
_this3.updateSize();
})["catch"](function (code, err) {
return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("Could not show changes."), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err)))));
}));
} else if (action === "back") {
this.actions.setMode("edit");
this.contentArea.setItem(this.editLayout);
this.topBar.setDisabled(false);
this.updateSize();
} else if (!action && this.bannerList.changed) {
// Confirm closing of dialog if there have been changes
return new OO.ui.Process().next(OO.ui.confirm("Changes made will be discarded.", {
title: "Close Rater?"
}).then(function (confirmed) {
return confirmed ? _this3.close() : null;
}));
}
return MainWindow["super"].prototype.getActionProcess.call(this, action);
};
// Use the getTeardownProcess() method to perform actions whenever the dialog is closed.
// `data` is the data passed into the window's .close() method.
MainWindow.prototype.getTeardownProcess = function (data) {
var _this4 = this;
return MainWindow["super"].prototype.getTeardownProcess.call(this, data).first(function () {
_this4.bannerList.clearItems();
_this4.topBar.searchBox.setValue("");
_this4.contentArea.setItem(_this4.editLayout);
_this4.topBar.setDisabled(false);
_this4.oresLabel.toggle(false).$element.find(".oresPrediction").empty();
_this4.pagetypeLabel.toggle(false).setLabel("");
_this4.$element.find(".oo-ui-window-frame").css("transform", "");
_this4.$element.find(".oo-ui-processDialog-location").off(".raterMainWin");
$("body").off(".raterMainWin");
});
};
MainWindow.prototype.setPreferences = function (prefs) {
this.preferences = $.extend({}, _config["default"].defaultPrefs, prefs);
// Applies preferences to existing items in the window:
this.bannerList.setPreferences(this.preferences);
};
MainWindow.prototype.onResetCache = function () {
this.executeAction("clearCache");
};
MainWindow.prototype.onSearchSelect = function (data) {
var _this5 = this;
this.topBar.searchBox.pushPending();
var name = this.topBar.searchBox.getValue().trim();
if (!name) {
this.topBar.searchBox.popPending().focus();
return;
}
var existingBanner = this.bannerList.items.find(function (banner) {
return banner.mainText === name || banner.redirectTargetMainText === name;
});
// Abort and show alert if banner already exists
if (existingBanner) {
this.topBar.searchBox.popPending();
return OO.ui.alert("There is already a {{" + name + "}} banner").then(this.searchBox.focus());
}
// Confirmation required for banners missing WikiProject from name, and for uncreated disambiguation talk pages
var confirmText;
if (!/^[Ww](?:P|iki[Pp]roject)/.test(name)) {
confirmText = new OO.ui.HtmlSnippet("{{" + mw.html.escape(name) + "}} is not a recognised WikiProject banner.<br/>Do you want to continue?");
} else if (name === "WikiProject Disambiguation" && $("#ca-talk.new").length !== 0 && this.bannerList.items.length === 0) {
// eslint-disable-next-line no-useless-escape
confirmText = "New talk pages shouldn't be created if they will only contain the \{\{WikiProject Disambiguation\}\} banner. Continue?";
}
$.when(confirmText ? OO.ui.confirm(confirmText) : true).then(function (confirmed) {
if (!confirmed) return;
// Create Template object
return _BannerWidget["default"].newFromTemplateName(name, data, {
preferences: _this5.preferences,
$overlay: _this5.$overlay,
isArticle: _this5.pageInfo.isArticle
}).then(function (banner) {
_this5.bannerList.addItems([banner]);
banner.setChanged();
_this5.updateSize();
});
}).then(function () {
return _this5.topBar.searchBox.setValue("").focus().popPending();
});
};
MainWindow.prototype.onSetClasses = function (classVal) {
var shellTemplate = this.bannerList.items.find(function (banner) {
return banner.isShellTemplate;
});
if (shellTemplate) {
shellTemplate.classDropdown.getMenu().selectItemByData(classVal);
shellTemplate.classDropdown.setAutofilled(false);
}
this.bannerList.items.forEach(function (banner) {
if (banner.hasClassRatings && !banner.isShellTemplate) {
banner.classDropdown.getMenu().selectItemByData(shellTemplate ? null : classVal);
banner.classDropdown.setAutofilled(false);
}
});
};
MainWindow.prototype.onSetImportances = function (importanceVal) {
this.bannerList.items.forEach(function (banner) {
if (banner.hasImportanceRatings) {
banner.importanceDropdown.getMenu().selectItemByData(importanceVal);
banner.importanceDropdown.setAutofilled(false);
}
});
};
MainWindow.prototype.onRemoveAll = function () {
this.bannerList.clearItems();
};
MainWindow.prototype.onClearAll = function () {
this.bannerList.items.forEach(function (banner) {
return banner.onClearButtonClick();
});
};
MainWindow.prototype.transformTalkWikitext = function (talkWikitext) {
var _this6 = this;
var bannersWikitext = this.bannerList.makeWikitext();
if (!talkWikitext) {
return bannersWikitext.trim();
}
// Reparse templates, in case talkpage wikitext has changed
var talkTemplates = (0, _Template.parseTemplates)(talkWikitext, true);
// replace existing banners wikitext with a control character
talkTemplates.forEach(function (template) {
if (_this6.existingBannerNames.includes(template.name)) {
talkWikitext = talkWikitext.replace(template.wikitext, "\x01");
}
});
// replace insertion point (first control character) with a different control character
talkWikitext = talkWikitext.replace("\x01", "\x02");
// remove other control characters
/* eslint-disable-next-line no-control-regex */
talkWikitext = talkWikitext.replace(/(?:\s|\n)*\x01(?:\s|\n)*/g, "");
// split into wikitext before/after the remaining control character (and trim each section)
var talkWikitextSections = talkWikitext.split("\x02").map(function (t) {
return t.trim();
});
if (talkWikitextSections.length === 2) {
// Found the insertion point for the banners
return (talkWikitextSections[0] + "\n" + bannersWikitext.trim() + "\n" + talkWikitextSections[1]).trim();
}
// Check if there's anything beside templates
var tempStr = talkWikitext;
talkTemplates.forEach(function (template) {
tempStr = tempStr.replace(template.wikitext, "");
});
if (/^#REDIRECT/i.test(talkWikitext) || !tempStr.trim()) {
// Is a redirect, or everything is a template: insert at the end
return talkWikitext.trim() + "\n" + bannersWikitext.trim();
} else {
// There is non-template content, so insert at the start
return bannersWikitext.trim() + "\n" + talkWikitext.trim();
}
};
MainWindow.prototype.isRatedAndNotStub = function () {
var nonStubRatinggs = this.bannerList.items.filter(function (banner) {
return banner.hasClassRatings && banner.classDropdown.getValue() && banner.classDropdown.getValue() !== "Stub";
});
return nonStubRatinggs.length > 0;
};
MainWindow.prototype.makeEditSummary = function () {
var _this7 = this;
var removedBanners = [];
var editedBanners = [];
var newBanners = [];
var shortName = function shortName(name) {
return name.replace("WikiProject ", "").replace("Subst:", "");
};
// Overall class/importance, if all the same
var allClasses = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.bannerList.items, function (banner) {
return banner.hasClassRatings || banner.isShellTemplate;
}, function (banner) {
return banner.classDropdown.getValue();
}));
var overallClass = allClasses.length === 1 && allClasses[0];
var allImportances = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.bannerList.items, function (banner) {
return banner.hasImportanceRatings;
}, function (banner) {
return banner.importanceDropdown.getValue();
}));
var overallImportance = allImportances.length === 1 && allImportances[0];
// Don't use them unless some have changed
var someClassesChanged = false;
var someImportancesChanged = false;
// removed banners:
this.existingBannerNames.forEach(function (name) {
var banner = _this7.bannerList.items.find(function (banner) {
return banner.name === name || banner.bypassedName === name;
});
if (!banner) {
removedBanners.push("−" + shortName(name));
}
});
// edited & new banners
this.bannerList.items.forEach(function (banner) {
var isNew = !banner.wikitext; // not added from wikitext on page
if (!isNew && !banner.changed) {
// Not changed
return;
}
var newClass = banner.hasClassRatings && (isNew || banner.classChanged) && banner.classDropdown.getValue();
if (newClass) {
someClassesChanged = true;
}
if (overallClass) {
newClass = null;
}
var newImportance = banner.hasImportanceRatings && (isNew || banner.importanceChanged) && banner.importanceDropdown.getValue();
if (newImportance) {
someImportancesChanged = true;
}
if (overallImportance) {
newImportance = null;
}
var rating = newClass && newImportance ? newClass + "/" + newImportance : newClass || newImportance || "";
if (rating) {
rating = " (" + rating + ")";
}
if (isNew) {
newBanners.push("+" + shortName(banner.name) + rating);
} else {
editedBanners.push(shortName(banner.name) + rating);
}
});
// overall rating
var overallRating = someClassesChanged && overallClass && someImportancesChanged && overallImportance ? overallClass + "/" + overallImportance : someClassesChanged && overallClass || someImportancesChanged && overallImportance || "";
if (overallRating) {
overallRating = " (" + overallRating + ")";
}
return "Assessment".concat(overallRating, ": ").concat([].concat(editedBanners, newBanners, removedBanners).join(", ")).concat(_config["default"].script.advert);
};
var _default = exports["default"] = MainWindow; // </nowiki>
},{"../Template":3,"../api":15,"../cache":17,"../config":18,"../prefs":21,"../util":23,"./Components/BannerListWidget":4,"./Components/BannerWidget":5,"./Components/PrefsFormWidget":10,"./Components/TopBarWidget":12}],15:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.makeErrorMsg = exports["default"] = void 0;
var _config = _interopRequireDefault(require("./config"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
// <nowiki>
var API = new mw.Api({
ajax: {
headers: {
"Api-User-Agent": "Rater/" + _config["default"].script.version + " ( https://en.wikipedia.org/wiki/User:Evad37/Rater )"
}
}
});
/* ---------- API for ORES ---------------------------------------------------------------------- */
API.getORES = function (revisionID) {
return $.get("https://ores.wikimedia.org/v3/scores/enwiki?models=articlequality&revids=" + revisionID);
};
/* ---------- Raw wikitext ---------------------------------------------------------------------- */
API.getRaw = function (page) {
return $.get("https:" + _config["default"].mw.wgServer + mw.util.getUrl(page, {
action: "raw"
})).then(function (data) {
if (!data) {
return $.Deferred().reject("ok-but-empty");
}
return data;
});
};
/* ---------- Edit with retry ------------------------------------------------------------------- */
/**
* @param {String} title
* @param {Object?} params additional params for the get request
* @returns {Promise<Object, string>} page, starttime timestamp
*/
var getPage = function getPage(title, params) {
return API.get($.extend({
"action": "query",
"format": "json",
"curtimestamp": 1,
"titles": title,
"prop": "revisions|info",
"rvprop": "content|timestamp",
"rvslots": "main"
}, params)).then(function (response) {
var page = Object.values(response.query.pages)[0];
var starttime = response.curtimestamp;
return $.Deferred().resolve(page, starttime);
});
};
/**
* @param {Object} page details object from API
* @param {string} starttime timestamp
* @param {Function} transform callback that prepares the edit:
* {Object} simplifiedPage => {Object|Promise<Object>} edit params
* @returns {Promise<Object>} params for edit query
*/
var processPage = function processPage(page, starttime, transform) {
var basetimestamp = page.revisions && page.revisions[0].timestamp;
var simplifiedPage = {
pageid: page.pageid,
missing: page.missing === "",
redirect: page.redirect === "",
categories: page.categories,
ns: page.ns,
title: page.title,
content: page.revisions && page.revisions[0].slots.main["*"]
};
return $.when(transform(simplifiedPage)).then(function (editParams) {
return $.extend({
action: "edit",
title: page.title,
// Protect against errors and conflicts
assert: "user",
basetimestamp: basetimestamp,
starttimestamp: starttime
}, editParams);
});
};
/** editWithRetry
*
* Edits a page, resolving edit conflicts, and retrying edits that fail. The
* tranform function may return a rejected promise if the page should not be
* edited; the @returns {Promise} will will be rejected with the same rejection
* values.
*
* Note: Unlike [mw.Api#Edit], a missing page will be created, unless the
* transform callback includes the "nocreate" param.
*
* [mw.Api#Edit]: <https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.edit>
*
* @param {String} title page to be edited
* @param {Object|null} getParams additional params for the get request
* @param {Function} transform callback that prepares the edit:
* {Object} simplifiedPage => {Object|Promise<Object>} params for API editing
* @returns {Promise<object>} promise, resolved on success, rejected if
* page was not edited
*/
API.editWithRetry = function (title, getParams, transform) {
return getPage(title, getParams).then(
// Succes: process the page
function (page, starttime) {
return processPage(page, starttime, transform);
},
// Failure: try again
function () {
return getPage(title, getParams).then(processPage, transform);
}).then(function (editParams) {
return API.postWithToken("csrf", editParams)["catch"](function (errorCode) {
if (errorCode === "editconflict") {
// Try again, starting over
return API.editWithRetry(title, getParams, transform);
}
// Try again
return API.postWithToken("csrf", editParams);
});
});
};
var makeErrorMsg = exports.makeErrorMsg = function makeErrorMsg(first, second) {
var code, xhr, message;
if (_typeof(first) === "object" && typeof second === "string") {
// Errors from $.get being rejected (ORES & Raw wikitext)
var errorObj = first.responseJSON && first.responseJSON.error;
if (errorObj) {
// Got an api-specific error code/message
code = errorObj.code;
message = errorObj.message;
} else {
xhr = first;
}
} else if (typeof first === "string" && _typeof(second) === "object") {
// Errors from mw.Api object
var mwErrorObj = second.error;
if (mwErrorObj) {
// Got an api-specific error code/message
code = errorObj.code;
message = errorObj.info;
} else if (first === "ok-but-empty") {
code = null;
message = "Got an empty response from the server";
} else {
xhr = second && second.xhr;
}
}
if (code && message) {
return "API error ".concat(code, ": ").concat(message);
} else if (message) {
return "API error: ".concat(message);
} else if (xhr) {
return "HTTP error ".concat(xhr.status);
} else if (typeof first === "string" && first !== "error" && typeof second === "string" && second !== "error") {
return "Error ".concat(first, ": ").concat(second);
} else if (typeof first === "string" && first !== "error") {
return "Error: ".concat(first);
} else {
return "Unknown API error";
}
};
var _default = exports["default"] = API; // </nowiki>
},{"./config":18}],16:[function(require,module,exports){
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("./config"));
var _prefs = require("./prefs");
var _api = _interopRequireWildcard(require("./api"));
var _setup = _interopRequireDefault(require("./setup"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
// <nowiki>
var autoStart = function autoStart() {
return (0, _prefs.getPrefs)().then(function (prefs) {
// Check if pref is turned off
if (!prefs.autostart) {
return;
}
// Check if pref is turned off for redirects, and current page is a redirect
if (!prefs.autostartRedirects && window.location.search.includes("redirect=no")) {
return;
}
// Check if viewing diff/history/old version
if (/(action|diff|oldid)/.test(window.location.search)) {
return;
}
var subjectTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getSubjectPage();
// Check if subject page is the main page
if (subjectTitle.getPrefixedText() === "Main Page") {
return;
}
// Check subject page namespace
if (prefs.autostartNamespaces && prefs.autostartNamespaces.length && !prefs.autostartNamespaces.includes(_config["default"].mw.wgNamespaceNumber)) {
return;
}
// If talk page does not exist, can just autostart
if ($("#ca-talk.new").length) {
return (0, _setup["default"])();
}
/* Check templates present on talk page. Fetches indirectly transcluded templates, so will find
Template:WPBannerMeta (and its subtemplates). But some banners such as MILHIST don't use that
meta template, so we also have to check for template titles containg 'WikiProject'
*/
var talkTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getTalkPage();
return _api["default"].get({
action: "query",
format: "json",
prop: "templates",
titles: talkTitle.getPrefixedText(),
tlnamespace: "10",
tllimit: "500",
indexpageids: 1
}).then(function (result) {
var id = result.query.pageids;
var templates = result.query.pages[id].templates;
if (!templates) {
return (0, _setup["default"])();
}
var hasWikiproject = templates.some(function (template) {
return /(WikiProject|WPBanner)/.test(template.title);
});
if (!hasWikiproject) {
return (0, _setup["default"])();
}
}, function (code, jqxhr) {
// Silently ignore failures (just log to console)
console.warn("[Rater] Error while checking whether to autostart." + (code == null) ? "" : " " + (0, _api.makeErrorMsg)(code, jqxhr));
return $.Deferred().reject();
});
});
};
var _default = exports["default"] = autoStart; // </nowiki>
},{"./api":15,"./config":18,"./prefs":21,"./setup":22}],17:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.write = exports.read = exports.clearItemIfInvalid = exports.clearInvalidItems = exports.clearAllItems = void 0;
var _util = require("./util");
// <nowiki>
/** write
* @param {String} key
* @param {Array|Object} val
* @param {Number} staleDays Number of days after which the data becomes stale (usable, but should
* be updated for next time).
* @param {Number} expiryDays Number of days after which the cached data may be deleted.
*/
var write = exports.write = function write(key, val, staleDays, expiryDays) {
try {
var defaultStaleDays = 1;
var defaultExpiryDays = 30;
var millisecondsPerDay = 24 * 60 * 60 * 1000;
var staleDuration = (staleDays || defaultStaleDays) * millisecondsPerDay;
var expiryDuration = (expiryDays || defaultExpiryDays) * millisecondsPerDay;
var stringVal = JSON.stringify({
value: val,
staleDate: new Date(Date.now() + staleDuration).toISOString(),
expiryDate: new Date(Date.now() + expiryDuration).toISOString()
});
localStorage.setItem("Rater-" + key, stringVal);
} catch (e) {} // eslint-disable-line no-empty
};
/** read
* @param {String} key
* @returns {Array|Object|String|Null} Cached array or object, or empty string if not yet cached,
* or null if there was error.
*/
var read = exports.read = function read(key) {
var val;
try {
var stringVal = localStorage.getItem("Rater-" + key);
if (stringVal !== "") {
val = JSON.parse(stringVal);
}
} catch (e) {
console.log("[Rater] error reading " + key + " from localStorage cache:");
console.log("\t" + e.name + " message: " + e.message + (e.at ? " at: " + e.at : "") + (e.text ? " text: " + e.text : ""));
}
return val || null;
};
var isRaterKey = function isRaterKey(key) {
return key && key.indexOf("Rater-") === 0;
};
var clearItemIfInvalid = exports.clearItemIfInvalid = function clearItemIfInvalid(key) {
if (!isRaterKey(key)) {
return;
}
var item = read(key.replace("Rater-", ""));
var isInvalid = !item || !item.expiryDate || (0, _util.isAfterDate)(item.expiryDate);
if (isInvalid) {
localStorage.removeItem(key);
}
};
var clearInvalidItems = exports.clearInvalidItems = function clearInvalidItems() {
// Loop backwards as localStorage length will decrease as items are removed
for (var i = localStorage.length; i >= 0; i--) {
setTimeout(clearItemIfInvalid, 100, localStorage.key(i));
}
};
var clearAllItems = exports.clearAllItems = function clearAllItems() {
// Loop backwards as localStorage length will decrease as items are removed
for (var i = localStorage.length; i >= 0; i--) {
var key = localStorage.key(i);
if (isRaterKey(key)) {
localStorage.removeItem(key);
}
}
};
// </nowiki>
},{"./util":23}],18:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
var packagejson = require("../package.json");
var version = packagejson.version;
// A global object that stores all the page and user configuration and settings
var config = {
// Script info
script: {
// Advert to append to edit summaries
advert: " ([[WP:RATER#".concat(version, "|Rater]])"),
version: version
},
// Default preferences, if user subpage raterPrefs.json does not exist
defaultPrefs: {
"autostart": false,
"autostartRedirects": false,
"autostartNamespaces": [0],
"minForShell": 1,
"bypassRedirects": true,
"autofillClassFromOthers": true,
"autofillClassFromOres": true,
"autofillImportance": true,
"collapseParamsLowerLimit": 6,
"watchlist": "preferences"
},
// MediaWiki configuration values
mw: mw.config.get(["skin", "wgPageName", "wgNamespaceNumber", "wgUserName", "wgFormattedNamespaces", "wgMonthNames", "wgRevisionId", "wgScriptPath", "wgServer", "wgCategories", "wgIsMainPage"]),
bannerDefaults: {
classes: ["FA", "FL", "A", "GA", "B", "C", "Start", "Stub", "List"],
importances: ["Top", "High", "Mid", "Low"],
extendedClasses: ["Category", "Draft", "File", "FM", "Portal", "Project", "Template", "Bplus", "Future", "Current", "Disambig", "NA", "Redirect", "Book"],
extendedImportances: ["Top", "High", "Mid", "Low", "Bottom", "NA"]
},
customBanners: {
"WikiProject Military history": {
classes: ["FA", "FL", "A", "GA", "B", "C", "Start", "Stub", "List", "AL", "BL", "CL", "Category", "Draft", "File", "Portal", "Project", "Template", "Disambig", "Redirect", "Book"],
importances: []
},
"WikiProject Portals": {
classes: ["FPo", "Complete", "Substantial", "Basic", "Incomplete", "Meta", "List", "Category", "Draft", "File", "Project", "Template", "Disambig", "NA", "Redirect"],
importances: ["Top", "High", "Mid", "Low", "Bottom", "NA"]
},
"WikiProject Video games": {
classes: ["FA", "FL", "FM", "GA", "B", "C", "Start", "Stub", "List", "Category", "Draft", "File", "Portal", "Project", "Template", "Disambig", "Redirect"],
importances: ["Top", "High", "Mid", "Low", "NA"]
}
},
shellTemplates: ["WikiProject banner shell", "WikiProjectBanners", "WikiProject Banners", "WPB", "WPBS", "Wikiprojectbannershell", "WikiProject Banner Shell", "Wpb", "WPBannerShell", "Wpbs", "Wikiprojectbanners", "WP Banner Shell", "WP banner shell", "Bannershell", "Wikiproject banner shell", "WikiProject Banners Shell", "WikiProjectBanner Shell", "WikiProjectBannerShell", "WikiProject BannerShell", "WikiprojectBannerShell", "WikiProject banner shell/redirect", "WikiProject Shell", "Banner shell", "Scope shell", "Project shell", "WikiProject banner"],
defaultParameterData: {
"auto": {
"label": {
"en": "Auto-rated"
},
"description": {
"en": "Automatically rated by a bot. Allowed values: ['yes']."
},
"autovalue": "yes"
},
"listas": {
"label": {
"en": "List as"
},
"description": {
"en": "Sortkey for talk page"
}
},
"small": {
"label": {
"en": "Small?"
},
"description": {
"en": "Display a small version. Allowed values: ['yes']."
},
"autovalue": "yes"
},
"attention": {
"label": {
"en": "Attention required?"
},
"description": {
"en": "Immediate attention required. Allowed values: ['yes']."
},
"autovalue": "yes"
},
"needs-image": {
"label": {
"en": "Needs image?"
},
"description": {
"en": "Request that an image or photograph of the subject be added to the article. Allowed values: ['yes']."
},
"aliases": ["needs-photo"],
"autovalue": "yes",
"suggested": true
},
"needs-infobox": {
"label": {
"en": "Needs infobox?"
},
"description": {
"en": "Request that an infobox be added to the article. Allowed values: ['yes']."
},
"aliases": ["needs-photo"],
"autovalue": "yes",
"suggested": true
}
}
};
var _default = exports["default"] = config; // </nowiki>
},{"../package.json":1}],19:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
// Attribution: Diff styles based on <https://en.wikipedia.org/wiki/Wikipedia:AutoWikiBrowser/style.css>
var styles = "table.diff, td.diff-otitle, td.diff-ntitle { table-layout: auto !important;; }\ntd.diff-otitle, td.diff-ntitle { text-align: center; }\ntd.diff-marker { text-align: right; font-weight: bold; font-size: 1.25em; }\ntd.diff-lineno { font-weight: bold; }\ntd.diff-addedline, td.diff-deletedline, td.diff-context { font-size: 88%; vertical-align: top; white-space: -moz-pre-wrap; white-space: pre-wrap; }\ntd.diff-addedline, td.diff-deletedline { border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; }\ntd.diff-addedline { border-color: #a3d3ff; }\ntd.diff-deletedline { border-color: #ffe49c; }\ntd.diff-context { background: #f3f3f3; color: #333333; border-style: solid; border-width: 1px 1px 1px 4px; border-color: #e6e6e6; border-radius: 0.33em; }\n.diffchange { font-weight: bold; text-decoration: none; }\ntable.diff {\n border: none;\n width: 98%; border-spacing: 4px;\n table-layout: fixed; /* Ensures that colums are of equal width */\n}\ntd.diff-addedline .diffchange, td.diff-deletedline .diffchange { border-radius: 0.33em; padding: 0.25em 0; }\ntd.diff-addedline .diffchange {\tbackground: #d8ecff; }\ntd.diff-deletedline .diffchange { background: #feeec8; }\ntable.diff td {\tpadding: 0.33em 0.66em; }\ntable.diff col.diff-marker { width: 2%; }\ntable.diff col.diff-content { width: 48%; }\ntable.diff td div {\n /* Force-wrap very long lines such as URLs or page-widening char strings. */\n word-wrap: break-word;\n /* As fallback (FF<3.5, Opera <10.5), scrollbars will be added for very wide cells\n instead of text overflowing or widening */\n overflow: auto;\n}" + // Override OOUI window manager preventing background scrolling/interaction.
// Scoped to Rater's own window manager (.rater-windowManager), so that other
// OOUI dialogs (e.g. OO.ui.confirm in #mw-teleport-target) keep their default
// fixed positioning and remain visible.
"html body.rater-mainWindow-open {\n\tposition: unset;\n\toverflow: unset;\n}\nhtml body.rater-mainWindow-open .rater-windowManager > .oo-ui-dialog.oo-ui-window-active {\n position: static;\n padding: 0;\n}" + // Increase z-index, to be above skin menus etc; smooth transition for dragging (transform:translate)
// 400 keeps Rater above Timeless sidebar dropdowns (.sidebar-inner, 350) / menus-cover (300) /
// fixed header (200), but below #mw-teleport-target (450) so OO.ui.confirm dialogs stay on top.
"html body.rater-mainWindow-open .rater-windowManager > .oo-ui-dialog.oo-ui-window-active > div {\n z-index: 400;\n transition: all 0.25s ease-out 0s, transform 0s !important\n}\n";
var _default = exports["default"] = styles; // </nowiki>
},{}],20:[function(require,module,exports){
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getBannerNames = void 0;
var _api = _interopRequireWildcard(require("./api"));
var _util = require("./util");
var cache = _interopRequireWildcard(require("./cache"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
// <nowiki>
var cacheBanners = function cacheBanners(banners) {
cache.write("banners", banners, 2, 60);
};
/**
* Gets banners/options from the Api
*
* @returns {Promise} Resolved with: banners object, bannerOptions array
*/
var getListOfBannersFromApi = function getListOfBannersFromApi() {
var finishedPromise = $.Deferred();
var querySkeleton = {
action: "query",
format: "json",
list: "categorymembers",
cmprop: "title",
cmnamespace: "10",
cmlimit: "500"
};
var categories = [{
title: "Category:WikiProject banners with quality assessment",
abbreviation: "withRatings",
banners: [],
processed: $.Deferred()
}, {
title: "Category:WikiProject banners without quality assessment",
abbreviation: "withoutRatings",
banners: [],
processed: $.Deferred()
}, {
title: "Category:WikiProject banner wrapper templates",
abbreviation: "wrappers",
banners: [],
processed: $.Deferred()
}, {
title: "Category:WikiProject banner templates not based on WPBannerMeta",
abbreviation: "notWPBM",
banners: [],
processed: $.Deferred()
}, {
title: "Category:Inactive WikiProject banners",
abbreviation: "inactive",
banners: [],
processed: $.Deferred()
}, {
title: "Category:Wrapper templates for WikiProject Women in Red",
abbreviation: "wir",
banners: [],
processed: $.Deferred()
}];
var processQuery = function processQuery(result, catIndex) {
if (!result.query || !result.query.categorymembers) {
// No results
// TODO: error or warning ********
finishedPromise.reject();
return;
}
// Gather titles into array - excluding "Template:" prefix
var resultTitles = result.query.categorymembers.map(function (info) {
return info.title.slice(9);
});
Array.prototype.push.apply(categories[catIndex].banners, resultTitles);
// Continue query if needed
if (result["continue"]) {
doApiQuery($.extend(categories[catIndex].query, result["continue"]), catIndex);
return;
}
categories[catIndex].processed.resolve();
};
var doApiQuery = function doApiQuery(q, catIndex) {
_api["default"].get(q).done(function (result) {
processQuery(result, catIndex);
}).fail(function (code, jqxhr) {
console.warn("[Rater] " + (0, _api.makeErrorMsg)(code, jqxhr, "Could not retrieve pages from [[:" + q.cmtitle + "]]"));
finishedPromise.reject();
});
};
categories.forEach(function (cat, index, arr) {
cat.query = $.extend({
"cmtitle": cat.title
}, querySkeleton);
$.when(arr[index - 1] && arr[index - 1].processed || true).then(function () {
doApiQuery(cat.query, index);
});
});
categories[categories.length - 1].processed.then(function () {
var banners = {};
categories.forEach(function (catObject) {
banners[catObject.abbreviation] = catObject.banners;
});
finishedPromise.resolve(banners);
});
return finishedPromise;
};
/**
* Gets banners from cache, if there and not too old
*
* @returns {Promise} Resolved with banners object
*/
var getBannersFromCache = function getBannersFromCache() {
var cachedBanners = cache.read("banners");
if (!cachedBanners || !cachedBanners.value || !cachedBanners.staleDate) {
return $.Deferred().reject();
}
if ((0, _util.isAfterDate)(cachedBanners.staleDate)) {
// Update in the background; still use old list until then
getListOfBannersFromApi().then(cacheBanners);
}
return $.Deferred().resolve(cachedBanners.value);
};
/**
* Gets banner names, grouped by type (withRatings, withoutRatings, wrappers, notWPBM)
* @returns {Promise<Object>} Object of string arrays keyed by type (withRatings, withoutRatings, wrappers, notWPBM)
*/
var getBannerNames = exports.getBannerNames = function getBannerNames() {
return getBannersFromCache().then(function (banners) {
// Ensure all keys exist
if (!banners.withRatings || !banners.withoutRatings || !banners.wrappers || !banners.notWPBM || !banners.inactive || !banners.wir) {
getListOfBannersFromApi().then(cacheBanners);
return $.extend({
withRatings: [],
withoutRatings: [],
wrappers: [],
notWPBM: [],
inactive: [],
wir: []
}, banners);
}
// Success: pass through
return banners;
})["catch"](function () {
// Failure: get from Api, then cache them
var bannersPromise = getListOfBannersFromApi();
bannersPromise.then(cacheBanners);
return bannersPromise;
});
};
// </nowiki>
},{"./api":15,"./cache":17,"./util":23}],21:[function(require,module,exports){
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setPrefs = exports.getPrefs = exports["default"] = void 0;
var _api = _interopRequireDefault(require("./api"));
var _util = require("./util");
var _config = _interopRequireDefault(require("./config"));
var cache = _interopRequireWildcard(require("./cache"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
// <nowiki>
var prefsPage = "User:".concat(mw.config.get("wgUserName"), "/raterPrefs.json");
var writePrefsToCache = function writePrefsToCache(prefs) {
return cache.write("prefs", prefs, 1 / 24 / 60 * 1,
// 1 min
1 / 24 / 60 * 1 // 1 min
);
};
var getPrefsFromApi = function getPrefsFromApi() {
return _api["default"].get({
"action": "query",
"format": "json",
"prop": "revisions",
"titles": prefsPage,
"rvprop": "content",
"rvslots": "main"
}).then(function (response) {
var page = response.query.pages[Object.keys(response.query.pages)[0]];
if (!page.pageid || page.missing === "") {
return _config["default"].defaultPrefs;
}
var prefs;
try {
prefs = JSON.parse(page.revisions[0].slots.main["*"]);
} catch (e) {
return $.Deferred().reject("JSON-parsing-error", e);
}
writePrefsToCache(prefs);
return prefs;
});
};
var getPrefsFromCache = function getPrefsFromCache() {
var cachedPrefs = cache.read("prefs");
if (!cachedPrefs || !cachedPrefs.value || !cachedPrefs.staleDate || (0, _util.isAfterDate)(cachedPrefs.staleDate)) {
// No cached value, or is too old
return $.Deferred().reject();
}
return $.Deferred().resolve(cachedPrefs.value);
};
var getPrefs = exports.getPrefs = function getPrefs() {
return getPrefsFromCache().then(
// Success: pass through (first param only)
function (prefs) {
return $.Deferred().resolve(prefs);
},
// Failure: get from Api
function () {
return getPrefsFromApi();
});
};
/**
*
* @param {Object} updatedPrefs object with key:value pairs for preferences json.
*/
var setPrefs = exports.setPrefs = function setPrefs(updatedPrefs) {
return _api["default"].editWithRetry(prefsPage, null, function () {
return {
"text": JSON.stringify(updatedPrefs),
"summary": "Saving Rater preferences " + _config["default"].script.advert
};
}).then(function () {
return writePrefsToCache(updatedPrefs);
});
};
var _default = exports["default"] = {
get: getPrefs,
set: setPrefs
}; // </nowiki>
},{"./api":15,"./cache":17,"./config":18,"./util":23}],22:[function(require,module,exports){
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("./config"));
var _api = _interopRequireDefault(require("./api"));
var _Template = require("./Template");
var _getBanners = require("./getBanners");
var cache = _interopRequireWildcard(require("./cache"));
var _windowManager = _interopRequireDefault(require("./windowManager"));
var _prefs = require("./prefs");
var _util = require("./util");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
// <nowiki>
var setupRater = function setupRater(clickEvent) {
if (clickEvent) {
clickEvent.preventDefault();
}
var setupCompletedPromise = $.Deferred();
var currentPage = mw.Title.newFromText(_config["default"].mw.wgPageName);
var talkPage = currentPage && currentPage.getTalkPage();
var subjectPage = currentPage && currentPage.getSubjectPage();
var subjectIsArticle = _config["default"].mw.wgNamespaceNumber <= 1;
// Get preferences (task 0)
var prefsPromise = (0, _prefs.getPrefs)();
// Get lists of all banners (task 1)
var bannersPromise = (0, _getBanners.getBannerNames)();
// Load talk page (task 2)
var loadTalkPromise = _api["default"].get({
action: "query",
prop: "revisions",
rvprop: "content",
rvsection: "0",
titles: talkPage.getPrefixedText(),
indexpageids: 1
}).then(function (result) {
var id = result.query.pageids;
var wikitext = id < 0 ? "" : result.query.pages[id].revisions[0]["*"];
return wikitext;
});
// Parse talk page for banners (task 3)
var parseTalkPromise = loadTalkPromise.then(function (wikitext) {
return (0, _Template.parseTemplates)(wikitext, true);
}) // Get all templates
.then(function (templates) {
return templates.filter(function (template) {
return template.getTitle() !== null;
});
}) // Filter out invalid templates (e.g. parser functions)
.then(function (templates) {
return (0, _Template.getWithRedirectTo)(templates);
}) // Check for redirects
.then(function (templates) {
return bannersPromise.then(function (allBanners) {
// Get list of all banner templates
return (0, _util.filterAndMap)(templates,
// Filter out non-banners
function (template) {
if (template.isShellTemplate()) {
return true;
}
var mainText = template.redirectTarget ? template.redirectTarget.getMainText() : template.getTitle().getMainText();
return allBanners.withRatings.includes(mainText) || allBanners.withoutRatings.includes(mainText) || allBanners.wrappers.includes(mainText) || allBanners.notWPBM.includes(mainText) || allBanners.inactive.includes(mainText) || allBanners.wir.includes(mainText);
},
// Set additional properties if needed
function (template) {
var mainText = template.redirectTarget ? template.redirectTarget.getMainText() : template.getTitle().getMainText();
if (allBanners.wrappers.includes(mainText)) {
template.redirectTarget = mw.Title.newFromText("Template:Subst:" + mainText);
}
if (allBanners.withoutRatings.includes(mainText) || allBanners.wir.includes(mainText)) {
template.withoutRatings = true;
}
if (allBanners.inactive.includes(mainText)) {
template.inactiveProject = true;
}
return template;
});
});
});
// Retrieve and store classes, importances, and TemplateData (task 4)
var templateDetailsPromise = parseTalkPromise.then(function (templates) {
// Wait for all promises to resolve
return $.when.apply(null, [].concat(_toConsumableArray(templates.map(function (template) {
return template.isShellTemplate() ? null : template.setClassesAndImportances();
})), _toConsumableArray(templates.map(function (template) {
return template.setParamDataAndSuggestions();
})))).then(function () {
// Add missing required/suggested values
templates.forEach(function (template) {
return template.addMissingParams();
});
// Return the now-modified templates
return templates;
});
});
// Check subject page features (task 5) - but don't error out if request fails
var subjectPageCheckPromise = _api["default"].get({
action: "query",
format: "json",
formatversion: "2",
prop: "categories",
titles: subjectPage.getPrefixedText(),
redirects: 1,
clcategories: ["Category:All disambiguation pages", "Category:All stub articles", "Category:Good articles", "Category:Featured articles", "Category:Featured lists"]
}).then(function (response) {
if (!response || !response.query || !response.query.pages) {
return null;
}
var redirectTarget = response.query.redirects && response.query.redirects[0].to || false;
if (redirectTarget || !subjectIsArticle) {
return {
redirectTarget: redirectTarget
};
}
var page = response.query.pages[0];
var hasCategory = function hasCategory(category) {
return page.categories && page.categories.find(function (cat) {
return cat.title === "Category:" + category;
});
};
return {
redirectTarget: redirectTarget,
disambig: hasCategory("All disambiguation pages"),
stubtag: hasCategory("All stub articles"),
isGA: hasCategory("Good articles"),
isFA: hasCategory("Featured articles"),
isFL: hasCategory("Featured lists"),
isList: !hasCategory("Featured lists") && /^Lists? of/.test(subjectPage.getPrefixedText())
};
})["catch"](function () {
return null;
}); // Failure ignored
// Retrieve rating from ORES (task 6, only needed for articles) - but don't error out if request fails
var shouldGetOres = subjectIsArticle; // TODO: Don't need to get ORES for redirects or disambigs
if (shouldGetOres) {
var latestRevIdPromise = !currentPage.isTalkPage() ? $.Deferred().resolve(_config["default"].mw.wgRevisionId) : _api["default"].get({
action: "query",
format: "json",
prop: "revisions",
titles: subjectPage.getPrefixedText(),
rvprop: "ids",
indexpageids: 1
}).then(function (result) {
if (result.query.redirects) {
return false;
}
var id = result.query.pageids;
var page = result.query.pages[id];
if (page.missing === "") {
return false;
}
if (id < 0) {
return $.Deferred().reject();
}
return page.revisions[0].revid;
});
var oresPromise = latestRevIdPromise.then(function (latestRevId) {
if (!latestRevId) {
return false;
}
return _api["default"].getORES(latestRevId).then(function (result) {
var data = result.enwiki.scores[latestRevId].articlequality;
if (data.error) {
return $.Deferred().reject(data.error.type, data.error.message);
}
var prediction = data.score.prediction;
var probabilities = data.score.probability;
if (prediction === "FA" || prediction === "GA") {
return {
prediction: "B or higher",
probability: ((probabilities.FA + probabilities.GA + probabilities.B) * 100).toFixed(1) + "%"
};
}
return {
prediction: prediction,
probability: (probabilities[prediction] * 100).toFixed(1) + "%"
};
})["catch"](function () {
return null;
}); // Failure ignored;
});
}
// Open the load dialog
var isOpenedPromise = $.Deferred();
var loadDialogWin = _windowManager["default"].openWindow("loadDialog", {
promises: [bannersPromise, loadTalkPromise, parseTalkPromise, templateDetailsPromise, subjectPageCheckPromise, shouldGetOres && oresPromise],
ores: shouldGetOres,
isOpened: isOpenedPromise
});
loadDialogWin.opened.then(isOpenedPromise.resolve);
$.when(prefsPromise, loadTalkPromise, templateDetailsPromise, subjectPageCheckPromise, shouldGetOres && oresPromise).then(
// All succeded
function (preferences, talkWikitext, banners, subjectPageCheck, oresPredicition) {
var result = {
success: true,
talkpage: talkPage,
subjectPage: subjectPage,
talkWikitext: talkWikitext,
banners: banners,
preferences: preferences,
isArticle: subjectIsArticle
};
if (subjectPageCheck) {
result = _objectSpread(_objectSpread({}, result), subjectPageCheck);
}
if (oresPredicition && subjectPageCheck && !subjectPageCheck.isGA && !subjectPageCheck.isFA && !subjectPageCheck.isFL) {
result.ores = oresPredicition;
}
_windowManager["default"].closeWindow("loadDialog", result);
}); // Any failures are handled by the loadDialog window itself
// On window closed, check data, and resolve/reject setupCompletedPromise
loadDialogWin.closed.then(function (data) {
if (data && data.success) {
// Got everything needed: Resolve promise with this data
setupCompletedPromise.resolve(data);
} else if (data && data.error) {
// There was an error: Reject promise with error code/info
setupCompletedPromise.reject(data.error.code, data.error.info);
} else {
// Window closed before completion: resolve promise without any data
setupCompletedPromise.resolve(null);
}
cache.clearInvalidItems();
});
return setupCompletedPromise;
};
var _default = exports["default"] = setupRater; // </nowiki>
},{"./Template":3,"./api":15,"./cache":17,"./config":18,"./getBanners":20,"./prefs":21,"./util":23,"./windowManager":24}],23:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.classMask = classMask;
exports.filterAndMap = void 0;
exports.importanceMask = importanceMask;
exports.isAfterDate = void 0;
exports.mostFrequent = mostFrequent;
exports.normaliseYesNo = void 0;
exports.uniqueArray = uniqueArray;
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
// <nowiki>
// Various utility functions and objects that might be used in multiple places
var isAfterDate = exports.isAfterDate = function isAfterDate(dateString) {
return new Date(dateString) < new Date();
};
var yesWords = ["add", "added", "affirm", "affirmed", "include", "included", "on", "true", "yes", "y", "1"];
var noWords = ["decline", "declined", "exclude", "excluded", "false", "none", "not", "no", "n", "off", "omit", "omitted", "remove", "removed", "0"];
var normaliseYesNo = exports.normaliseYesNo = function normaliseYesNo(val) {
if (val == null) {
return val;
}
var trimmedLcVal = val.trim().toLowerCase();
if (yesWords.includes(trimmedLcVal)) {
return "yes";
} else if (noWords.includes(trimmedLcVal)) {
return "no";
} else {
return trimmedLcVal;
}
};
/**
*
* @param {Array} array
* @param {Function} filterPredicate (currentVal, currentIndex, array) => {boolean}
* @param {Function} mapTransform (currentVal, currentIndex, array) => {any}
* @returns {Array}
*/
var filterAndMap = exports.filterAndMap = function filterAndMap(array, filterPredicate, mapTransform) {
return array.reduce(function (accumulated, currentVal, currentIndex) {
if (filterPredicate(currentVal, currentIndex, array)) {
return [].concat(_toConsumableArray(accumulated), [mapTransform(currentVal, currentIndex, array)]);
}
return accumulated;
}, []);
};
/**
*
* @param {string[]|number[]} array
* @returns {string|null} item with the highest frequency
* e.g. `mostFrequent(["apple", "apple", "orange"])` returns `"apple"`
*/
function mostFrequent(array) {
if (!array || !Array.isArray(array) || array.length === 0) return null;
var map = {};
var mostFreq = null;
array.forEach(function (item) {
map[item] = (map[item] || 0) + 1;
if (mostFreq === null || map[item] > map[mostFreq]) {
mostFreq = item;
}
});
return mostFreq;
}
/**
*
* @param {string[]|number[]} array
* @returns {string[]|number[]} array with only unique values
* e.g. `uniqueArray(["apple", "apple", "orange"])` returns `["apple", "orange"]`
*/
function uniqueArray(array) {
if (!array || !Array.isArray(array) || array.length === 0) return [];
var seen = {};
var unique = [];
array.forEach(function (item) {
if (!seen[item]) {
unique.push(item);
seen[item] = true;
}
});
return unique;
}
function classMask(classVal) {
if (!classVal) {
return classVal;
}
switch (classVal.toLowerCase()) {
case "fa":
case "fl":
case "a":
case "ga":
case "b":
case "c":
case "na":
case "fm":
case "al":
case "bl":
case "cl":
return classVal.toUpperCase();
case "start":
case "stub":
case "list":
case "portal":
case "project":
case "draft":
case "book":
case "future":
case "current":
case "complete":
case "substantial":
case "basic":
case "incomplete":
case "meta":
return classVal.slice(0, 1).toUpperCase() + classVal.slice(1).toLowerCase();
case "image":
case "img":
case "file":
return "File";
case "category":
case "cat":
case "categ":
return "Category";
case "disambiguation":
case "disambig":
case "disamb":
case "dab":
return "Disambig";
case "redirect":
case "redir":
case "red":
return "Redirect";
case "template":
case "temp":
case "tpl":
return "Template";
case "bplus":
case "b+":
return "Bplus";
case "fpo":
return "FPo";
default:
return classVal;
}
}
function importanceMask(importance) {
if (!importance) {
return importance;
}
if (importance.toLowerCase() === "na") {
return "NA";
}
return importance.slice(0, 1).toUpperCase() + importance.slice(1).toLowerCase();
}
// </nowiki>
},{}],24:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _LoadDialog = _interopRequireDefault(require("./Windows/LoadDialog"));
var _MainWindow = _interopRequireDefault(require("./Windows/MainWindow"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
// <nowiki>
var factory = new OO.Factory();
// Register window constructors with the factory.
factory.register(_LoadDialog["default"]);
factory.register(_MainWindow["default"]);
var manager = new OO.ui.WindowManager({
"factory": factory
});
// Marker class, so CSS rules can target Rater's own windows without affecting
// other OOUI dialogs (e.g. OO.ui.confirm, which renders in #mw-teleport-target)
manager.$element.addClass("rater-windowManager");
$(document.body).append(manager.$element);
var _default = exports["default"] = manager; // </nowiki>
},{"./Windows/LoadDialog":13,"./Windows/MainWindow":14}]},{},[2])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJwYWNrYWdlLmpzb24iLCJyYXRlci1zcmMvQXBwLmpzIiwicmF0ZXItc3JjL1RlbXBsYXRlLmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9CYW5uZXJMaXN0V2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9CYW5uZXJXaWRnZXQuanMiLCJyYXRlci1zcmMvV2luZG93cy9Db21wb25lbnRzL0Ryb3Bkb3duUGFyYW1ldGVyV2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9Ib3Jpem9udGFsTGF5b3V0V2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9QYXJhbWV0ZXJMaXN0V2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvQ29tcG9uZW50cy9QYXJhbWV0ZXJXaWRnZXQuanMiLCJyYXRlci1zcmMvV2luZG93cy9Db21wb25lbnRzL1ByZWZzRm9ybVdpZGdldC5qcyIsInJhdGVyLXNyYy9XaW5kb3dzL0NvbXBvbmVudHMvU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldC5qcyIsInJhdGVyLXNyYy9XaW5kb3dzL0NvbXBvbmVudHMvVG9wQmFyV2lkZ2V0LmpzIiwicmF0ZXItc3JjL1dpbmRvd3MvTG9hZERpYWxvZy5qcyIsInJhdGVyLXNyYy9XaW5kb3dzL01haW5XaW5kb3cuanMiLCJyYXRlci1zcmMvYXBpLmpzIiwicmF0ZXItc3JjL2F1dG9zdGFydC5qcyIsInJhdGVyLXNyYy9jYWNoZS5qcyIsInJhdGVyLXNyYy9jb25maWcuanMiLCJyYXRlci1zcmMvY3NzLmpzIiwicmF0ZXItc3JjL2dldEJhbm5lcnMuanMiLCJyYXRlci1zcmMvcHJlZnMuanMiLCJyYXRlci1zcmMvc2V0dXAuanMiLCJyYXRlci1zcmMvdXRpbC5qcyIsInJhdGVyLXNyYy93aW5kb3dNYW5hZ2VyLmpzIl0sIm5hbWVz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QUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsY0FBQSxFQUFBLElBQUEsQ0FBQSxnQkFBQSxFQUFBLE9BQUEsY0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxPQUFBLENBQUEsSUFBQSxDQUFBLEdBQUEsTUFBQSxDQUFBLGNBQUEsS0FBQSxNQUFBLENBQUEsd0JBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxPQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsQ0FBQSxDQUFBLEdBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsRUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxXQUFBLENBQUEsS0FBQSxDQUFBLEVBQUEsQ0FBQTtBQUFBLFNBQUEsdUJBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxHQUFBLENBQUEsZ0JBQUEsQ0FBQTtBQUFBLFNBQUEsbUJBQUEsQ0FBQSxXQUFBLGtCQUFBLENBQUEsQ0FBQSxLQUFBLGdCQUFBLENBQUEsQ0FBQSxLQUFBLDJCQUFBLENBQUEsQ0FBQSxLQUFBLGtCQUFBO0FBQUEsU0FBQSxtQkFBQSxjQUFBLFNBQUE7QUFBQSxTQUFBLDRCQUFBLENBQUEsRUFBQSxDQUFBLFFBQUEsQ0FBQSwyQkFBQSxDQUFBLFNBQUEsaUJBQUEsQ0FBQSxDQUFBLEVBQUEsQ0FBQSxPQUFBLENBQUEsTUFBQSxRQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxLQUFBLDZCQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsV0FBQSxLQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsV0FBQSxDQUFBLElBQUEsYUFBQSxDQUFBLGNBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxvQkFBQSxDQUFBLCtDQUFBLElBQUEsQ0FBQSxDQUFBLElBQUEsaUJBQUEsQ0FBQSxDQUFBLEVBQUEsQ0FBQTtBQUFBLFNBQUEsaUJBQUEsQ0FBQSw4QkFB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Q0FBQSxFQUFBLENBQUEsT0FBQSxDQUFBLE1BQUEsUUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsS0FBQSw2QkFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFdBQUEsS0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLFdBQUEsQ0FBQSxJQUFBLGFBQUEsQ0FBQSxjQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsb0JBQUEsQ0FBQSwrQ0FBQSxJQUFBLENBQUEsQ0FBQSxJQUFBLGlCQUFBLENBQUEsQ0FBQSxFQUFBLENBQUE7QUFBQSxTQUFBLGtCQUFBLENBQUEsRUFBQSxDQUFBLGFBQUEsQ0FBQSxJQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsTUFBQSxNQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsTUFBQSxZQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLENBQUEsR0FBQSxDQUFBLEdBQUEsQ0FBQSxFQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxDQUFBLFVBQUEsQ0FBQTtBQUFBLFNBQUEsc0JBQUEsQ0FBQSxFQUFBLENBQUEsUUFBQSxDQUFBLFdBQUEsQ0FBQSxnQ0FBQSxNQUFBLElBQUEsQ0FBQSxDQUFBLE1BQUEsQ0FBQSxRQUFBLEtBQUEsQ0FBQSw0QkFBQSxDQUFBLFFBQUEsQ0FBQSxFQUFBLENBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLENBQUEsT0FBQSxDQUFBLE9BQUEsQ0FBQSxpQkFBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsUUFBQSxDQUFBLFFBQUEsTUFBQSxDQUFBLENBQUEsTUFBQSxDQUFBLFVBQUEsQ0FBQSx1QkFBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsTUFBQSxDQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxLQUFBLEdBQUEsQ0FBQSxDQUFBLE1BQUEsS0FBQSxDQUFBLEdBQUEsQ0FBQSxpQkFBQSxDQUFBLElBQUEsQ0FBQSxPQUFBLENBQUEsR0FBQSxDQUFBLHlCQUFBLENBQUEsWUFBQSxDQUFBLGVBQUEsQ0FBQSxHQUFBLENBQUEsY0FBQSxNQUFBLENBQUEsQ0FBQSxNQUFBLENBQUEsMkJBQUEsQ0FBQSxRQUFBLENBQUEsYUFBQSxDQUFBO0FBQUEsU0FBQSxnQkFBQSxDQUFBLFFBQUEsS0FBQSxDQUFBLE9BQUEsQ0FBQSxDQUFBLFVBQUEsQ0FBQTtBQUNoRDs7QUFFQSxJQUFJLGdCQUFnQixHQUFHLFNBQVMsZ0JBQWdCLENBQUUsTUFBTSxFQUFHO0VBQzFELE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDOztFQUVyQjtFQUNBLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLE1BQU8sQ0FBQztFQUM1QyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFFLElBQUksRUFBRTtJQUNwQyxNQUFNLEVBQUUsSUFBSSxDQUFDO0VBQ2QsQ0FBRSxDQUFDO0VBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFBQyxTQUFTLEVBQUM7RUFBcUIsQ0FBQyxDQUFDOztFQUV2RjtFQUNBLElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVc7RUFFckMsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUztFQUVqQyxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUs7O0VBRXBCO0VBQ0EsSUFBSSxDQUFDLFNBQVMsQ0FBRTtJQUFDLFFBQVEsRUFBRTtFQUFjLENBQUUsQ0FBQztFQUM1QyxJQUFJLENBQUMsT0FBTyxDQUFFLElBQUksRUFBRTtJQUFDLGNBQWMsRUFBRTtFQUFnQixDQUFFLENBQUM7RUFFeEQsSUFBSSxDQUFDLFNBQVMsQ0FBRTtJQUFDLFNBQVMsRUFBRTtFQUFlLENBQUUsQ0FBQztFQUM5QyxJQUFJLENBQUMsT0FBTyxDQUFFLElBQUksRUFBRTtJQUFDLGVBQWUsRUFBRTtFQUFZLENBQUUsQ0FBQztFQUVyRCxJQUFJLENBQUMsU0FBUyxDQUFFO0lBQUMsdUJBQXVCLEVBQUU7RUFBd0IsQ0FBRSxDQUFDO0VBQ3JFLElBQUksQ0FBQyxPQUFPLENBQUUsSUFBSSxFQUFFO0lBQUMsd0JBQXdCLEVBQUU7RUFBc0MsQ0FBRSxDQUFDO0VBRXhGLElBQUksQ0FBQyxTQUFTLENBQUU7SUFBQyxhQUFhLEVBQUU7RUFBbUIsQ0FBRSxDQUFDO0VBQ3RELElBQUksQ0FBQyxPQUFPLENBQUUsSUFBSSxFQUFFO0lBQUMsbUJBQW1CLEVBQUU7RUFBZSxDQUFFLENBQUM7QUFDN0QsQ0FBQztBQUVELEVBQUUsQ0FBQyxZQUFZLENBQUUsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFPLENBQUM7QUFDakQsRUFBRSxDQUFDLFVBQVUsQ0FBRSxnQkFBZ0IsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFhLENBQUM7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLFlBQVc7RUFDckQ7RUFDQSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztBQUN6QixDQUFDO0FBRUQsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxZQUFXO0VBQ2xELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSTtBQUNwQixDQUFDO0FBRUQsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLGNBQWMsR0FBRyxVQUFXLE1BQU0sRUFBRztFQUMvRCxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7RUFDMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ2xCLENBQUM7QUFFRCxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsb0NBQW9DLEdBQUcsVUFBVSxlQUFlLEVBQUc7RUFDN0YsZUFBZSxHQUFHLGVBQWUsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FDbkQsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsUUFBUSxLQUFLLHVCQUF1QixJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsS0FBSyx1QkFBdUI7RUFBQSxDQUNuSCxDQUFDO0VBQ0QsSUFBSSxDQUFDLGVBQWUsRUFBRTtFQUV0QixJQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUMxQyxVQUFBLE1BQU07SUFBQSxPQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssa0JBQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksTUFBTSxDQUFDLHNCQUFzQixLQUFLLGtCQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztFQUFBLENBQ3JILENBQUM7RUFDRCxJQUFJLENBQUMsbUJBQW1CLEVBQUU7SUFDekI7RUFDRDtFQUVBLElBQU0sWUFBWSxHQUFHLENBQ3BCO0lBQUUsSUFBSSxFQUFFLFFBQVE7SUFBRSxTQUFTLEVBQUU7RUFBSyxDQUFDLEVBQ25DO0lBQUUsSUFBSSxFQUFFLE1BQU07SUFBRSxTQUFTLEVBQUU7RUFBSyxDQUFDLEVBQ2pDO0lBQUUsSUFBSSxFQUFFLFdBQVc7SUFBRSxTQUFTLEVBQUU7RUFBSyxDQUFDLEVBQ3RDO0lBQUUsSUFBSSxFQUFFLFFBQVE7SUFBRSxTQUFTLEVBQUU7RUFBTSxDQUFDLENBQ3BDO0VBQ0QsWUFBWSxDQUFDLE9BQU8sQ0FBQyxVQUFBLFdBQVcsRUFBSTtJQUNuQyxJQUFBLElBQUEsR0FBcUMsQ0FBQyxlQUFlLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBQSxNQUFNO1FBQUEsT0FDckYsTUFBTSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQ3RDLElBQUksQ0FBQyxVQUFBLFNBQVM7VUFBQSxPQUNkLFNBQVMsQ0FBQyxJQUFJLEtBQUssV0FBVyxDQUFDLElBQUksSUFDbkMsTUFBTSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssV0FBVyxDQUFDLElBQUk7UUFBQSxDQUN6RCxDQUFDO01BQUEsQ0FDSCxDQUFDO01BQUEsS0FBQSxHQUFBLGNBQUEsQ0FBQSxJQUFBO01BTk0sY0FBYyxHQUFBLEtBQUE7TUFBRSxVQUFVLEdBQUEsS0FBQTtJQU9qQyxJQUFJLENBQUMsY0FBYyxFQUFFO0lBRXJCLElBQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQyxTQUFTLEdBQUcsSUFBQSxvQkFBYyxFQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxjQUFjLENBQUMsS0FBSztJQUMxRyxjQUFjLFVBQU8sQ0FBQyxDQUFDO0lBRXZCLElBQUksQ0FBQyxVQUFVLElBQUksY0FBYyxFQUFFO01BQ2xDLElBQU0sS0FBSyxHQUFHLG1CQUFtQixDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQzdELENBQUMsQ0FBQyxDQUFDO01BQUEsRUFDSCxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUMsQ0FBQztNQUNyRCxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQzFDLElBQUksMkJBQWUsQ0FBRTtRQUNwQixNQUFNLEVBQUUsV0FBVyxDQUFDLElBQUk7UUFDeEIsT0FBTyxFQUFFLGNBQWM7UUFDdkIsWUFBWSxFQUFFO01BQ2YsQ0FBQyxFQUNELG1CQUFtQixDQUFDLFNBQVMsSUFBSSxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FDL0UsQ0FBQyxDQUNELEVBQUUsS0FBSyxDQUFDO0lBQ1YsQ0FBQyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxJQUFJLGNBQWMsRUFBRTtNQUN4RCxVQUFVLENBQUMsUUFBUSxDQUFFLGNBQWUsQ0FBQztNQUNyQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDM0I7RUFDRCxDQUFDLENBQUM7QUFDSCxDQUFDO0FBRUQsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLHlCQUF5QixHQUFHLFlBQVk7RUFBQSxJQUFBLEtBQUE7RUFDbEUsSUFDQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQUEsTUFBTTtJQUFBLE9BQUksTUFBTSxDQUFDLGVBQWU7RUFBQSxFQUFDLEVBQ2pEO0lBQ0Qsd0JBQVksQ0FBQyxtQkFBbUIsQ0FDL0Isa0JBQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQ3hCO01BQUMsY0FBYyxFQUFFO0lBQUksQ0FBQyxFQUN0QjtNQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztNQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQVMsQ0FDbkUsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLGlCQUFpQixFQUFJO01BQzNCLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBRSxLQUFJLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUUsQ0FBQztNQUNoRjtNQUNBLEtBQUksQ0FBQyxvQkFBb0IsQ0FBQztRQUFDLGNBQWMsRUFBRTtNQUFJLENBQUMsQ0FBQztNQUNqRDtNQUNBLEtBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNyQixDQUFDLENBQUM7RUFDSDtFQUVBLE9BQU8sSUFBSTtBQUNaLENBQUM7QUFHRCxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsUUFBUSxHQUFHLFVBQVcsS0FBSyxFQUFFLEtBQUssRUFBRztFQUUvRCxJQUFLLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFHO0lBQ3pCLE9BQU8sSUFBSTtFQUNaOztFQUVBO0VBQ0EsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBTSxDQUFDOztFQUV0RTtFQUNBLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFBLE1BQU07SUFBQSxPQUFJLE1BQU0sQ0FBQyxlQUFlO0VBQUEsRUFBQyxFQUFFO0lBQ3ZELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0VBQzVCO0VBQ0EsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUM7O0VBRWhDO0VBQ0EsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0VBRXBCLE9BQU8sSUFBSTtBQUNaLENBQUM7QUFFRCxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEdBQUcsVUFBUyxNQUFNLEVBQUU7RUFDbEUsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUM7RUFDckI7RUFDQSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyx1QkFBdUIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMscUJBQXFCLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFO0lBQ25IO0VBQ0Q7RUFDQTtFQUNBLElBQU0sa0JBQWtCLEdBQUcsSUFBQSxpQkFBVyxFQUFFLElBQUEsa0JBQVksRUFDbkQsSUFBSSxDQUFDLEtBQUssRUFDVixVQUFBLE1BQU0sRUFBSTtJQUNULElBQUksTUFBTSxDQUFDLGVBQWUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUU7TUFDdEQsT0FBTyxLQUFLO0lBQ2I7SUFDQSxJQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNuRSxPQUFPLFNBQVMsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7RUFDeEMsQ0FBQyxFQUNELFVBQUEsTUFBTTtJQUFBLE9BQUksTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztFQUFBLENBQ3RFLENBQUMsQ0FBQztFQUNGO0VBQ0EsSUFBSSxrQkFBa0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO0lBQ2xDO0VBQ0Q7RUFDQTtFQUNBLElBQUksU0FBUztFQUNiLElBQUksa0JBQWtCLENBQUMsTUFBTSxLQUFLLENBQUMsS0FBSyxJQUFJLENBQUMsV0FBVyxDQUFDLHVCQUF1QixJQUFJLE1BQU0sQ0FBQyxjQUFjLENBQUMsRUFBRTtJQUMzRyxTQUFTLEdBQUcsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO0VBQ2xDLENBQUMsTUFBTSxJQUFJLGtCQUFrQixDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxxQkFBcUIsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO0lBQ3ZHO0lBQ0EsUUFBTyxJQUFJLENBQUMsU0FBUztNQUNyQixLQUFLLE1BQU07TUFBRSxLQUFLLE9BQU87TUFBRSxLQUFLLEdBQUc7TUFBRSxLQUFLLE1BQU07UUFDL0MsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTO0lBQzNCO0VBQ0QsQ0FBQyxNQUFNO0lBQ047SUFDQTtFQUNEO0VBQ0E7RUFDQSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFBLE1BQU0sRUFBSTtJQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUU7TUFDdkQ7SUFDRDtJQUNBLElBQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ25FLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRTtNQUMvRDtJQUNEO0lBQ0EsSUFBSSxNQUFNLENBQUMsY0FBYyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxTQUFTLEVBQUU7TUFDMUYsTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQztNQUNyRDtJQUNEO0lBQ0EsTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQztJQUMxRCxNQUFNLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUM7RUFDekMsQ0FBQyxDQUFDO0FBQ0gsQ0FBQztBQUVELGdCQUFnQixDQUFDLFNBQVMsQ0FBQyx5QkFBeUIsR0FBRyxZQUFXO0VBQ2pFLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixFQUFFO0lBQ3pDO0VBQ0Q7RUFDQSxJQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVTtFQUN6SCxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7SUFDdEI7RUFDRDtFQUNBO0VBQ0E7RUFDQSxJQUFNLGNBQWMsR0FBRyxLQUFLO0VBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQUEsTUFBTSxFQUFJO0lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUU7TUFDakM7SUFDRDtJQUNBLElBQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDN0UsSUFBSSxjQUFjLElBQUksY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUU7TUFDL0M7SUFDRDtJQUNBLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLGNBQWMsQ0FBQztJQUNwRSxNQUFNLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztFQUM5QyxDQUFDLENBQUM7QUFDSCxDQUFDO0FBRUQsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLGNBQWMsR0FBRyxVQUFTLEtBQUssRUFBRTtFQUMzRCxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUs7RUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQztFQUFBLEVBQUM7RUFDMUQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7RUFDM0IsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVELGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxZQUFZLEdBQUcsWUFBVztFQUNwRCxJQUFJLGVBQWUsR0FBRyxJQUFBLGtCQUFZLEVBQ2pDLElBQUksQ0FBQyxLQUFLLEVBQ1YsVUFBQSxNQUFNO0lBQUEsT0FBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlO0VBQUEsR0FDakMsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7RUFBQSxDQUNoQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztFQUNaLElBQUksYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQUEsTUFBTTtJQUFBLE9BQUksTUFBTSxDQUFDLGVBQWU7RUFBQSxFQUFDO0VBQ3JFLElBQUksQ0FBQyxhQUFhLEVBQUU7SUFDbkIsT0FBTyxlQUFlO0VBQ3ZCO0VBQ0EsSUFBSSxXQUFXLEdBQUcsSUFBSSwyQkFBZSxDQUFDO0lBQ3JDLElBQUksRUFBQyxHQUFHO0lBQ1IsS0FBSyxFQUFFLElBQUksR0FBRyxlQUFlLEdBQUcsSUFBSSxJQUNsQyxhQUFhLENBQUMsb0JBQW9CLEdBQUcsYUFBYSxDQUFDLG9CQUFvQixHQUFHLElBQUksR0FBRyxFQUFFO0VBQ3RGLENBQUMsQ0FBQztFQUNGLGFBQWEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUUsV0FBVyxDQUFFLENBQUM7RUFDckQsSUFBSSxhQUFhLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO0VBQ2hELGFBQWEsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUUsV0FBVyxDQUFFLENBQUM7RUFDeEQsT0FBTyxhQUFhO0FBQ3JCLENBQUM7QUFBQyxJQUFBLFFBQUEsR0FBQSxPQUFBLGNBRWEsZ0JBQWdCLEVBQy9COzs7Ozs7Ozs7QUN2UUEsSUFBQSxvQkFBQSxHQUFBLHNCQUFBLENBQUEsT0FBQTtBQUNBLElBQUEsZ0JBQUEsR0FBQSxzQkFBQSxDQUFBLE9BQUE7QUFDQSxJQUFBLHdCQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxnQ0FBQSxHQUFBLHNCQUFBLENBQUEsT0FBQTtBQUNBLElBQUEsS0FBQSxHQUFBLE9BQUE7QUFDQSxJQUFBLFNBQUEsR0FBQSxPQUFBO0FBQ0EsSUFBQSx1QkFBQSxHQUFBLHNCQUFBLENBQUEsT0FBQTtBQUNBLElBQUEsT0FBQSxHQUFBLHNCQUFBLENBQUEsT0FBQTtBQUF3QyxTQUFBLHVCQUFBLENBQUEsV0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFVBQUEsR0FBQSxDQUFBLGdCQUFBLENBQUE7QUFBQSxTQUFBLG1CQUFBLENBQUEsV0FBQSxrQkFBQSxDQUFBLENBQUEsS0FBQSxnQkFBQSxDQUFBLENBQUEsS0FBQSwyQkFBQSxDQUFBLENBQUEsS0FBQSxrQkFBQTtBQUFBLFNBQUEsbUJBQUEsY0FBQSxTQUFBO0FBQUEsU0FBQSw0QkFBQSxDQUFBLEVBQUEsQ0FBQSxRQUFBLENBQUEsMkJBQUEsQ0FBQSxTQUFBLGlCQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsT0FBQSxDQUFBLE1BQUEsUUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsS0FBQSw2QkFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFdBQUEsS0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLFdBQUEsQ0FBQSxJQUFBLGFBQUEsQ0FBQSxjQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsb0JBQUEsQ0FBQSwrQ0FBQSxJQUFBLENBQUEsQ0FBQSxJQUFBLGlCQUFBLENBQUEsQ0FBQSxFQUFBLENBQUE7QUFBQSxTQUFBLGlCQUFBLENBQUEsOEJBQUEsTUFBQSxZQUFBLENBQUEsQ0FBQSxNQUFBLENBQUEsUUFBQSxhQUFBLENBQUEsdUJBQUEsS0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBO0FBQUEsU0FBQSxtQkFBQSxDQUFBLFFBQUEsS0FBQSxDQUFBLE9BQUEsQ0FBQSxDQUFBLFVBQUEsaUJBQUEsQ0FBQSxDQUFBO0FBQUEsU0FBQSxrQkFBQSxDQUFBLEVBQUEsQ0FBQSxhQUFBLENBQUEsSUFBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLE1BQUEsTUFBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLE1BQUEsWUFBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxHQUFBLENBQUEsRUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxVQUFBLENBQUE7QUFDeEM7O0FBRUEsU0FBUyxZQUFZLENBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRztFQUFBLElBQUEsS0FBQTtFQUN6QztFQUNBLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDO0VBQ3JCO0VBQ0EsWUFBWSxTQUFNLENBQUMsSUFBSSxDQUFFLElBQUksRUFBRSxNQUFPLENBQUM7RUFDdkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUTs7RUFFL0I7RUFDQSxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXOztFQUVyQztFQUNBLElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVM7RUFDbkMsSUFBSSxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQztFQUMvQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsUUFBUSxDQUFDLG9CQUFvQjtFQUN6RCxJQUFJLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJO0VBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVE7RUFDakMsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUztFQUNuQyxJQUFJLENBQUMsV0FBVyxHQUFHLFFBQVEsQ0FBQyxXQUFXO0VBQ3ZDLElBQUksQ0FBQyxjQUFjLEdBQUcsUUFBUSxDQUFDLGNBQWM7RUFDN0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQztFQUNqRCxJQUFJLENBQUMsc0JBQXNCLEdBQUcsUUFBUSxDQUFDLGNBQWMsSUFBSSxRQUFRLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0VBQzlGLElBQUksQ0FBQyxlQUFlLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0VBQ2pELElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBQSxTQUFTO0lBQUEsT0FBSSxTQUFTLENBQUMsVUFBVTtFQUFBLEVBQUMsQ0FBQyxDQUFDO0VBQzVFLElBQUksQ0FBQyxlQUFlLEdBQUcsUUFBUSxDQUFDLE9BQU8sSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU07RUFDbEUsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFFBQVEsQ0FBQyxXQUFXLElBQUksUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNO0VBQy9FLElBQUksQ0FBQyxlQUFlLEdBQUcsUUFBUSxDQUFDLGVBQWU7O0VBRS9DOztFQUVBLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBRTtJQUMzQyxJQUFJLEVBQUUsT0FBTztJQUNiLEtBQUssRUFBRSxlQUFlO0lBQ3RCLEtBQUssRUFBRSxlQUFlO0lBQ3RCLEtBQUssRUFBRSxhQUFhO0lBQ3BCLFFBQVEsRUFBRSxDQUFDLENBQUMsNEJBQTRCO0VBQ3pDLENBQUUsQ0FBQztFQUNILElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBRTtJQUMxQyxJQUFJLEVBQUUsUUFBUTtJQUNkLEtBQUssRUFBRSxrQkFBa0I7SUFDekIsS0FBSyxFQUFFLGtCQUFrQjtJQUN6QixLQUFLLEVBQUUsYUFBYTtJQUNwQixRQUFRLEVBQUUsQ0FBQyxDQUFDLDRCQUE0QjtFQUN6QyxDQUFFLENBQUM7RUFDSCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBQyxNQUFNLENBQUM7RUFDeEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUMsTUFBTSxDQUFDO0VBRXZELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUU7SUFDckQsS0FBSyxFQUFFLENBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFFO0lBQzlDLFFBQVEsRUFBRSxDQUFDLENBQUMsNEJBQTRCO0VBQ3pDLENBQUUsQ0FBQztFQUVILElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUU7SUFDeEQsS0FBSyxPQUFBLE1BQUEsQ0FBTyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxRQUFBLE1BQUEsQ0FBSyxJQUFJLENBQUMsZUFBZSxHQUFHLGFBQWEsR0FBRyxFQUFFLENBQUU7SUFDN0YsUUFBUSxFQUFFLENBQUMsQ0FBQyxnRkFBZ0YsQ0FBQztJQUM3RixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7SUFDdkIsU0FBUyxFQUFDLE1BQU07SUFDaEIsTUFBTSxFQUFDLEtBQUs7SUFDWixLQUFLLEVBQUU7TUFDTixRQUFRLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVE7TUFDekMsS0FBSyxFQUFFLEdBQUc7TUFDVixNQUFNLEVBQUUsS0FBSztNQUNiLEtBQUssRUFBRSxhQUFhO01BQ3BCLE1BQU0sRUFBRTtJQUNUO0VBQ0QsQ0FBRSxDQUFDO0VBQ0gsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FDaEMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQUMsV0FBVyxFQUFDO0VBQU0sQ0FBQyxDQUFDLENBQy9DLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUFDLGFBQWEsRUFBQztFQUFRLENBQUMsQ0FBQzs7RUFFckU7RUFDQSxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUU7SUFDekIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLG1DQUF1QixDQUFFO01BQ2pELEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLHlDQUF5QyxDQUFDO01BQ3ZFLElBQUksRUFBRTtRQUNMLEtBQUssR0FDSixJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUU7VUFDM0IsSUFBSSxFQUFFLElBQUk7VUFDVixLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsZ0NBQUEsTUFBQSxDQUE4QixNQUFNLENBQUMsU0FBUyxHQUFHLFVBQVUsR0FBRyxhQUFhLGFBQVU7UUFDbEgsQ0FBRSxDQUFDLEVBQUEsTUFBQSxDQUFBLGtCQUFBLENBQ0Esa0JBQVksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBRSxVQUFBLFNBQVM7VUFBQSxPQUNwRCxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUU7WUFDM0IsSUFBSSxFQUFFLFNBQVM7WUFDZixLQUFLLEVBQUU7VUFDUixDQUFFLENBQUM7UUFBQSxDQUNKLENBQUM7TUFFSCxDQUFDO01BQ0QsUUFBUSxFQUFFLElBQUksQ0FBQztJQUNoQixDQUFFLENBQUM7SUFDSCxJQUFJLGVBQWUsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFBLFNBQVM7TUFBQSxPQUFJLFNBQVMsQ0FBQyxJQUFJLEtBQUssT0FBTztJQUFBLEVBQUM7SUFDdkYsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFFLGVBQWUsSUFBSSxJQUFBLGVBQVMsRUFBQyxlQUFlLENBQUMsS0FBSyxDQUFFLENBQUM7RUFDckcsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtJQUNoQyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksbUNBQXVCLENBQUU7TUFDakQsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMseUNBQXlDLENBQUM7TUFDdkUsSUFBSSxFQUFFO1FBQ0wsS0FBSyxHQUNKLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBRTtVQUMzQixJQUFJLEVBQUUsSUFBSTtVQUNWLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxnQ0FBQSxNQUFBLENBQThCLE1BQU0sQ0FBQyxTQUFTLEdBQUcsb0JBQW9CLEdBQUcsYUFBYSxhQUFVO1FBQzVILENBQUUsQ0FBQyxFQUFBLE1BQUEsQ0FBQSxrQkFBQSxDQUNBLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFFLFVBQUEsU0FBUztVQUFBLE9BQ2pDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBRTtZQUMzQixJQUFJLEVBQUUsU0FBUztZQUNmLEtBQUssRUFBRTtVQUNSLENBQUUsQ0FBQztRQUFBLENBQ0osQ0FBQztNQUVILENBQUM7TUFDRCxRQUFRLEVBQUUsSUFBSSxDQUFDO0lBQ2hCLENBQUUsQ0FBQztJQUNILElBQUksVUFBVSxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQUEsU0FBUztNQUFBLE9BQUksU0FBUyxDQUFDLElBQUksS0FBSyxPQUFPO0lBQUEsRUFBQztJQUNsRixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUUsVUFBVSxJQUFJLElBQUEsZUFBUyxFQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUUsQ0FBQztFQUMzRjtFQUVBLElBQUksSUFBSSxDQUFDLG9CQUFvQixFQUFFO0lBQzlCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLG1DQUF1QixDQUFFO01BQ3RELEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLDhDQUE4QyxDQUFDO01BQzVFLElBQUksRUFBRTtRQUNMLEtBQUssR0FDSixJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUU7VUFDM0IsSUFBSSxFQUFFLElBQUk7VUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsZ0NBQUEsTUFBQSxDQUE4QixNQUFNLENBQUMsU0FBUyxHQUFHLGVBQWUsR0FBRyxhQUFhLGFBQVU7UUFDbkksQ0FBRSxDQUFDLEVBQUEsTUFBQSxDQUFBLGtCQUFBLENBQ0EsUUFBUSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBQSxVQUFVO1VBQUEsT0FDckMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFFO1lBQzNCLElBQUksRUFBRSxVQUFVO1lBQ2hCLEtBQUssRUFBRTtVQUNSLENBQUUsQ0FBQztRQUFBLENBQ0osQ0FBQztNQUVILENBQUM7TUFDRCxRQUFRLEVBQUUsSUFBSSxDQUFDO0lBQ2hCLENBQUUsQ0FBQztJQUNILElBQUksZUFBZSxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQUEsU0FBUztNQUFBLE9BQUksU0FBUyxDQUFDLElBQUksS0FBSyxZQUFZO0lBQUEsRUFBQztJQUM1RixJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBRSxlQUFlLElBQUksSUFBQSxvQkFBYyxFQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUUsQ0FBQztFQUMvRztFQUVBLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFFO0lBQzlDLEtBQUssRUFBRSxDQUFFLElBQUksQ0FBQyxvQkFBb0I7RUFDbkMsQ0FBRSxDQUFDO0VBQ0gsSUFBSSxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUU7SUFDakQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBRSxJQUFJLENBQUMsYUFBYSxDQUFFLENBQUM7RUFDbEQ7RUFDQSxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtJQUM5QixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBRSxDQUFDO0VBQ3ZEOztFQUVBOztFQUVBLElBQUksZ0JBQWdCLEdBQUcsSUFBQSxrQkFBWSxFQUNsQyxRQUFRLENBQUMsVUFBVSxFQUNuQixVQUFBLEtBQUssRUFBSTtJQUNSLElBQUssS0FBSSxDQUFDLGVBQWUsRUFBRztNQUMzQixJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksR0FBRyxFQUFFO1FBQ3RCLEtBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsS0FBSztRQUNuQyxPQUFPLEtBQUs7TUFDYjtNQUNBLE9BQU8sS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPO0lBQzlCO0lBQ0EsT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFlBQVk7RUFDN0QsQ0FBQyxFQUNELFVBQUEsS0FBSztJQUFBLE9BQUksSUFBSSwyQkFBZSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRTtNQUFDLFFBQVEsRUFBRSxLQUFJLENBQUM7SUFBUSxDQUFDLENBQUM7RUFBQSxDQUMvRixDQUFDO0VBRUQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLCtCQUFtQixDQUFFO0lBQzdDLEtBQUssRUFBRSxnQkFBZ0I7SUFDdkIsV0FBVyxFQUFFLElBQUksQ0FBQztFQUNuQixDQUFFLENBQUM7O0VBRUg7O0VBRUEsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksMkNBQStCLENBQUM7SUFDaEUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxvQkFBb0I7SUFDMUMsV0FBVyxFQUFFLGdCQUFnQjtJQUM3QixRQUFRLEVBQUUsQ0FBQyxDQUFDLDhDQUE4QyxDQUFDO0lBQzNELFFBQVEsRUFBRSxVQUFTLEdBQUcsRUFBRTtNQUN2QixJQUFBLHFCQUFBLEdBQStCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUM7UUFBeEQsU0FBUyxHQUFBLHFCQUFBLENBQVQsU0FBUztRQUFFLElBQUksR0FBQSxxQkFBQSxDQUFKLElBQUk7UUFBRSxLQUFLLEdBQUEscUJBQUEsQ0FBTCxLQUFLO01BQzNCLE9BQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLEdBQUksSUFBSSxHQUFHLFNBQVM7SUFDNUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDWix5QkFBeUIsRUFBRSxJQUFJO0lBQy9CLFFBQVEsRUFBRSxJQUFJLENBQUM7RUFDaEIsQ0FBQyxDQUFDO0VBQ0YsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7RUFDeEMsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksMkNBQStCLENBQUM7SUFDakUsV0FBVyxFQUFFLGlCQUFpQjtJQUM5QixRQUFRLEVBQUUsQ0FBQyxDQUFDLDhDQUE4QyxDQUFDO0lBQzNELFFBQVEsRUFBRSxVQUFTLEdBQUcsRUFBRTtNQUN2QixJQUFBLHNCQUFBLEdBQWdDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDO1FBQS9ELFVBQVUsR0FBQSxzQkFBQSxDQUFWLFVBQVU7UUFBRSxJQUFJLEdBQUEsc0JBQUEsQ0FBSixJQUFJO1FBQUUsS0FBSyxHQUFBLHNCQUFBLENBQUwsS0FBSztNQUM1QixPQUFRLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFJLElBQUksR0FBRyxVQUFVO0lBQzdDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ1oseUJBQXlCLEVBQUUsSUFBSTtJQUMvQixRQUFRLEVBQUUsSUFBSSxDQUFDO0VBQ2hCLENBQUMsQ0FBQztFQUNGLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDO0lBQ2hELEtBQUssRUFBRSxLQUFLO0lBQ1osSUFBSSxFQUFFLEtBQUs7SUFDWCxLQUFLLEVBQUU7RUFDUixDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO0VBQ3BCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLGtDQUFzQixDQUFFO0lBQ3ZELEtBQUssRUFBRSxDQUNOLElBQUksQ0FBQyxxQkFBcUIsRUFDMUIsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQztNQUFDLEtBQUssRUFBQztJQUFHLENBQUMsQ0FBQyxFQUNsQyxJQUFJLENBQUMsc0JBQXNCLEVBQzNCLElBQUksQ0FBQyxrQkFBa0I7RUFFekIsQ0FBRSxDQUFDO0VBRUgsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFO0lBQzFFLEtBQUssRUFBRSxnQkFBZ0I7SUFDdkIsS0FBSyxFQUFFO0VBQ1IsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztFQUNoQjtFQUNBLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUMsR0FBRyxDQUFDO0lBQ3hFLE9BQU8sRUFBRSxNQUFNO0lBQ2YsYUFBYSxFQUFFO0VBQ2hCLENBQUMsQ0FBQzs7RUFFRjs7RUFFQTtFQUNBLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLENBQUMsTUFBTSxDQUNsRCxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQzNCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUN6QixDQUFDO0VBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7SUFDMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBRSxDQUFDO0VBQ2xDO0VBRUEsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO0lBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO01BQ2pCLFlBQVksRUFBRSxNQUFNO01BQ3BCLGVBQWUsRUFBRSxNQUFNO01BQ3ZCLFNBQVMsRUFBRSxZQUFZO01BQ3ZCLGVBQWUsRUFBRSxNQUFNO01BQ3ZCLFdBQVcsRUFBRTtJQUNkLENBQUMsQ0FBQztFQUNIOztFQUVBOztFQUVBLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtJQUN6QixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBRSxJQUFJLEVBQUU7TUFBQyxRQUFRLEVBQUU7SUFBZ0IsQ0FBRSxDQUFDO0VBQ2pFO0VBQ0EsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7SUFDOUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBRSxJQUFJLEVBQUU7TUFBQyxRQUFRLEVBQUU7SUFBcUIsQ0FBRSxDQUFDO0VBQzNFO0VBQ0EsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUUsSUFBSSxFQUFFO0lBQ2pDLFFBQVEsRUFBRSxtQkFBbUI7SUFDN0IsMEJBQTBCLEVBQUUsd0JBQXdCO0lBQ3BELGFBQWEsRUFBRTtFQUNoQixDQUFFLENBQUM7RUFDSCxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtJQUFFLE9BQU8sRUFBRTtFQUFpQixDQUFDLENBQUM7RUFDcEUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7SUFDeEMsUUFBUSxFQUFFLDBCQUEwQjtJQUNwQyxPQUFPLEVBQUUseUJBQXlCO0lBQ2xDLFFBQVEsRUFBRTtFQUNYLENBQUMsQ0FBQztFQUNGLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO0lBQ3pDLFFBQVEsRUFBRSwyQkFBMkI7SUFDckMsT0FBTyxFQUFFLDBCQUEwQjtJQUNuQyxRQUFRLEVBQUU7RUFDWCxDQUFDLENBQUM7RUFDRixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7SUFBQyxPQUFPLEVBQUU7RUFBcUIsQ0FBRyxDQUFDO0VBQ25FLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFFLElBQUksRUFBRTtJQUFDLE9BQU8sRUFBRTtFQUFvQixDQUFFLENBQUM7O0VBRWpFO0VBQ0EsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRTtJQUNyQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7RUFDdEI7QUFFRDtBQUNBLEVBQUUsQ0FBQyxZQUFZLENBQUUsWUFBWSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTyxDQUFDOztBQUU3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxDQUFDLG1CQUFtQixHQUFHLFVBQVMsWUFBWSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUU7RUFDdkUsSUFBSSxRQUFRLEdBQUcsSUFBSSxrQkFBUSxDQUFDLENBQUM7RUFDN0IsUUFBUSxDQUFDLElBQUksR0FBRyxZQUFZO0VBQzVCLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7SUFDaEMsUUFBUSxDQUFDLGNBQWMsR0FBRyxJQUFJO0VBQy9CO0VBQ0EsT0FBTyxJQUFBLDJCQUFpQixFQUFDLFFBQVEsQ0FBQyxDQUNoQyxJQUFJLENBQUMsVUFBUyxRQUFRLEVBQUU7SUFDeEIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUNaLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLEVBQ25DLFFBQVEsQ0FBQywwQkFBMEIsQ0FBQyxDQUNyQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQU07TUFDWjtNQUNBLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO01BQzNCO01BQ0EsT0FBTyxRQUFRO0lBQ2hCLENBQUMsQ0FBQztFQUNILENBQUMsQ0FBQyxDQUNELElBQUksQ0FBQyxVQUFBLFFBQVE7SUFBQSxPQUFJLElBQUksWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUM7RUFBQSxFQUFDO0FBQ3ZELENBQUM7QUFFRCxZQUFZLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxZQUFXO0VBQ2pEO0VBQ0EsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7QUFDekIsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLFlBQVc7RUFDOUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJO0VBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO0VBQ3BCLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyx1QkFBdUIsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEtBQUssdUJBQXVCLEVBQUU7SUFDekc7SUFDQSxJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDO0VBQ25DO0FBQ0QsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEdBQUcsWUFBVztFQUNyRCxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7RUFDakIsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDekMsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLFlBQVc7RUFDakQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0VBQ2pCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSTtFQUN4QixJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztFQUMvRCxJQUFJLFNBQVMsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUc7SUFDOUM7SUFDQSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7RUFDMUM7QUFDRCxDQUFDO0FBRUQsWUFBWSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsR0FBRyxZQUFXO0VBQ3RELElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztFQUNqQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSTtFQUM3QixJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0VBQ3pFLElBQUksY0FBYyxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRztJQUN4RDtJQUNBLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0VBQy9DO0FBQ0QsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsc0JBQXNCLEdBQUcsWUFBVztFQUMxRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztFQUNwQyxJQUFJLENBQUMscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUM7RUFDbEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxZQUFZLENBQUMsU0FBUyxDQUFDLG9CQUFvQixHQUFHLFVBQVMsWUFBWSxFQUFFLGFBQWEsRUFBRTtFQUNuRixJQUFJLElBQUksR0FBRyxZQUFZLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7RUFDOUYsSUFBSSxvQkFBb0IsR0FBRyxJQUFJLEtBQUssT0FBTyxJQUMxQyxJQUFJLEtBQUssWUFBWSxJQUNwQixJQUFJLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxlQUFnQixJQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQSxXQUFXO0lBQUEsT0FBSSxXQUFXLENBQUMsSUFBSSxLQUFLLElBQUk7RUFBQSxFQUFDO0VBQ3RGLElBQUksS0FBSyxHQUFHLGFBQWEsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsc0JBQXNCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztFQUNsRyxJQUFJLFNBQVMsR0FBRyxJQUFJLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxJQUFJO0VBQ3RGLE9BQU87SUFDTixTQUFTLEVBQUUsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDO0lBQzVDLFVBQVUsRUFBRSxDQUFDLEVBQUUsS0FBSyxJQUFJLFNBQVMsQ0FBQztJQUNsQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxJQUFJLFNBQVMsQ0FBQztJQUNwQyxpQkFBaUIsRUFBRSxDQUFDLEVBQUUsSUFBSSxJQUFJLG9CQUFvQixDQUFDO0lBQ25ELElBQUksRUFBSixJQUFJO0lBQ0osS0FBSyxFQUFMLEtBQUs7SUFDTCxTQUFTLEVBQVQ7RUFDRCxDQUFDO0FBQ0YsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsd0JBQXdCLEdBQUcsWUFBVztFQUM1RCxJQUFBLHNCQUFBLEdBQWlGLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQXRHLFNBQVMsR0FBQSxzQkFBQSxDQUFULFNBQVM7SUFBRSxVQUFVLEdBQUEsc0JBQUEsQ0FBVixVQUFVO0lBQUUsV0FBVyxHQUFBLHNCQUFBLENBQVgsV0FBVztJQUFFLGlCQUFpQixHQUFBLHNCQUFBLENBQWpCLGlCQUFpQjtJQUFFLElBQUksR0FBQSxzQkFBQSxDQUFKLElBQUk7SUFBRSxTQUFTLEdBQUEsc0JBQUEsQ0FBVCxTQUFTO0VBQzVFO0VBQ0EsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUUsYUFBYSxFQUFHLFNBQVMsSUFBSSxFQUFHLENBQUM7RUFDMUU7RUFDQSxJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUN2QyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLGFBQWEsSUFDbEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFVBQUEsR0FBRyxFQUFJO0lBQUMsT0FBTztNQUFDLElBQUksRUFBRSxHQUFHO01BQUUsS0FBSyxFQUFDO0lBQUcsQ0FBQztFQUFFLENBQUMsQ0FBQztFQUNqRixJQUFJLENBQUMsc0JBQXNCLENBQUMsY0FBYyxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUM7RUFDL0Q7RUFDQSxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsVUFBVSxDQUFDO0VBQzlEO0VBQ0EsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBRSxTQUFTLElBQUksV0FBVyxHQUFHLENBQUMsb0NBQW9DLENBQUMsR0FBRyxFQUFHLENBQUM7RUFDNUc7RUFDQSxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFFLGlCQUFpQixHQUFHLENBQUMsOEJBQThCLENBQUMsR0FBRyxFQUFHLENBQUM7QUFDL0YsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEdBQUcsWUFBVztFQUMzRCxJQUFJLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEMsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMseUJBQXlCLEdBQUcsWUFBVztFQUM3RCxJQUFBLHNCQUFBLEdBQTZDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQWxFLFNBQVMsR0FBQSxzQkFBQSxDQUFULFNBQVM7SUFBRSxVQUFVLEdBQUEsc0JBQUEsQ0FBVixVQUFVO0lBQUUsV0FBVyxHQUFBLHNCQUFBLENBQVgsV0FBVztFQUN4QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsVUFBVSxDQUFDO0VBQzlELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUUsU0FBUyxJQUFJLFdBQVcsR0FBRyxDQUFDLG9DQUFvQyxDQUFDLEdBQUcsRUFBRyxDQUFDO0FBQzdHLENBQUM7QUFFRCxZQUFZLENBQUMsU0FBUyxDQUFDLHdCQUF3QixHQUFHLFlBQVc7RUFDNUQ7RUFDQSxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQztFQUNoQztFQUNBLElBQUssSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUc7SUFDM0M7RUFDRDtFQUNBO0VBQ0EsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3RCLENBQUM7QUFFRCxZQUFZLENBQUMsU0FBUyxDQUFDLGNBQWMsR0FBRyxZQUFXO0VBQ2xELElBQUEsc0JBQUEsR0FBeUQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFBOUUsU0FBUyxHQUFBLHNCQUFBLENBQVQsU0FBUztJQUFFLFVBQVUsR0FBQSxzQkFBQSxDQUFWLFVBQVU7SUFBRSxJQUFJLEdBQUEsc0JBQUEsQ0FBSixJQUFJO0lBQUUsS0FBSyxHQUFBLHNCQUFBLENBQUwsS0FBSztJQUFFLFNBQVMsR0FBQSxzQkFBQSxDQUFULFNBQVM7RUFDbkQsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLFVBQVUsRUFBRTtJQUM5QjtJQUNBO0VBQ0Q7RUFDQSxJQUFJLFlBQVksR0FBRyxJQUFJLDJCQUFlLENBQ3JDO0lBQ0MsTUFBTSxFQUFFLElBQUk7SUFDWixPQUFPLEVBQUUsS0FBSyxJQUFJO0VBQ25CLENBQUMsRUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUNwQjtJQUFDLFFBQVEsRUFBRSxJQUFJLENBQUM7RUFBUSxDQUN6QixDQUFDO0VBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQztFQUMzQyxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztFQUN2QyxJQUFJLENBQUMsc0JBQXNCLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztFQUN4QyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzFDLENBQUM7QUFFRCxZQUFZLENBQUMsU0FBUyxDQUFDLGlDQUFpQyxHQUFHLFlBQVc7RUFDckUsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0VBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FDN0MsVUFBQSxXQUFXO0lBQUEsT0FBSSxXQUFXLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUk7RUFBQSxDQUNwRCxDQUFDO0VBQ0QsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGNBQWMsQ0FDeEMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FDL0IsVUFBQSxVQUFVO0lBQUEsT0FBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO0VBQUEsQ0FDNUMsQ0FDRCxDQUFDO0FBQ0YsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEdBQUcsWUFBVztFQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUNwQixDQUFDO0FBRUQsWUFBWSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsR0FBRyxZQUFXO0VBQ3RELElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUM1QixJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLENBQ3RDLENBQUM7RUFDRCxJQUFLLElBQUksQ0FBQyxlQUFlLEVBQUc7SUFDM0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0VBQzFDO0VBQ0EsSUFBSyxJQUFJLENBQUMsb0JBQW9CLEVBQUc7SUFDaEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7RUFDL0M7QUFDRCxDQUFDO0FBRUQsWUFBWSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEdBQUcsWUFBVztFQUNsRCxJQUFJLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFO0lBQ2pDO0VBQ0Q7RUFDQTtFQUNBLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUk7RUFDN0I7RUFDQSxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxNQUFBLE1BQUEsQ0FBTSxJQUFJLENBQUMsc0JBQXNCLFFBQUEsTUFBQSxDQUFLLElBQUksQ0FBQyxlQUFlLEdBQUcsYUFBYSxHQUFHLEVBQUUsQ0FBRSxDQUFDO0VBQ3BIO0VBQ0EsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsc0JBQXNCO0VBQ3ZDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLHNCQUFzQjtFQUMzQyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSTtFQUNsQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDbEIsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsWUFBWSxHQUFHLFlBQVc7RUFDaEQsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtJQUNuQyxPQUFPLElBQUksQ0FBQyxRQUFRO0VBQ3JCO0VBQ0EsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVM7RUFDekIsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVc7RUFDN0IsSUFBSSxTQUFTLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUM7RUFDakgsSUFBSSxRQUFRLEdBQUcsU0FBUyxJQUFJLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztFQUMvQyxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztFQUN0RyxJQUFJLGFBQWEsR0FBRyxjQUFjLElBQUksY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0VBRTlELE9BQU8sQ0FBQyxJQUFJLEdBQ1gsSUFBSSxDQUFDLElBQUksSUFDUCxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLGVBQWUsS0FBSyxRQUFRLElBQUUsSUFBSSxNQUFBLE1BQUEsQ0FBTSxJQUFJLFdBQUEsTUFBQSxDQUFRLE1BQU0sRUFBQSxNQUFBLENBQUcsUUFBUSxJQUFFLEVBQUUsSUFBSyxFQUFFLENBQUUsSUFDaEgsSUFBSSxDQUFDLG9CQUFvQixJQUFJLGFBQWEsSUFBRSxJQUFJLE1BQUEsTUFBQSxDQUFNLElBQUksZ0JBQUEsTUFBQSxDQUFhLE1BQU0sRUFBQSxNQUFBLENBQUcsYUFBYSxJQUFFLEVBQUUsSUFBSyxFQUFFLENBQUUsR0FDNUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQ3BDLEdBQUcsQ0FBQyxVQUFBLFNBQVM7SUFBQSxPQUFJLFNBQVMsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQztFQUFBLEVBQUMsQ0FDdEQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUNWLElBQUksQ0FBQyxjQUFjLEVBQ2xCLE9BQU8sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRUQsWUFBWSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEdBQUcsVUFBUyxLQUFLLEVBQUU7RUFDdkQsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLO0VBQ3hCLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUU7SUFDckMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0VBQ3RCO0VBQ0EsSUFBSSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDO0FBQ3pDLENBQUM7QUFBQyxJQUFBLFFBQUEsR0FBQSxPQUFBLGNBRWEsWUFBWSxFQUMzQjs7Ozs7Ozs7O0FDNWZBOztBQUVBLFNBQVMsdUJBQXVCLENBQUUsTUFBTSxFQUFHO0VBQzFDO0VBQ0EsTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDakIsUUFBUSxFQUFFLENBQUMsQ0FBQywrQ0FBK0M7RUFDNUQsQ0FBQyxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUUsQ0FBQzs7RUFFakI7RUFDQSx1QkFBdUIsU0FBTSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUUsTUFBTyxDQUFDO0VBRWxELElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVE7RUFDL0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsK0JBQStCLENBQUM7O0VBRXZEO0VBQ0EsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLFVBQVU7RUFDckMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFFO0lBQzNDLElBQUksRUFBRSxPQUFPO0lBQ2IsS0FBSyxFQUFFLHFCQUFxQjtJQUM1QixLQUFLLEVBQUUsYUFBYTtJQUNwQixRQUFRLEVBQUUsQ0FBQyxDQUFDLDZFQUE2RTtFQUMxRixDQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUMzQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLE1BQU0sQ0FDN0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUNyQixDQUFDOztFQUVEO0VBQ0EsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO0lBQ3ZCLFFBQVEsRUFBRSxzQkFBc0I7SUFDaEMsUUFBUSxFQUFFO0VBQ1gsQ0FBQyxDQUFDO0FBQ0g7QUFDQSxFQUFFLENBQUMsWUFBWSxDQUFFLHVCQUF1QixFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsY0FBZSxDQUFDO0FBRWhFLHVCQUF1QixDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsVUFBUyxXQUFXLEVBQUU7RUFDdkUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztFQUN6QyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUN0RCxRQUFRLEVBQUUsV0FBVyxHQUFHLGlCQUFpQixHQUFHO0VBQzdDLENBQUMsQ0FBQztFQUNGLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLFdBQVc7QUFDaEMsQ0FBQztBQUVELHVCQUF1QixDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsR0FBRyxZQUFXO0VBQ25FLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDO0VBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ3BCLENBQUM7QUFFRCx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEdBQUcsWUFBVztFQUNuRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUNwQixDQUFDO0FBRUQsdUJBQXVCLENBQUMsU0FBUyxDQUFDLFFBQVEsR0FBRyxZQUFXO0VBQ3ZELElBQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztFQUNqRCxPQUFPLFlBQVksSUFBSSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDOUMsQ0FBQztBQUFDLElBQUEsUUFBQSxHQUFBLE9BQUEsY0FFYSx1QkFBdUIsRUFDdEM7Ozs7Ozs7Ozs7Ozs7OztBQ3pEQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsc0JBQXNCLENBQUUsTUFBTSxFQUFHO0VBQ3pDO0VBQ0EsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLENBQUM7RUFDckI7RUFDQSxzQkFBc0IsU0FBTSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUUsQ0FBQyxDQUFFLENBQUM7RUFFN0MsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUEsYUFBQSxDQUFBLGFBQUEsS0FDcEMsTUFBTTtJQUNULFFBQVEsRUFBRSxJQUFJLENBQUM7RUFBUSxFQUN2QixDQUFDO0FBRUg7QUFDQSxFQUFFLENBQUMsWUFBWSxDQUFFLHNCQUFzQixFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTyxDQUFDO0FBQUMsSUFBQSxRQUFBLEdBQUEsT0FBQSxjQUV6QyxzQkFBc0IsRUFDckM7Ozs7Ozs7OztBQ3hCQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxtQkFBbUIsR0FBRyxTQUFTLG1CQUFtQixDQUFFLE1BQU0sRUFBRztFQUNoRSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQzs7RUFFckI7RUFDQSxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFFLElBQUksRUFBRSxNQUFPLENBQUM7RUFDL0MsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUU7SUFDcEMsTUFBTSxFQUFFLElBQUksQ0FBQztFQUNkLENBQUUsQ0FBQztFQUNILElBQUksQ0FBQyxRQUFRLENBQUUsTUFBTSxDQUFDLEtBQU0sQ0FBQztFQUU3QixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQztFQUVuRCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXOztFQUVyQztFQUNBO0VBQ0E7RUFDQSxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLHdCQUF3QixHQUFHLENBQUM7RUFDaEUsSUFBSSxZQUFZLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsWUFBWSxFQUFHO0lBQ3RELElBQUksY0FBYyxHQUFHLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN2QyxJQUFJLGFBQWEsR0FBRyxjQUFjLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDeEMsSUFBSSxXQUFXLEdBQUcsQ0FBQztJQUNuQixLQUFLLElBQUksQ0FBQyxHQUFHLGFBQWEsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7TUFDdkQsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxFQUFFO1FBQUU7UUFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQzNCLFdBQVcsRUFBRTtNQUNkO0lBQ0Q7SUFDQSxJQUFJLFdBQVcsR0FBQyxDQUFDLEVBQUU7TUFDbEI7TUFDQSxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQztRQUN0RCxLQUFLLEVBQUUsT0FBTyxHQUFHLFdBQVcsR0FBRyxRQUFRLElBQUksV0FBVyxLQUFHLENBQUMsR0FBRyxXQUFXLEdBQUcsWUFBWSxDQUFDO1FBQ3hGLE1BQU0sRUFBRSxLQUFLO1FBQ2IsUUFBUSxFQUFFLENBQUMsQ0FBQyxnQ0FBZ0M7TUFDN0MsQ0FBQyxDQUFDO01BQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQy9DO0VBQ0Q7O0VBRUE7RUFDQSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQztJQUNqRCxLQUFLLEVBQUUsZUFBZTtJQUN0QixJQUFJLEVBQUUsS0FBSztJQUNYLE1BQU0sRUFBRSxLQUFLO0lBQ2IsUUFBUSxFQUFFLENBQUMsQ0FBQyxnQ0FBZ0M7RUFDN0MsQ0FBQyxDQUFDO0VBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDOztFQUV6Qzs7RUFFQTtFQUNBLElBQUksQ0FBQyxTQUFTLENBQUU7SUFBRSxVQUFRO0VBQWtCLENBQUUsQ0FBQztFQUMvQyxJQUFJLENBQUMsT0FBTyxDQUFFLElBQUksRUFBRTtJQUFFLGVBQWUsRUFBRTtFQUFvQixDQUFFLENBQUM7O0VBRTlEO0VBQ0EsSUFBSSxDQUFDLFNBQVMsQ0FBRTtJQUFFLE1BQU0sRUFBRTtFQUFrQixDQUFFLENBQUM7RUFDL0MsSUFBSSxDQUFDLE9BQU8sQ0FBRSxJQUFJLEVBQUU7SUFBRSxlQUFlLEVBQUU7RUFBb0IsQ0FBRSxDQUFDOztFQUU5RDtFQUNBLElBQUksQ0FBQyxTQUFTLENBQUU7SUFBQyxhQUFhLEVBQUU7RUFBc0IsQ0FBRSxDQUFDO0VBQ3pELElBQUksQ0FBQyxPQUFPLENBQUUsSUFBSSxFQUFFO0lBQUMsc0JBQXNCLEVBQUU7RUFBZSxDQUFFLENBQUM7O0VBRS9EO0VBQ0EsSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUc7SUFDbkMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBRSxJQUFJLEVBQUU7TUFBRSxPQUFPLEVBQUU7SUFBa0MsQ0FBRSxDQUFDO0VBQzlGO0VBQ0EsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBRSxJQUFJLEVBQUU7SUFBRSxPQUFPLEVBQUU7RUFBNkIsQ0FBRSxDQUFDO0FBQ3BGLENBQUM7QUFFRCxFQUFFLENBQUMsWUFBWSxDQUFFLG1CQUFtQixFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTyxDQUFDO0FBQ3BELEVBQUUsQ0FBQyxVQUFVLENBQUUsbUJBQW1CLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBYSxDQUFDO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxZQUFXO0VBQ3hEO0VBQ0EsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7QUFDekIsQ0FBQztBQUVELG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsVUFBVyxLQUFLLEVBQUUsS0FBSyxFQUFHO0VBQ2xFLElBQUssS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUc7SUFDekIsT0FBTyxJQUFJO0VBQ1o7O0VBRUE7RUFDQSxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFNLENBQUM7O0VBRXRFO0VBQ0EsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0VBRXBCLE9BQU8sSUFBSTtBQUNaLENBQUM7QUFFRCxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEdBQUcsVUFBUyxTQUFTLEVBQUU7RUFDckUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0VBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEdBQUcsWUFBVztFQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUNwQixDQUFDO0FBRUQsbUJBQW1CLENBQUMsU0FBUyxDQUFDLGlCQUFpQixHQUFHLFlBQVc7RUFDNUQsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFBLElBQUk7SUFBQSxPQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxLQUFLLGlCQUFpQjtFQUFBLEVBQUM7QUFDOUUsQ0FBQztBQUVELG1CQUFtQixDQUFDLFNBQVMsQ0FBQywrQkFBK0IsR0FBRyxZQUFXO0VBQzFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQztFQUNqRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFBLGVBQWU7SUFBQSxPQUFJLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0VBQUEsRUFBQztFQUNuRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDckIsQ0FBQztBQUVELG1CQUFtQixDQUFDLFNBQVMsQ0FBQywwQkFBMEIsR0FBRyxZQUFXO0VBQ3JFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztFQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDO0FBQ3RDLENBQUM7QUFFRCxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsWUFBWSxHQUFHLFVBQVMsU0FBUyxFQUFFLFdBQVcsRUFBRTtFQUM3RSxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQzdCLEdBQUcsQ0FBQyxVQUFBLFNBQVM7SUFBQSxPQUFJLFNBQVMsQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQztFQUFBLEVBQUMsQ0FDaEUsSUFBSSxDQUFDLEVBQUUsQ0FBQztBQUNYLENBQUM7QUFFRCxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsY0FBYyxHQUFHLFVBQVMsS0FBSyxFQUFFO0VBQzlELElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSztFQUN4QixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztFQUNyQztFQUNBO0VBQ0EsSUFBSyxNQUFNLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsd0JBQXdCLEVBQUc7SUFDakU7RUFDRDtFQUNBLElBQUksWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBQSxLQUFLO0lBQUEsT0FBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztFQUFBLEVBQUM7RUFDN0QsSUFBSSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxNQUFNO0VBQzVELElBQ0MsWUFBWSxLQUFLLENBQUMsSUFDWixrQkFBa0IsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLHdCQUF3QixFQUNwRTtJQUNEO0VBQ0Q7RUFDQSxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLHdCQUF3QixHQUFHLGtCQUFrQixFQUM5RCxZQUFZLENBQUMsTUFDZCxDQUFDO0VBQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUNyQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztFQUM3QjtFQUNBLElBQUksZ0JBQWdCLEdBQUcsWUFBWSxDQUFDLE1BQU0sR0FBRyxXQUFXO0VBQ3hELElBQUksZ0JBQWdCLEtBQUssQ0FBQyxFQUFFO0lBQzNCLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQztFQUNsRCxDQUFDLE1BQU07SUFDTixJQUFJLENBQUMsd0JBQXdCLENBQUMsUUFBUSxDQUNyQyxPQUFPLEdBQUcsZ0JBQWdCLEdBQUcsUUFBUSxJQUFJLGdCQUFnQixLQUFHLENBQUMsR0FBRyxVQUFVLEdBQUcsV0FBVyxDQUN6RixDQUFDO0VBQ0Y7QUFDRCxDQUFDO0FBQUMsSUFBQSxRQUFBLEdBQUEsT0FBQSxjQUVhLG1CQUFtQixFQUNsQzs7Ozs7Ozs7O0FDMUtBLElBQUEsS0FBQSxHQUFBLE9BQUE7QUFDQSxJQUFBLHVCQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQThELFNBQUEsdUJBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxHQUFBLENBQUEsZ0JBQUEsQ0FBQTtBQUM5RDs7QUFFQSxTQUFTLGVBQWUsQ0FBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRztFQUN4RDtFQUNBLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDO0VBQ3JCO0VBQ0EsZUFBZSxTQUFNLENBQUMsSUFBSSxDQUFFLElBQUksRUFBRSxNQUFPLENBQUM7RUFDMUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUTtFQUUvQixJQUFJLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxJQUFJO0VBQzFCLElBQUksQ0FBQyxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUs7RUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsVUFBVTtFQUN0QyxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSTtFQUN4QyxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsSUFBSSxDQUFDLENBQUM7RUFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsSUFBSSxFQUFFO0VBQ3ZELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRO0VBQ3pDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTOztFQUUzQztFQUNBLFFBQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNO0lBQUk7SUFDcEMsS0FBSyxDQUFDO01BQ0wsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJO0lBQzVCO0lBQ0QsS0FBSyxDQUFDO01BQ0wsSUFBSSxpQkFBaUIsR0FDcEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUUsU0FBUyxDQUFDLEtBQU0sQ0FBQyxLQUFLLENBQUMsSUFDbEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsb0JBQWMsQ0FBQyxDQUFDLE9BQU8sQ0FBRSxJQUFBLG9CQUFjLEVBQUMsU0FBUyxDQUFDLEtBQUssQ0FBRSxDQUFDLEtBQUssQ0FDdkY7TUFDRCxJQUFJLGtCQUFrQixHQUNyQixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBRSxTQUFTLENBQUMsS0FBSyxJQUFJLElBQUssQ0FBQyxLQUFLLENBQUMsSUFDMUQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsb0JBQWMsQ0FBQyxDQUFDLE9BQU8sQ0FBRSxTQUFTLENBQUMsS0FBSyxHQUFHLElBQUEsb0JBQWMsRUFBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDL0c7TUFDRCxJQUFJLGVBQWUsR0FBRyxDQUFDLGlCQUFpQixJQUFJLENBQUMsa0JBQWtCO01BQy9ELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFFO1FBQzlDLFFBQVEsRUFBRSxlQUFlLEdBQUcsU0FBUyxHQUFHLGlCQUFpQjtRQUN6RCxhQUFhLEVBQUUsZUFBZSxHQUFHLElBQUksR0FBRyxTQUFTO1FBQ2pELFFBQVEsRUFBRSxDQUFDLENBQUMsa0NBQWtDO01BQy9DLENBQUUsQ0FBQztNQUNIO0lBQ0Q7SUFDRTtFQUNGLENBQUMsQ0FBQzs7RUFFRjs7RUFFQSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBRTtJQUMzQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7SUFDakI7SUFDQTtJQUNBLE9BQU8sRUFBRSxJQUFBLGtCQUFZLEVBQ3BCLElBQUksQ0FBQyxhQUFhLEVBQ2xCLFVBQUEsR0FBRztNQUFBLE9BQUksR0FBRyxLQUFHLElBQUk7SUFBQSxHQUNqQixVQUFBLEdBQUc7TUFBQSxPQUFLO1FBQUMsSUFBSSxFQUFFLEdBQUc7UUFBRSxLQUFLLEVBQUM7TUFBRyxDQUFDO0lBQUEsQ0FDL0IsQ0FBQztJQUNELFFBQVEsRUFBRSxDQUFDLENBQUMsZ0NBQWdDLENBQUM7SUFDN0MsUUFBUSxFQUFFLElBQUksQ0FBQztFQUNoQixDQUFFLENBQUM7RUFDSDtFQUNBLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDckMsYUFBYSxFQUFFLENBQUM7SUFDaEIsZ0JBQWdCLEVBQUUsS0FBSztJQUN2QixRQUFRLEVBQUU7RUFDWCxDQUFDLENBQUM7RUFDRjtFQUNBLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUFDLGFBQWEsRUFBRTtFQUFRLENBQUMsQ0FBQztFQUN4RjtFQUNBLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUM1RCxhQUFhLEVBQUUsQ0FBQztJQUNoQixRQUFRLEVBQUUsTUFBTTtJQUNoQixZQUFZLEVBQUU7RUFDZixDQUFDLENBQUM7RUFFRixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUM7SUFDM0MsSUFBSSxFQUFFLE9BQU87SUFDYixLQUFLLEVBQUUsTUFBTTtJQUNiLE1BQU0sRUFBRSxLQUFLO0lBQ2IsS0FBSyxFQUFFLGFBQWE7SUFDcEIsUUFBUSxFQUFFLENBQUMsQ0FBQywrQkFBK0I7RUFDNUMsQ0FBQyxDQUFDO0VBRUYsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDO0lBQzFDLElBQUksRUFBRSxNQUFNO0lBQ1osS0FBSyxFQUFFLFFBQVE7SUFDZixNQUFNLEVBQUU7RUFDVCxDQUFDLENBQUM7RUFFRixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUM7SUFDMUMsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxHQUFHLE9BQU87SUFDM0MsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLEdBQUcsb0JBQW9CLEdBQUcsUUFBUTtJQUN4RCxNQUFNLEVBQUUsS0FBSztJQUNiLEtBQUssRUFBRSxhQUFhO0lBQ3BCLFFBQVEsRUFBRSxJQUFJLENBQUM7RUFDaEIsQ0FBQyxDQUFDO0VBRUYsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQztJQUNyRCxLQUFLLEVBQUUsQ0FDTixJQUFJLENBQUMsYUFBYSxFQUNsQixJQUFJLENBQUMsWUFBWSxFQUNqQixJQUFJLENBQUMsWUFBWSxDQUNqQjtJQUNELFFBQVEsRUFBRSxDQUFDLENBQUMsOEJBQThCO0VBQzNDLENBQUMsQ0FBQztFQUNGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsR0FBRyxDQUFDO0lBQy9ELFdBQVcsRUFBRSxPQUFPO0lBQ3BCLE9BQU8sRUFBRSxNQUFNO0lBQ2YsY0FBYyxFQUFFO0VBQ2pCLENBQUMsQ0FBQztFQUVGLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLGtDQUFzQixDQUFDO0lBQ3BELEtBQUssRUFBRSxDQUNOLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLGtCQUFrQjtJQUV4QjtFQUNELENBQUMsQ0FBQztFQUVGLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBRSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7SUFDakUsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSTtJQUN2QixLQUFLLEVBQUUsS0FBSztJQUNaLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksS0FBSztJQUMxRSxVQUFVLEVBQUU7RUFDYixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztFQUNYLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUFDLFFBQVEsRUFBRTtFQUFrQixDQUFDLENBQUM7O0VBRTVGOztFQUVBLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBRTtJQUN4QyxJQUFJLEVBQUUsT0FBTztJQUNiLEtBQUssRUFBRSx3Q0FBd0M7SUFDL0MsS0FBSyxFQUFFLGFBQWE7SUFDcEIsUUFBUSxFQUFFLENBQUMsQ0FBQyxvRUFBb0U7RUFDakYsQ0FBRSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDMUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDO0lBQ3RDLEtBQUssRUFBQyxJQUFJLENBQUMsSUFBSSxJQUNiLElBQUksQ0FBQyxLQUFLLEdBQ1IsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQ2xCLEdBQUcsQ0FDTDtJQUNGLFFBQVEsRUFBRSxDQUFDLENBQUMsNEJBQTRCO0VBQ3pDLENBQUMsQ0FBQztFQUNGLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBRTtJQUMzQyxJQUFJLEVBQUUsT0FBTztJQUNiLEtBQUssRUFBRSxxQkFBcUI7SUFDNUIsS0FBSyxFQUFFLGFBQWE7SUFDcEIsUUFBUSxFQUFFLENBQUMsQ0FBQyxrRUFBa0U7RUFDL0UsQ0FBRSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7RUFDM0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDO0lBQ3hDLElBQUksRUFBRSxNQUFNO0lBQ1osTUFBTSxFQUFFLEtBQUs7SUFDYixRQUFRLEVBQUUsQ0FBQyxDQUFDLGtDQUFrQztFQUMvQyxDQUFDLENBQUM7RUFDRixJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQ3RDLGVBQWUsRUFBRSxlQUFlO0lBQ2hDLGFBQWEsRUFBRTtFQUNoQixDQUFDLENBQUM7RUFDRixJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDbkQsV0FBVyxFQUFFLE9BQU87SUFDcEIsT0FBTyxFQUFFO0VBQ1YsQ0FBQyxDQUFDO0VBRUYsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLENBQUM7SUFDNUMsS0FBSyxFQUFFLENBQ04sSUFBSSxDQUFDLFdBQVcsRUFDaEIsSUFBSSxDQUFDLFNBQVMsRUFDZCxJQUFJLENBQUMsY0FBYyxFQUNuQixJQUFJLENBQUMsVUFBVSxDQUNmO0lBQ0QsUUFBUSxFQUFFLENBQUMsQ0FBQyxzQ0FBc0M7RUFDbkQsQ0FBQyxDQUFDO0VBQ0YsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO0lBQ2xCLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztFQUM3Qzs7RUFFQTtFQUNBLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUMxRCxHQUFHLENBQUM7SUFDSixPQUFPLEVBQUUsT0FBTztJQUNoQixTQUFTLEVBQUUsY0FBYztJQUN6QixRQUFRLEVBQUUsSUFBSSxDQUFDLFVBQVUsR0FBRyxpQkFBaUIsR0FBRyxnQkFBZ0I7SUFDaEUsZUFBZSxFQUFFLE1BQU07SUFDdkIsY0FBYyxFQUFFLE1BQU07SUFDdEIsUUFBUSxFQUFFLGFBQWE7SUFDdkIsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxHQUFHO0VBQzFDLENBQUMsQ0FBQyxDQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztFQUU1RCxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBRSxJQUFJLEVBQUU7SUFBRSxPQUFPLEVBQUU7RUFBYyxDQUFFLENBQUM7RUFDM0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUUsSUFBSSxFQUFFO0lBQUUsT0FBTyxFQUFFO0VBQWlCLENBQUUsQ0FBQztFQUNqRSxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBRSxJQUFJLEVBQUU7SUFBRSxPQUFPLEVBQUU7RUFBZ0IsQ0FBRSxDQUFDO0VBQy9ELElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFFLElBQUksRUFBRTtJQUFFLE9BQU8sRUFBRTtFQUFnQixDQUFFLENBQUM7RUFDL0QsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO0lBQ2xCLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtNQUFDLFFBQVEsRUFBRTtJQUFrQixDQUFFLENBQUM7RUFDN0Q7QUFDRDtBQUNBLEVBQUUsQ0FBQyxZQUFZLENBQUUsZUFBZSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTyxDQUFDO0FBRWhELGVBQWUsQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLFlBQVc7RUFDcEQ7RUFDQSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztBQUN6QixDQUFDO0FBRUQsZUFBZSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsWUFBVztFQUNsRCxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7RUFDN0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0VBQzVCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO0lBQUMsWUFBWSxFQUFFO0VBQU8sQ0FBQyxDQUFDO0VBQzFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7RUFDbEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxlQUFlLENBQUMsU0FBUyxDQUFDLGNBQWMsR0FBRyxZQUFXO0VBQ3JELElBQUksQ0FBQyxRQUFRLENBQ1osSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FDckIsQ0FBQztFQUNELElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztFQUM1QixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7RUFDN0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxlQUFlLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxZQUFXO0VBQ3BELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7RUFDL0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0VBQzVCLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztFQUM3QixJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDckIsQ0FBQztBQUVELGVBQWUsQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLFlBQVc7RUFDcEQsSUFBSSxVQUFPLENBQUMsQ0FBQztBQUNkLENBQUM7QUFFRCxlQUFlLENBQUMsU0FBUyxDQUFDLGdCQUFnQixHQUFHLFVBQVMsVUFBVSxFQUFFLGVBQWUsRUFBRTtFQUNsRixJQUFJLGVBQWUsRUFBRTtJQUNwQjtFQUNEO0VBQ0EsSUFBSSxVQUFVLEVBQUU7SUFDZixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDckMsQ0FBQyxNQUFNO0lBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO0VBQ3JDO0FBQ0QsQ0FBQztBQUVELGVBQWUsQ0FBQyxTQUFTLFVBQU8sR0FBRyxZQUFXO0VBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxlQUFlLENBQUMsU0FBUyxDQUFDLFFBQVEsR0FBRyxVQUFTLEdBQUcsRUFBRTtFQUNsRDtFQUNBLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSztFQUN2QixJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7RUFDakMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7SUFBQyxRQUFRLEVBQUU7RUFBZ0IsQ0FBQyxDQUFDOztFQUUvQztFQUNBLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRzs7RUFFaEI7RUFDQSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDOztFQUUvQjtFQUNBLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJO0VBQ25DLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7RUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7SUFBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLEdBQUc7RUFBTyxDQUFDLENBQUM7O0VBRXJFO0VBQ0EsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQ3RCLElBQUksQ0FBQyxJQUFJLElBQ1IsSUFBSSxDQUFDLEtBQUssR0FDUixLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FDbEIsRUFBRSxDQUVOLENBQUM7O0VBRUQ7RUFDQSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7SUFDbEIsSUFBSSxpQkFBaUIsR0FDcEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUUsR0FBSSxDQUFDLEtBQUssQ0FBQyxJQUN2QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxvQkFBYyxDQUFDLENBQUMsT0FBTyxDQUFFLElBQUEsb0JBQWMsRUFBQyxHQUFHLENBQUUsQ0FBQyxLQUFLLENBQzFFO0lBQ0QsSUFBSSxrQkFBa0IsR0FDckIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUUsR0FBRyxJQUFJLElBQUssQ0FBQyxLQUFLLENBQUMsSUFDL0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsb0JBQWMsQ0FBQyxDQUFDLE9BQU8sQ0FBRSxHQUFHLEdBQUcsSUFBQSxvQkFBYyxFQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQ3RGO0lBQ0QsSUFBSSxlQUFlLEdBQUcsQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLGtCQUFrQjtJQUMvRCxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUM7SUFDckQsSUFBSSxDQUFDLGVBQWUsRUFBRTtNQUNyQixJQUFJLFVBQVUsR0FBRyxpQkFBaUI7TUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQztJQUM1QztFQUNEOztFQUVBO0VBQ0EsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7QUFDcEIsQ0FBQztBQUVELGVBQWUsQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLFlBQVc7RUFDcEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJO0VBQ3RCLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztFQUNoQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztJQUFDLFFBQVEsRUFBRTtFQUFpQixDQUFDLENBQUM7QUFDakQsQ0FBQztBQUVELGVBQWUsQ0FBQyxTQUFTLENBQUMsWUFBWSxHQUFHLFVBQVMsU0FBUyxFQUFFLFdBQVcsRUFBRTtFQUN6RSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDbkIsT0FBTyxFQUFFO0VBQ1Y7RUFDQSxPQUFPLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLFdBQVcsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFFLEVBQUUsQ0FBQztBQUM5RCxDQUFDO0FBRUQsZUFBZSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsWUFBVztFQUNqRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUFDLElBQUEsUUFBQSxHQUFBLE9BQUEsY0FFYSxlQUFlLEVBQzlCOzs7Ozs7Ozs7QUN4VEEsSUFBQSxPQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQWtDLFNBQUEsdUJBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxHQUFBLENBQUEsZ0JBQUEsQ0FBQTtBQUNsQzs7QUFFQSxTQUFTLGVBQWUsQ0FBRSxNQUFNLEVBQUc7RUFDbEM7RUFDQSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQztFQUNyQjtFQUNBLGVBQWUsU0FBTSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUUsTUFBTyxDQUFDO0VBRTFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDO0VBRS9DLElBQUksQ0FBQyxNQUFNLEdBQUksSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBRTtJQUN4QyxLQUFLLEVBQUUsYUFBYTtJQUNwQixRQUFRLEVBQUUsSUFBSSxDQUFDO0VBQ2hCLENBQUUsQ0FBQztFQUVILElBQUksQ0FBQyxXQUFXLEdBQUc7SUFDbEIsV0FBVyxFQUFFO01BQ1osS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO01BQ3JDLEtBQUssRUFBRTtJQUNSLENBQUM7SUFDRCxvQkFBb0IsRUFBRTtNQUNyQixLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7TUFDckMsS0FBSyxFQUFFO0lBQ1IsQ0FBQztJQUNELHFCQUFxQixFQUFFO01BQ3RCLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxPQUFPLENBQUMsMkJBQTJCLENBQUMsQ0FBQztNQUNuRCxLQUFLLEVBQUU7SUFDUixDQUFDO0lBQ0QsaUJBQWlCLEVBQUU7TUFDbEIsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO01BQ3JDLEtBQUssRUFBRTtJQUNSLENBQUM7SUFDRCx5QkFBeUIsRUFBRztNQUMzQixLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUM7TUFDckMsS0FBSyxFQUFFO0lBQ1IsQ0FBQztJQUNELHVCQUF1QixFQUFFO01BQ3hCLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQztNQUNyQyxLQUFLLEVBQUU7SUFDUixDQUFDO0lBQ0Qsb0JBQW9CLEVBQUU7TUFDckIsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO01BQ3JDLEtBQUssRUFBRTtJQUNSLENBQUM7SUFDRCwwQkFBMEIsRUFBRTtNQUMzQixLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFFO1FBQUUsS0FBSyxFQUFFO01BQUUsQ0FBRSxDQUFDO01BQ2xELEtBQUssRUFBRTtJQUNSLENBQUM7SUFDRCxXQUFXLEVBQUU7TUFDWixLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFFO1FBQ3BDLEtBQUssRUFBRSxDQUNOLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBRTtVQUM3QixJQUFJLEVBQUUsYUFBYTtVQUNuQixLQUFLLEVBQUUsU0FBUztVQUNoQixLQUFLLEVBQUU7UUFDUixDQUFFLENBQUMsRUFDSCxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUU7VUFDN0IsSUFBSSxFQUFFLE9BQU87VUFDYixLQUFLLEVBQUUsUUFBUTtVQUNmLEtBQUssRUFBRTtRQUNSLENBQUUsQ0FBQyxFQUNILElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBRTtVQUM3QixJQUFJLEVBQUUsVUFBVTtVQUNoQixLQUFLLEVBQUUsT0FBTztVQUNkLEtBQUssRUFBRTtRQUNSLENBQUUsQ0FBQztNQUVMLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQztNQUNsQyxLQUFLLEVBQUU7SUFDUixDQUFDO0lBQ0QsWUFBWSxFQUFFO01BQ2IsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUU7UUFDOUIsS0FBSyxFQUFFLGFBQWE7UUFDcEIsS0FBSyxFQUFFLDRFQUE0RTtRQUNuRixLQUFLLEVBQUUsQ0FBQyxhQUFhO01BQ3RCLENBQUU7SUFDSDtFQUNELENBQUM7RUFFRCxLQUFLLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUc7SUFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FDcEIsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBRSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssRUFBRTtNQUN4RCxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLO01BQ3ZDLEtBQUssRUFBRTtJQUNSLENBQUUsQ0FBQyxDQUNILENBQUM7RUFDSDtFQUVBLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO0lBQUMsT0FBTyxFQUFFO0VBQW1CLENBQUMsQ0FBQztBQUNoRjtBQUNBLEVBQUUsQ0FBQyxZQUFZLENBQUUsZUFBZSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTyxDQUFDO0FBRWhELGVBQWUsQ0FBQyxTQUFTLENBQUMsYUFBYSxHQUFHLFVBQVMsS0FBSyxFQUFFO0VBQUEsSUFBQSxLQUFBO0VBQUEsSUFBQSxLQUFBLFlBQUEsTUFBQSxFQUM1QjtJQUM1QixJQUFJLEtBQUssR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQzNCLElBQUksS0FBSyxHQUFHLEtBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLO0lBQzFFLFFBQVEsS0FBSyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSTtNQUN2QyxLQUFLLHdCQUF3QjtRQUM1QixLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDO1FBQzdCO01BQ0QsS0FBSyx1QkFBdUI7TUFDNUIsS0FBSyx3QkFBd0I7UUFDNUIsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDckI7TUFDRCxLQUFLLHNDQUFzQztRQUMxQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFBLEVBQUU7VUFBQSxPQUNmLEtBQUssQ0FBQyxNQUFNLENBQ1gsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQ2IsRUFBRSxLQUFLLENBQUMsR0FDTCxRQUFRLEdBQ1Isa0JBQU0sQ0FBQyxFQUFFLENBQUMscUJBQXFCLENBQUMsRUFBRSxDQUN0QyxDQUFDO1FBQUEsQ0FDRixDQUFDO1FBQ0Q7SUFDRDtFQUNELENBQUM7RUF2QkQsS0FBSyxJQUFJLFFBQVEsSUFBSSxLQUFLO0lBQUEsS0FBQTtFQUFBO0FBd0IzQixDQUFDO0FBRUQsZUFBZSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsWUFBVztFQUMvQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7RUFDZCxLQUFLLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUc7SUFDdkMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLO0lBQzVDLElBQUksS0FBSztJQUNULFFBQVEsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJO01BQzlCLEtBQUssd0JBQXdCO1FBQzVCLEtBQUssR0FBRyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDO01BQ0QsS0FBSyx3QkFBd0I7UUFDNUIsS0FBSyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN4QjtNQUNELEtBQUssdUJBQXVCO1FBQzNCLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xDO01BQ0QsS0FBSyxzQ0FBc0M7UUFDMUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3RDO0lBQ0Q7SUFDQSxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsS0FBSztFQUN4QjtFQUNBLE9BQU8sS0FBSztBQUNiLENBQUM7QUFFRCxlQUFlLENBQUMsU0FBUyxDQUFDLGlCQUFpQixHQUFHLFlBQVc7RUFBQSxJQUFBLE1BQUE7RUFDeEQsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMseUZBQXlGLENBQUMsQ0FDdEcsSUFBSSxDQUFDLFVBQUEsU0FBUyxFQUFJO0lBQ2xCLElBQUksU0FBUyxFQUFFO01BQ2QsTUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDeEI7RUFDRCxDQUFDLENBQUM7QUFDSixDQUFDO0FBQUMsSUFBQSxRQUFBLEdBQUEsT0FBQSxjQUVhLGVBQWUsRUFDOUI7Ozs7Ozs7OztBQzFKQTs7QUFFQSxJQUFJLCtCQUErQixHQUFHLFNBQVMsK0JBQStCLENBQUUsTUFBTSxFQUFHO0VBQ3hGLEVBQUUsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUUsTUFBTyxDQUFDO0VBQzFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLE1BQU8sQ0FBQztFQUM5QyxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxXQUFXLEdBQUcsRUFBRTtFQUM5RSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyx1Q0FBdUMsQ0FBQztBQUNoRSxDQUFDO0FBQ0QsRUFBRSxDQUFDLFlBQVksQ0FBRSwrQkFBK0IsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLGVBQWdCLENBQUM7QUFDekUsRUFBRSxDQUFDLFVBQVUsQ0FBRSwrQkFBK0IsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxhQUFjLENBQUM7O0FBRTNFO0FBQ0EsK0JBQStCLENBQUMsU0FBUyxDQUFDLGNBQWMsR0FBRyxVQUFTLFdBQVcsRUFBRTtFQUNoRixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRTtJQUNoQyxJQUFJLFdBQVcsSUFBSSxJQUFJLEVBQUU7TUFDeEIsT0FBTyxDQUFDLElBQUksQ0FBQyxpR0FBaUcsRUFBRSxXQUFXLENBQUM7SUFDN0g7SUFDQTtFQUNEO0VBQ0EsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXO0FBQy9CLENBQUM7O0FBRUQ7QUFDQSwrQkFBK0IsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEdBQUcsWUFBWTtFQUN4RSxJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7RUFDbkcsT0FBTyxRQUFRLENBQUMsT0FBTyxDQUFFO0lBQUUsS0FBSyxFQUFFLFNBQVAsS0FBSyxDQUFBLEVBQWMsQ0FBQztFQUFFLENBQUUsQ0FBQztBQUNyRCxDQUFDOztBQUVEO0FBQ0EsK0JBQStCLENBQUMsU0FBUyxDQUFDLDhCQUE4QixHQUFHLFVBQVcsUUFBUSxFQUFHO0VBQ2hHLE9BQU8sUUFBUSxJQUFJLEVBQUU7QUFDdEIsQ0FBQzs7QUFFRDtBQUNBLCtCQUErQixDQUFDLFNBQVMsQ0FBQyw0QkFBNEIsR0FBRyxVQUFXLE9BQU8sRUFBRztFQUM3RixJQUFJLG9CQUFvQixHQUFHLFNBQXZCLG9CQUFvQixDQUFZLGNBQWMsRUFBRTtJQUNuRCxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUc7RUFDNUcsQ0FBQztFQUNELElBQUksb0JBQW9CLEdBQUcsU0FBdkIsb0JBQW9CLENBQVksVUFBVSxFQUFFO0lBQy9DLE9BQU8sSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFFO01BQ2xDLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtNQUNyQixLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUssSUFBSSxVQUFVLENBQUM7SUFDdkMsQ0FBRSxDQUFDO0VBQ0osQ0FBQztFQUNELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7QUFDL0UsQ0FBQzs7QUFFRDtBQUNBLCtCQUErQixDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsR0FBRyxVQUFXLElBQUksRUFBRztFQUNoRjtFQUNBLElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztFQUMvQjtFQUNBLElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUU7SUFDOUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO0VBQzVCO0VBQ0E7RUFDQSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0VBQ2xCLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUM7RUFDdkUsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUyxDQUFDO0FBQy9CLENBQUM7QUFBQyxJQUFBLFFBQUEsR0FBQSxPQUFBLGNBRWEsK0JBQStCLEVBQzlDOzs7Ozs7Ozs7QUM5REEsSUFBQSxPQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxnQ0FBQSxHQUFBLHNCQUFBLENBQUEsT0FBQTtBQUNBLElBQUEsV0FBQSxHQUFBLE9BQUE7QUFBZ0QsU0FBQSx1QkFBQSxDQUFBLFdBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxVQUFBLEdBQUEsQ0FBQSxnQkFBQSxDQUFBO0FBQUEsU0FBQSxtQkFBQSxDQUFBLFdBQUEsa0JBQUEsQ0FBQSxDQUFBLEtBQUEsZ0JBQUEsQ0FBQSxDQUFBLEtBQUEsMkJBQUEsQ0FBQSxDQUFBLEtBQUEsa0JBQUE7QUFBQSxTQUFBLG1CQUFBLGNBQUEsU0FBQTtBQUFBLFNBQUEsNEJBQUEsQ0FBQSxFQUFBLENBQUEsUUFBQSxDQUFBLDJCQUFBLENBQUEsU0FBQSxpQkFBQSxDQUFBLENBQUEsRUFBQSxDQUFBLE9BQUEsQ0FBQSxNQUFBLFFBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLEtBQUEsNkJBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxXQUFBLEtBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxhQUFBLENBQUEsY0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLG9CQUFBLENBQUEsK0NBQUEsSUFBQSxDQUFBLENBQUEsSUFBQSxpQkFBQSxDQUFBLENBQUEsRUFBQSxDQUFBO0FBQUEsU0FBQSxpQkFBQSxDQUFBLDhCQUFBLE1BQUEsWUFBQSxDQUFBLENBQUEsTUFBQSxDQUFBLFFBQUEsYUFBQSxDQUFBLHVCQUFBLEtBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQTtBQUFBLFNBQUEsbUJBQUEsQ0FBQSxRQUFBLEtBQUEsQ0FBQSxPQUFBLENBQUEsQ0FBQSxVQUFBLGlCQUFBLENBQUEsQ0FBQTtBQUFBLFNBQUEsa0JBQUEsQ0FBQSxFQUFBLENBQUEsYUFBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxNQUFBLE1BQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxNQUFBLFlBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsQ0FBQSxHQUFBLENBQUEsR0FBQSxDQUFBLEVBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLENBQUEsVUFBQSxDQUFBO0FBQ2hEOztBQUVBLFNBQVMsWUFBWSxDQUFFLE1BQU0sRUFBRztFQUFBLElBQUEsS0FBQTtFQUMvQjtFQUNBLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUNoQjtJQUNDLFFBQVEsRUFBRSxLQUFLO0lBQ2YsTUFBTSxFQUFFLEtBQUs7SUFDYixNQUFNLEVBQUU7RUFDVCxDQUFDLEVBQ0QsTUFBTSxJQUFJLENBQUMsQ0FDWixDQUFDO0VBQ0Q7RUFDQSxZQUFZLFNBQU0sQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLE1BQU8sQ0FBQztFQUN2QyxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFROztFQUUvQjtFQUNBLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSwyQ0FBK0IsQ0FBRTtJQUNyRCxXQUFXLEVBQUUsc0JBQXNCO0lBQ25DLFFBQVEsRUFBRSxDQUFDLENBQUMsNkVBQTZFLENBQUM7SUFDMUYsUUFBUSxFQUFFLElBQUksQ0FBQztFQUNoQixDQUFFLENBQUM7RUFDSCxJQUFBLDBCQUFjLEVBQUMsQ0FBQyxDQUNkLElBQUksQ0FBQyxVQUFBLE9BQU87SUFBQSxVQUFBLE1BQUEsQ0FBQSxrQkFBQSxDQUNULE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFVBQUEsVUFBVTtNQUFBLE9BQUs7UUFDekMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQztRQUM3QyxJQUFJLEVBQUU7VUFDTCxJQUFJLEVBQUU7UUFDUDtNQUNELENBQUM7SUFBQSxDQUFDLENBQUMsR0FBQSxrQkFBQSxDQUNBLE9BQU8sQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFVBQUEsVUFBVTtNQUFBLE9BQUs7UUFDNUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQztRQUM3QyxJQUFJLEVBQUU7VUFDTCxJQUFJLEVBQUUsVUFBVTtVQUNoQixjQUFjLEVBQUU7UUFDakI7TUFDRCxDQUFDO0lBQUEsQ0FBQyxDQUFDLEdBQUEsa0JBQUEsQ0FDQSxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFBLFVBQVU7TUFBQSxPQUFLO1FBQ3RDLEtBQUssRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsR0FBRyxxQkFBcUI7UUFDckUsSUFBSSxFQUFFO1VBQ0wsSUFBSSxFQUFFLFVBQVU7VUFDaEIsT0FBTyxFQUFFO1FBQ1Y7TUFDRCxDQUFDO0lBQUEsQ0FBQyxDQUFDLEdBQUEsa0JBQUEsQ0FDQSxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFBLFVBQVU7TUFBQSxPQUFLO1FBQ3JDLEtBQUssRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7UUFDN0MsSUFBSSxFQUFFO1VBQ0wsSUFBSSxFQUFFO1FBQ1A7TUFDRCxDQUFDO0lBQUEsQ0FBQyxDQUFDLEdBQUEsa0JBQUEsQ0FDQSxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxVQUFBLFVBQVU7TUFBQSxPQUFLO1FBQ3RDLEtBQUssRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsR0FBRyxhQUFhO1FBQzdELElBQUksRUFBRTtVQUNMLElBQUksRUFBRSxVQUFVO1VBQ2hCLGNBQWMsRUFBRTtRQUNqQjtNQUNELENBQUM7SUFBQSxDQUFDLENBQUMsR0FBQSxrQkFBQSxDQUNBLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQUEsVUFBVTtNQUFBLE9BQUs7UUFDakMsS0FBSyxFQUFFLFVBQVUsR0FBRyxtQ0FBbUM7UUFDdkQsSUFBSSxFQUFFO1VBQ0wsSUFBSSxFQUFFLFVBQVU7VUFDaEIsY0FBYyxFQUFFO1FBQ2pCO01BQ0QsQ0FBQztJQUFBLENBQUMsQ0FBQztFQUFBLENBQ0gsQ0FBQyxDQUNELElBQUksQ0FBQyxVQUFBLGFBQWE7SUFBQSxPQUFJLEtBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQztFQUFBLEVBQUM7O0VBRXJFO0VBQ0EsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFFO0lBQzlDLElBQUksRUFBRSxLQUFLO0lBQ1gsS0FBSyxFQUFFLEtBQUs7SUFDWixLQUFLLEVBQUUsYUFBYTtJQUNwQixRQUFRLEVBQUUsQ0FBQyxDQUFDLG9FQUFvRTtFQUNqRixDQUFFLENBQUM7RUFDSCxJQUFJLGdCQUFnQixHQUFHLENBQUMsQ0FBQywrRkFBK0YsQ0FBQyxDQUN2SCxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUM7O0VBRWhFO0VBQ0E7RUFDQSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxjQUFjLENBQUU7SUFDL0MsSUFBSSxFQUFFLEtBQUs7SUFDWCxLQUFLLEVBQUUsWUFBWTtJQUNuQixjQUFjLEVBQUUsSUFBSTtJQUNwQixJQUFJLEVBQUU7TUFDTCxLQUFLLEdBQ0osSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLHVCQUF1QixDQUFFO1FBQ2xDLEtBQUssRUFBRTtNQUNSLENBQUUsQ0FBQyxFQUNILElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBRTtRQUMzQixJQUFJLEVBQUU7VUFBQyxTQUFPO1FBQUksQ0FBQztRQUNuQixLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyw4Q0FBOEM7TUFDNUUsQ0FBRSxDQUFDLEVBQUEsTUFBQSxDQUFBLGtCQUFBLENBQ0Esa0JBQVMsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFBLFNBQVM7UUFBQSxPQUFJLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBRTtVQUNoRixJQUFJLEVBQUU7WUFBQyxTQUFPO1VBQVMsQ0FBQztVQUN4QixLQUFLLEVBQUU7UUFDUixDQUFFLENBQUM7TUFBQSxDQUNILENBQUMsSUFDRCxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsdUJBQXVCLENBQUU7UUFDbEMsS0FBSyxFQUFFO01BQ1IsQ0FBRSxDQUFDLEVBQ0gsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFFO1FBQzNCLElBQUksRUFBRTtVQUFDLFVBQVUsRUFBRTtRQUFJLENBQUM7UUFDeEIsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsbURBQW1EO01BQ2pGLENBQUUsQ0FBQyxHQUFBLGtCQUFBLENBQ0Esa0JBQVMsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxVQUFBLFVBQVU7UUFBQSxPQUFJLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBRTtVQUNyRixJQUFJLEVBQUU7WUFBQyxVQUFVLEVBQUU7VUFBVSxDQUFDO1VBQzlCLEtBQUssRUFBRTtRQUNSLENBQUUsQ0FBQztNQUFBLENBQ0gsQ0FBQztJQUVILENBQUM7SUFDRCxRQUFRLEVBQUUsQ0FBQyxDQUFDLHlGQUF5RixDQUFDO0lBQ3RHLFFBQVEsRUFBRSxJQUFJLENBQUM7RUFDaEIsQ0FBRSxDQUFDOztFQUVIO0VBQ0EsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFFO0lBQzlDLElBQUksRUFBRSxPQUFPO0lBQ2IsS0FBSyxFQUFFLFlBQVk7SUFDbkIsS0FBSyxFQUFFO0VBQ1IsQ0FBRSxDQUFDOztFQUVIO0VBQ0EsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFFO0lBQzdDLElBQUksRUFBRSxRQUFRO0lBQ2QsS0FBSyxFQUFFLFdBQVc7SUFDbEIsS0FBSyxFQUFFO0VBQ1IsQ0FBRSxDQUFDOztFQUVIO0VBQ0EsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsaUJBQWlCLENBQUU7SUFDL0MsS0FBSyxFQUFFLENBQ04sSUFBSSxDQUFDLGVBQWUsRUFDcEIsSUFBSSxDQUFDLGNBQWMsQ0FDbkI7SUFDRCxRQUFRLEVBQUUsQ0FBQyxDQUFDLCtCQUErQjtFQUM1QyxDQUFFLENBQUM7RUFDSDtFQUNBLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQzs7RUFFL0Q7RUFDQSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUMxQyxHQUFHLENBQUM7SUFDSixVQUFVLEVBQUUsT0FBTztJQUNuQixPQUFPLEVBQUUsTUFBTTtJQUNmLFlBQVksRUFBRSxNQUFNO0lBQ3BCLFNBQVMsRUFBRSxNQUFNO0lBQ2pCLFdBQVcsRUFBRSxNQUFNO0lBQ25CLGlCQUFpQixFQUFFLGNBQWM7SUFDakMsUUFBUSxFQUFFO0VBQ1gsQ0FBQyxDQUFDLENBQ0QsTUFBTSxDQUNOLGdCQUFnQixFQUNoQixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQ2xCLENBQUM7O0VBRUY7O0VBRUEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO0lBQzVCLE9BQU8sRUFBRSxnQkFBZ0I7SUFDekIsUUFBUSxFQUFFO0VBQ1gsQ0FBQyxDQUFDO0VBQ0YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO0lBQUMsT0FBTyxFQUFFO0VBQWdCLENBQUMsQ0FBQztFQUMvRCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtJQUFDLFFBQVEsRUFBRTtFQUFnQixDQUFDLENBQUM7RUFDekUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO0lBQUMsT0FBTyxFQUFFO0VBQWtCLENBQUMsQ0FBQztFQUNqRSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7SUFBQyxPQUFPLEVBQUU7RUFBaUIsQ0FBQyxDQUFDO0FBQ2hFO0FBQ0EsRUFBRSxDQUFDLFlBQVksQ0FBRSxZQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFZLENBQUM7QUFFbEQsWUFBWSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEdBQUcsVUFBUyxJQUFJLEVBQUU7RUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDO0FBQ2hDLENBQUM7QUFFRCxZQUFZLENBQUMsU0FBUyxDQUFDLGNBQWMsR0FBRyxVQUFTLElBQUksRUFBRTtFQUN0RCxJQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7RUFDM0IsSUFBSSxJQUFJLFNBQU0sSUFBSSxJQUFJLFNBQU0sS0FBRyxJQUFJLEVBQUU7SUFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxTQUFNLENBQUM7RUFDcEM7RUFDQSxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBRyxJQUFJLEVBQUU7SUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDO0VBQzdDO0FBQ0QsQ0FBQztBQUVELFlBQVksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEdBQUcsWUFBVztFQUNwRCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztBQUN2QixDQUFDO0FBRUQsWUFBWSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsWUFBVztFQUNuRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztBQUN0QixDQUFDO0FBRUQsWUFBWSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEdBQUcsVUFBUyxPQUFPLEVBQUU7RUFDdEQsQ0FDQyxJQUFJLENBQUMsU0FBUyxFQUNkLElBQUksQ0FBQyxlQUFlLEVBQ3BCLElBQUksQ0FBQyxjQUFjLEVBQ25CLElBQUksQ0FBQyxlQUFlLEVBQ3BCLElBQUksQ0FBQyxjQUFjLENBQ25CLENBQUMsT0FBTyxDQUFDLFVBQUEsTUFBTTtJQUFBLE9BQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUM7RUFBQSxFQUFDO0FBQ2pELENBQUM7QUFBQyxJQUFBLFFBQUEsR0FBQSxPQUFBLGNBRWEsWUFBWSxFQUMzQjs7Ozs7Ozs7O0FDN01BLElBQUEsSUFBQSxHQUFBLE9BQUE7QUFBc0MsU0FBQSxtQkFBQSxDQUFBLFdBQUEsa0JBQUEsQ0FBQSxDQUFBLEtBQUEsZ0JBQUEsQ0FBQSxDQUFBLEtBQUEsMkJBQUEsQ0FBQSxDQUFBLEtBQUEsa0JBQUE7QUFBQSxTQUFBLG1CQUFBLGNBQUEsU0FBQTtBQUFBLFNBQUEsNEJBQUEsQ0FBQSxFQUFBLENBQUEsUUFBQSxDQUFBLDJCQUFBLENBQUEsU0FBQSxpQkFBQSxDQUFBLENBQUEsRUFBQSxDQUFBLE9BQUEsQ0FBQSxNQUFBLFFBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLEtBQUEsNkJBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxXQUFBLEtBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxhQUFBLENBQUEsY0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLG9CQUFBLENBQUEsK0NBQUEsSUFBQSxDQUFBLENBQUEsSUFBQSxpQkFBQSxDQUFBLENBQUEsRUFBQSxDQUFBO0FBQUEsU0FBQSxpQkFBQSxDQUFBLDhCQUFBLE1BQUEsWUFBQSxDQUFBLENBQUEsTUFBQSxDQUFBLFFBQUEsYUFBQSxDQUFBLHVCQUFBLEtBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQTtBQUFBLFNBQUEsbUJBQUEsQ0FBQSxRQUFBLEtBQUEsQ0FBQSxPQUFBLENBQUEsQ0FBQSxVQUFBLGlCQUFBLENBQUEsQ0FBQTtBQUFBLFNBQUEsa0JBQUEsQ0FBQSxFQUFBLENBQUEsYUFBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxNQUFBLE1BQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxNQUFBLFlBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsQ0FBQSxHQUFBLENBQUEsR0FBQSxDQUFBLEVBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLENBQUEsVUFBQSxDQUFBO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsSUFBSSxVQUFVLEdBQUcsU0FBUyxVQUFVLENBQUUsTUFBTSxFQUFHO0VBQzlDLFVBQVUsU0FBTSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUUsTUFBTyxDQUFDO0FBQ3RDLENBQUM7QUFDRCxFQUFFLENBQUMsWUFBWSxDQUFFLFVBQVUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU8sQ0FBQztBQUUzQyxVQUFVLFVBQU8sQ0FBQyxJQUFJLEdBQUcsWUFBWTtBQUNyQyxVQUFVLFVBQU8sQ0FBQyxLQUFLLEdBQUcsa0JBQWtCOztBQUU1QztBQUNBLFVBQVUsQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLFlBQVk7RUFBQSxJQUFBLHFCQUFBO0VBQzdDO0VBQ0EsVUFBVSxTQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUUsSUFBSyxDQUFDO0VBQ2xEO0VBQ0EsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFFO0lBQ3JDLE1BQU0sRUFBRSxJQUFJO0lBQ1osUUFBUSxFQUFFO0VBQ1gsQ0FBRSxDQUFDO0VBQ0g7RUFDQSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBRTtJQUMvQyxRQUFRLEVBQUU7RUFDWCxDQUFFLENBQUM7RUFDSCxJQUFJLENBQUMsVUFBVSxHQUFHLENBQ2pCLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUU7SUFDdEIsS0FBSyxFQUFFLG1DQUFtQztJQUMxQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLDZCQUE2QjtFQUMxQyxDQUFDLENBQUMsRUFDRixJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFFO0lBQ3RCLEtBQUssRUFBRSxvQ0FBb0M7SUFDM0MsUUFBUSxFQUFFLENBQUMsQ0FBQyw2QkFBNkI7RUFDMUMsQ0FBQyxDQUFDLEVBQ0YsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBRTtJQUN0QixLQUFLLEVBQUUsOEJBQThCO0lBQ3JDLFFBQVEsRUFBRSxDQUFDLENBQUMsNkJBQTZCO0VBQzFDLENBQUMsQ0FBQyxFQUNGLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUU7SUFDdEIsS0FBSyxFQUFFLCtCQUErQjtJQUN0QyxRQUFRLEVBQUUsQ0FBQyxDQUFDLDZCQUE2QjtFQUMxQyxDQUFDLENBQUMsRUFDRixJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFFO0lBQ3RCLEtBQUssRUFBRSxzQ0FBc0M7SUFDN0MsUUFBUSxFQUFFLENBQUMsQ0FBQyw2QkFBNkI7RUFDMUMsQ0FBQyxDQUFDLEVBQ0YsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBRTtJQUN0QixLQUFLLEVBQUUsMEJBQTBCO0lBQ2pDLFFBQVEsRUFBRSxDQUFDLENBQUMsNkJBQTZCO0VBQzFDLENBQUMsQ0FBQyxFQUNGLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUU7SUFDdEIsS0FBSyxFQUFFLGtDQUFrQztJQUN6QyxRQUFRLEVBQUUsQ0FBQyxDQUFDLDZCQUE2QjtFQUMxQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUNYO0VBQ0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFFO0lBQzFDLEtBQUssRUFBRTtFQUNSLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0VBQ1gsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFOztFQUV2QjtFQUNBLENBQUEscUJBQUEsT0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUMsTUFBTSxDQUFBLEtBQUEsQ0FBQSxxQkFBQSxHQUMzQixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDeEIsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBRTtJQUN2QixLQUFLLEVBQUUsZUFBZTtJQUN0QixRQUFRLEVBQUUsQ0FBQyxDQUFDLGtDQUFrQztFQUMvQyxDQUFDLENBQUMsQ0FBRSxRQUFRLEVBQUEsTUFBQSxDQUFBLGtCQUFBLENBQ1QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsUUFBUTtFQUFBLEVBQUMsSUFDakQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQzFCLENBQUM7O0VBRUQ7RUFDQSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVMsQ0FBQzs7RUFFMUM7RUFDQSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBRSxJQUFJLEVBQUU7SUFBRSxPQUFPLEVBQUU7RUFBcUIsQ0FBRSxDQUFDO0FBQ3BFLENBQUM7QUFFRCxVQUFVLENBQUMsU0FBUyxDQUFDLGtCQUFrQixHQUFHLFlBQVc7RUFDcEQ7RUFDQSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDYixDQUFDOztBQUVEO0FBQ0EsVUFBVSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsWUFBWTtFQUNoRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBRSxJQUFLLENBQUM7QUFDakQsQ0FBQztBQUVELFVBQVUsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEdBQUcsVUFBUyxNQUFNLEVBQUUsT0FBTyxFQUFFO0VBQ2xFLElBQUksYUFBYSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7RUFDbEQsSUFBSSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sSUFBSSxHQUFHLEVBQUUsYUFBYSxHQUFHLE1BQU0sQ0FBQztFQUMxRSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQztBQUNsRCxDQUFDO0FBRUQsVUFBVSxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsR0FBRyxVQUFTLFlBQVksRUFBRTtFQUFBLElBQUEsS0FBQTtFQUNwRSxJQUFJLFVBQVUsR0FBRyxTQUFiLFVBQVUsQ0FBRyxLQUFLLEVBQUk7SUFDekI7SUFDQSxJQUFJLE1BQU0sR0FBRyxLQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztJQUNuQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQztJQUM3QztJQUNBO0lBQ0EsSUFBSSxjQUFjLEdBQUcsR0FBRyxHQUFHLEtBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkQsSUFBSSxTQUFTLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDckIsSUFBSSxVQUFVLEdBQUcsRUFBRTtJQUNuQixJQUFJLGdCQUFnQixHQUFHLGNBQWMsR0FBRyxVQUFVO0lBRWxELEtBQU0sSUFBSSxJQUFJLEdBQUMsQ0FBQyxFQUFFLElBQUksR0FBRyxVQUFVLEVBQUUsSUFBSSxFQUFFLEVBQUU7TUFDNUMsTUFBTSxDQUFDLFVBQVUsQ0FDaEIsS0FBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFJLENBQUMsRUFDakMsU0FBUyxHQUFHLElBQUksR0FBRyxVQUFVLEVBQzdCLGdCQUNELENBQUM7SUFDRjtFQUNELENBQUM7RUFDRCxJQUFJLFdBQVcsR0FBRyxTQUFkLFdBQVcsQ0FBSSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBSztJQUN4QyxJQUFJLE1BQU0sR0FBRyxLQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztJQUNuQyxNQUFNLENBQUMsUUFBUSxDQUNkLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLFdBQVcsR0FBRyxJQUFBLGlCQUFZLEVBQUMsSUFBSSxFQUFFLElBQUksQ0FDMUQsQ0FBQztJQUNELEtBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUM3QixLQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7RUFDbEIsQ0FBQztFQUNELFlBQVksQ0FBQyxPQUFPLENBQUMsVUFBUyxPQUFPLEVBQUUsS0FBSyxFQUFFO0lBQzdDLE9BQU8sQ0FBQyxJQUFJLENBQ1g7TUFBQSxPQUFNLFVBQVUsQ0FBQyxLQUFLLENBQUM7SUFBQSxHQUN2QixVQUFDLElBQUksRUFBRSxJQUFJO01BQUEsT0FBSyxXQUFXLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUM7SUFBQSxDQUMvQyxDQUFDO0VBQ0YsQ0FBQyxDQUFDO0FBQ0gsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsVUFBVSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsVUFBVyxJQUFJLEVBQUc7RUFBQSxJQUFBLE1BQUE7RUFDeEQsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7RUFDakIsT0FBTyxVQUFVLFNBQU0sQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUUsSUFBSyxDQUFDLENBQ2xFLElBQUksQ0FBRSxZQUFNO0lBQ1osSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJO0lBQzlCLE1BQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQztJQUN2QyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3pFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO01BQUEsT0FBTSxNQUFJLENBQUMsc0JBQXNCLENBQUMsWUFBWSxDQUFDO0lBQUEsRUFBQztFQUNwRSxDQUFDLEVBQUUsSUFBSyxDQUFDO0FBQ1gsQ0FBQzs7QUFFRDtBQUNBLFVBQVUsQ0FBQyxTQUFTLENBQUMsY0FBYyxHQUFHLFVBQVcsSUFBSSxFQUFHO0VBQ3ZELElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO0VBQ2pCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtJQUNqQjtJQUNBLE9BQU8sVUFBVSxTQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLElBQUssQ0FBQyxDQUNqRSxJQUFJLENBQUMsR0FBRyxDQUFDO0VBQ1o7RUFDQTtFQUNBLE9BQU8sVUFBVSxTQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLElBQUssQ0FBQztBQUNwRSxDQUFDOztBQUVEO0FBQ0EsVUFBVSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsR0FBRyxVQUFXLElBQUksRUFBRztFQUFBLElBQUEsTUFBQTtFQUMzRCxPQUFPLFVBQVUsU0FBTSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLElBQUssQ0FBQyxDQUNyRSxLQUFLLENBQUUsWUFBTTtJQUNkO0lBQ0MsTUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUUsVUFBQSxTQUFTLEVBQUk7TUFDckMsSUFBSSxZQUFZLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO01BQ3ZDLFNBQVMsQ0FBQyxRQUFRLENBQ2pCLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUMsQ0FBQyxDQUNwRCxDQUFDO0lBQ0YsQ0FBRSxDQUFDO0VBQ0osQ0FBQyxFQUFFLElBQUssQ0FBQztBQUNYLENBQUM7QUFBQyxJQUFBLFFBQUEsR0FBQSxPQUFBLGNBRWEsVUFBVSxFQUN6Qjs7Ozs7Ozs7OztBQ3JMQSxJQUFBLGFBQUEsR0FBQSxzQkFBQSxDQUFBLE9BQUE7QUFDQSxJQUFBLGlCQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxPQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxJQUFBLEdBQUEsdUJBQUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxnQkFBQSxHQUFBLHNCQUFBLENBQUEsT0FBQTtBQUNBLElBQUEsTUFBQSxHQUFBLE9BQUE7QUFDQSxJQUFBLFNBQUEsR0FBQSxPQUFBO0FBQ0EsSUFBQSxhQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxLQUFBLEdBQUEsT0FBQTtBQUNBLElBQUEsS0FBQSxHQUFBLHVCQUFBLENBQUEsT0FBQTtBQUFrQyxTQUFBLHdCQUFBLENBQUEsRUFBQSxDQUFBLDZCQUFBLE9BQUEsTUFBQSxDQUFBLE9BQUEsT0FBQSxJQUFBLENBQUEsT0FBQSxPQUFBLFlBQUEsdUJBQUEsWUFBQSx3QkFBQSxDQUFBLEVBQUEsQ0FBQSxTQUFBLENBQUEsSUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFVBQUEsU0FBQSxDQUFBLE1BQUEsQ0FBQSxFQUFBLENBQUEsRUFBQSxDQUFBLEtBQUEsU0FBQSxtQkFBQSxDQUFBLGlCQUFBLENBQUEsZ0JBQUEsT0FBQSxDQUFBLENBQUEsMEJBQUEsQ0FBQSxTQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsQ0FBQSxHQUFBLENBQUEsR0FBQSxDQUFBLFFBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLFVBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLEVBQUEsQ0FBQSxjQUFBLEVBQUEsSUFBQSxDQUFBLGdCQUFBLEVBQUEsT0FBQSxjQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxFQUFBLE9BQUEsQ0FBQSxJQUFBLENBQUEsR0FBQSxNQUFBLENBQUEsY0FBQSxLQUFBLE1BQUEsQ0FBQSx3QkFBQSxDQUFBLENBQUEsRUFBQSxFQUFBLE9BQUEsQ0FBQSxDQUFBLEdBQUEsSUFBQSxDQUFBLENBQUEsR0FBQSxJQUFBLENBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxFQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLFdBQUEsQ0FBQSxLQUFBLENBQUEsRUFBQSxDQUFBO0FBQUEsU0FBQSx1QkFBQSxDQUFBLFdBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxVQUFBLEdBQUEsQ0FBQSxnQkFBQSxDQUFBO0FBQ2xDOztBQUVBLFNBQVMsVUFBVSxDQUFFLE1BQU0sRUFBRztFQUM3QixVQUFVLFNBQU0sQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLE1BQU8sQ0FBQztBQUN0QztBQUNBLEVBQUUsQ0FBQyxZQUFZLENBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsYUFBYyxDQUFDO0FBRWxELFVBQVUsVUFBTyxDQUFDLElBQUksR0FBRyxNQUFNO0FBQy9CLFVBQVUsVUFBTyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDO0VBQUMsYUFBYSxFQUFDO0FBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUN6RSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO0VBQUMsYUFBYSxFQUFFO0FBQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0VBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztFQUFFLFFBQVEsRUFBRTtBQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFDbEgsSUFBSSxFQUNKLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUM7RUFBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO0VBQUUsUUFBUSxFQUFFO0FBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUNwRixJQUFJLEVBQ0osQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQztFQUFDLFdBQVcsRUFBQztBQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUMsa0JBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUN2RSxDQUFDO0FBQ0QsVUFBVSxVQUFPLENBQUMsSUFBSSxHQUFHLE9BQU87QUFDaEMsVUFBVSxVQUFPLENBQUMsT0FBTyxHQUFHO0FBQzNCO0FBQ0E7RUFDQyxLQUFLLEVBQUUsR0FBRztFQUFFO0VBQ1osS0FBSyxFQUFFLGlDQUFpQztFQUN4QyxLQUFLLEVBQUUsU0FBUztFQUNoQixLQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFDRDtBQUNBO0VBQ0MsTUFBTSxFQUFFLFdBQVc7RUFDbkIsS0FBSyxFQUFFLE1BQU07RUFDYixJQUFJLEVBQUUsVUFBVTtFQUNoQixLQUFLLEVBQUUsYUFBYTtFQUNwQixLQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFDRDtBQUNBO0VBQ0MsTUFBTSxFQUFFLE1BQU07RUFDZCxTQUFTLEVBQUUsR0FBRztFQUNkLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLDBDQUEwQyxDQUFDO0VBQ3hFLEtBQUssRUFBRSxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUM7RUFDakMsS0FBSyxFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztBQUNwQyxDQUFDLEVBQ0Q7RUFDQyxNQUFNLEVBQUUsU0FBUztFQUNqQixTQUFTLEVBQUUsR0FBRztFQUNkLEtBQUssRUFBRSxjQUFjO0VBQ3JCLEtBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN6QixDQUFDLEVBQ0Q7RUFDQyxNQUFNLEVBQUUsU0FBUztFQUNqQixTQUFTLEVBQUUsR0FBRztFQUNkLEtBQUssRUFBRSxjQUFjO0VBQ3JCLEtBQUssRUFBRSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztBQUM1QixDQUFDLEVBQ0Q7RUFDQyxNQUFNLEVBQUUsTUFBTTtFQUNkLEtBQUssRUFBRSxNQUFNO0VBQ2IsS0FBSyxFQUFFLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRDtBQUNBO0VBQ0MsTUFBTSxFQUFFLFdBQVc7RUFDbkIsS0FBSyxFQUFFLFFBQVE7RUFDZixLQUFLLEVBQUUsQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDO0VBQ2pDLEtBQUssRUFBRTtBQUNSLENBQUMsRUFDRDtFQUNDLE1BQU0sRUFBRSxZQUFZO0VBQ3BCLEtBQUssRUFBRSxRQUFRO0VBQ2YsS0FBSyxFQUFFLE1BQU07RUFDYixLQUFLLEVBQUU7QUFDUixDQUFDLENBQ0Q7O0FBRUQ7QUFDQSxVQUFVLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxZQUFZO0VBQzdDO0VBQ0EsVUFBVSxTQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUUsSUFBSyxDQUFDOztFQUVsRDtFQUNBLElBQUksQ0FBQyxXQUFXLEdBQUcsa0JBQVMsQ0FBQyxZQUFZOztFQUV6QztFQUNBLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSx3QkFBWSxDQUFDO0lBQzlCLFFBQVEsRUFBRSxJQUFJLENBQUM7RUFDaEIsQ0FBRSxDQUFDO0VBQ0gsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7SUFBQyxRQUFRLEVBQUM7RUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7O0VBRTlEO0VBQ0EsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDO0lBQ3RDLFFBQVEsRUFBRSxDQUFDLENBQUMsZ0ZBQWdGLENBQUM7SUFDN0YsS0FBSyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQ3hCLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FDTixJQUFJLENBQUM7TUFBQyxNQUFNLEVBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDO01BQUUsUUFBUSxFQUFDO0lBQVEsQ0FBQyxDQUFDLENBQzNELE1BQU0sQ0FDTixDQUFDLENBQUMsT0FBTyxDQUFDLENBQ1IsR0FBRyxDQUFDO01BQUMsZ0JBQWdCLEVBQUU7SUFBYyxDQUFDLENBQUMsQ0FDdkMsSUFBSSxDQUFDO01BQ0wsS0FBSyxFQUFFLDRKQUE0SjtNQUNuSyxPQUFPLEVBQUUscUNBQXFDO01BQzlDLEtBQUssRUFBRSxXQUFXO01BQ2xCLE9BQU8sRUFBRSxNQUFNO01BQ2YsUUFBUSxFQUFFO0lBQ1gsQ0FBQyxDQUNILENBQUMsRUFDRixHQUFHLEVBQ0gsQ0FBQyxDQUFDLCtCQUErQixDQUNsQztFQUNELENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7RUFDaEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDO0lBQzFDLFFBQVEsRUFBRSxDQUFDLENBQUMsbUZBQW1GO0VBQ2hHLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7RUFDaEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUM7O0VBRXhFOztFQUVBO0VBQ0EsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLDRCQUFnQixDQUFDO0lBQ3RDLFdBQVcsRUFBRSxJQUFJLENBQUM7RUFDbkIsQ0FBQyxDQUFDO0VBQ0YsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFFO0lBQ3hDLE1BQU0sRUFBRSxLQUFLO0lBQ2IsUUFBUSxFQUFFLEtBQUs7SUFDZixRQUFRLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUMzQixDQUFFLENBQUM7O0VBRUg7RUFDQTtFQUNBLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSwyQkFBZSxDQUFDLENBQUM7RUFDdEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFFO0lBQ3pDLE1BQU0sRUFBRSxJQUFJO0lBQ1osUUFBUSxFQUFFLEtBQUs7SUFDZixRQUFRLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQztFQUMxQixDQUFFLENBQUM7O0VBRUg7RUFDQSxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBRTtJQUN2RCxLQUFLLEVBQUU7RUFDUixDQUFFLENBQUM7RUFDSCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBRTtJQUFDLEtBQUssRUFBRSxFQUFFO0lBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQyxPQUFPO0VBQUUsQ0FBQyxDQUFDO0VBQ3BGLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsQ0FDcEMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FDcEIsSUFBSSxDQUFDLG1CQUFtQixFQUN4QjtJQUFFLEtBQUssRUFBRTtFQUFNLENBQ2hCLENBQUMsQ0FDRCxDQUFDO0VBQ0YsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUU7SUFDakQsTUFBTSxFQUFFLElBQUk7SUFDWixRQUFRLEVBQUUsS0FBSztJQUNmLFFBQVEsRUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUM7RUFDdkMsQ0FBRSxDQUFDO0VBRUgsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFFO0lBQ3pDLEtBQUssRUFBRSxDQUNOLElBQUksQ0FBQyxVQUFVLEVBQ2YsSUFBSSxDQUFDLFdBQVcsRUFDaEIsSUFBSSxDQUFDLG1CQUFtQixDQUN4QjtJQUNELE1BQU0sRUFBRSxLQUFLO0lBQ2IsUUFBUSxFQUFFO0VBQ1gsQ0FBRSxDQUFDO0VBRUgsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7SUFBQyxLQUFLLEVBQUM7RUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUM7O0VBRWhFOztFQUVBLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtJQUN6QixjQUFjLEVBQUUsZ0JBQWdCO0lBQ2hDLFlBQVksRUFBRSxjQUFjO0lBQzVCLGdCQUFnQixFQUFFLGtCQUFrQjtJQUNwQyxXQUFXLEVBQUUsYUFBYTtJQUMxQixVQUFVLEVBQUU7RUFDYixDQUFDLENBQUM7RUFDRixJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7SUFBQyxhQUFhLEVBQUU7RUFBd0IsQ0FBQyxDQUFDOztFQUV4RTtFQUNBO0VBQ0EsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUNoQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsS0FBSyxFQUFHO0lBQzNELElBQUksWUFBWTtJQUNoQixRQUFPLEtBQUssQ0FBQyxLQUFLO01BQ2xCLEtBQUssRUFBRTtRQUFFO1FBQ1IsWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUMsR0FBRztRQUMvRDtNQUNELEtBQUssRUFBRTtRQUFFO1FBQ1IsWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUMsR0FBRztRQUMvRDtNQUNEO1FBQ0M7SUFDRDtJQUNBLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQztJQUNsQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7RUFDdkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztFQUVkLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtJQUFDLFlBQVksRUFBRTtFQUFjLENBQUMsQ0FBQztBQUU3RCxDQUFDO0FBRUQsVUFBVSxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsR0FBRyxZQUFXO0VBQ3hEO0VBQ0EsSUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztFQUMzQztFQUNBLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztFQUNqQjtFQUNBLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQztBQUNuQyxDQUFDO0FBRUQsVUFBVSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEdBQUcsWUFBVztFQUMvQyxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztFQUN4RCxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUFDLFFBQVEsRUFBQztFQUFNLENBQUMsQ0FBQztFQUMxRjtFQUNBO0VBQ0EsSUFBSSxRQUFRLEdBQUc7SUFBRSxDQUFDLEVBQUUsQ0FBQztJQUFFLENBQUMsRUFBRTtFQUFFLENBQUM7RUFDN0IsSUFBTSxTQUFTLEdBQUcsU0FBWixTQUFTLENBQVksR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUU7SUFDL0MsSUFBSSxHQUFHLEdBQUcsTUFBTSxFQUFFLE9BQU8sTUFBTTtJQUMvQixJQUFJLEdBQUcsR0FBRyxNQUFNLEVBQUUsT0FBTyxNQUFNO0lBQy9CLE9BQU8sR0FBRztFQUNYLENBQUM7RUFDRCxJQUFNLFVBQVUsR0FBRyxTQUFiLFVBQVUsQ0FBSSxHQUFHLEVBQUs7SUFDM0I7SUFDQSxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsVUFBVSxHQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBQyxDQUFDLEdBQUcsR0FBRztJQUMvRCxPQUFPLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQztFQUN2QyxDQUFDO0VBQ0QsSUFBTSxVQUFVLEdBQUcsU0FBYixVQUFVLENBQUksR0FBRyxFQUFLO0lBQzNCO0lBQ0EsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDLElBQUUsTUFBTSxDQUFDLFdBQVcsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFDLENBQUM7SUFDakU7SUFDQSxJQUFJLFFBQVEsR0FBRyxDQUFDLFFBQVEsQ0FBQyxlQUFlLElBQUUsUUFBUSxFQUFFLFlBQVksR0FBRyxNQUFNLENBQUMsV0FBVyxHQUFDLENBQUM7SUFDdkYsT0FBTyxTQUFTLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUM7RUFDMUMsQ0FBQztFQUVELElBQUksV0FBVyxHQUFHLEtBQUs7RUFDdkIsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0VBRWpCLElBQUksV0FBVyxHQUFHLFNBQWQsV0FBVyxDQUFHLEtBQUssRUFBSTtJQUMxQixXQUFXLEdBQUcsSUFBSTtJQUNsQixRQUFRLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPO0lBQzFCLFFBQVEsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLE9BQU87RUFDM0IsQ0FBQztFQUNELElBQUksVUFBVSxHQUFHLFNBQWIsVUFBVSxDQUFHLEtBQUssRUFBSTtJQUN6QixJQUFJLENBQUMsV0FBVyxJQUFJLFFBQVEsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLFFBQVEsQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFO01BQzlEO0lBQ0Q7SUFDQSxJQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxDQUFDO0lBQ3JDLElBQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLENBQUM7SUFDckMsUUFBUSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTztJQUMxQixRQUFRLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPO0lBQzFCLFFBQVEsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3hDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3hDLFFBQVEsQ0FBQyxHQUFHLENBQUMsV0FBVyxlQUFBLE1BQUEsQ0FBZSxRQUFRLENBQUMsQ0FBQyxVQUFBLE1BQUEsQ0FBTyxRQUFRLENBQUMsQ0FBQyxRQUFLLENBQUM7RUFDekUsQ0FBQztFQUNELElBQUksU0FBUyxHQUFHLFNBQVosU0FBUyxDQUFBLEVBQVM7SUFDckIsV0FBVyxHQUFHLEtBQUs7SUFDbkIsT0FBTyxRQUFRLENBQUMsQ0FBQztJQUNqQixPQUFPLFFBQVEsQ0FBQyxDQUFDO0lBQ2pCO0lBQ0EsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbkMsUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbkMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxXQUFXLGVBQUEsTUFBQSxDQUFlLFFBQVEsQ0FBQyxDQUFDLFVBQUEsTUFBQSxDQUFPLFFBQVEsQ0FBQyxDQUFDLFFBQUssQ0FBQztFQUN6RSxDQUFDOztFQUVEO0VBQ0EsSUFBTSxPQUFPLEdBQUksY0FBYyxJQUFJLE1BQU0sR0FBSSxTQUFTLEdBQUcsT0FBTztFQUNoRSxTQUFTLENBQUMsRUFBRSxDQUFDLE9BQU8sR0FBQyxvQkFBb0IsRUFBRTtJQUFBLE9BQU0sUUFBUSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsV0FBVyxDQUFDO0VBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUM3RixTQUFTLENBQUMsRUFBRSxDQUFDLE9BQU8sR0FBQyxvQkFBb0IsRUFBRSxZQUFNO0lBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUM7RUFBRSxDQUFFLENBQUMsQ0FBQyxDQUFDO0VBQzNHLFNBQVMsQ0FBQyxFQUFFLENBQUMsT0FBTyxHQUFDLG1CQUFtQixFQUFFLFdBQVcsQ0FBQztFQUN0RCxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sR0FBQyxtQkFBbUIsRUFBRSxVQUFVLENBQUM7RUFDckQsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEdBQUMsaUJBQWlCLEVBQUUsU0FBUyxDQUFDO0FBQ25ELENBQUM7O0FBRUQ7QUFDQSxVQUFVLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxZQUFZO0VBQ2hELElBQUksYUFBYSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLENBQUM7RUFDckQsSUFBSSxZQUFZLEdBQUcsYUFBYSxJQUFJLGFBQWEsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztFQUM1RSxJQUFJLGFBQWEsR0FBRyxhQUFhLElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztFQUN0RyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLFlBQVksRUFBRSxhQUFhLENBQUM7QUFDbEQsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsVUFBVSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsVUFBVyxJQUFJLEVBQUc7RUFBQSxJQUFBLEtBQUE7RUFDeEQsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7RUFDakIsT0FBTyxVQUFVLFNBQU0sQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUUsSUFBSyxDQUFDLENBQ2xFLElBQUksQ0FBRSxZQUFNO0lBQ1osS0FBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3BCO0lBQ0EsS0FBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQ3JDLEtBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDOUM7SUFDQSxLQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXO0lBQ25DLEtBQUksQ0FBQyxRQUFRLEdBQUc7TUFDZixRQUFRLEVBQUUsSUFBSSxDQUFDLGNBQWM7TUFDN0IsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRO01BQ3pCLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTztNQUN4QixTQUFTLEVBQUUsSUFBSSxDQUFDO0lBQ2pCLENBQUM7SUFDRDtJQUNBLEtBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUM1QixLQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsR0FBSSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQ3ZELE1BQU0sR0FDTixJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVTtJQUNwQyxLQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsR0FBRyxLQUFJLENBQUMsUUFBUTtJQUN4QyxLQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FDdkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUUsVUFBQSxjQUFjO01BQUEsT0FBSSxJQUFJLHdCQUFZLENBQ25ELGNBQWMsRUFDZDtRQUNDLFdBQVcsRUFBRSxLQUFJLENBQUMsV0FBVztRQUM3QixRQUFRLEVBQUUsS0FBSSxDQUFDLFFBQVE7UUFDdkIsU0FBUyxFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUM7TUFDMUIsQ0FDRCxDQUFDO0lBQUEsQ0FBQyxDQUNILENBQUM7SUFDRCxJQUFJLG1CQUFtQixHQUFHLEtBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFBLE1BQU07TUFBQSxPQUFJLE1BQU0sQ0FBQyxlQUFlO0lBQUEsRUFBQztJQUN0RixJQUFJLG1CQUFtQixJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixFQUFFO01BQ2hFLG1CQUFtQixDQUFDLG9CQUFvQixHQUFHLEtBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FDdEUsVUFBQyxXQUFXLEVBQUUsU0FBUztRQUFBLE9BQUssV0FBVyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQztNQUFBLEdBQ3ZFLG1CQUFtQixDQUFDLGdCQUNyQixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQztJQUMvQjtJQUNBLEtBQUksQ0FBQyxVQUFVLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUN6QyxvQ0FBb0MsQ0FBQyxDQUFDO0lBQ3hDO0lBQ0EsSUFBSSxLQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRTtNQUMzQixLQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQzFELENBQUMsTUFBTSxJQUFJLEtBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFO01BQ3BDLEtBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNoRSxDQUFDLE1BQU0sSUFBSSxLQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO01BQ2hELEtBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDekQsQ0FBQyxNQUFNLElBQUksS0FBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtNQUNoRCxLQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDN0QsQ0FBQyxNQUFNLElBQUksS0FBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtNQUNoRCxLQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQzFELENBQUMsTUFBTSxJQUFJLEtBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7TUFDbEQsS0FBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUN6RCxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO01BQ3JCLEtBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVO01BQ3JDLEtBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxNQUFNLENBQ2xFLGNBQWMsRUFDZCxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQ3hDLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUNyQyxDQUFDO0lBQ0YsQ0FBQyxNQUFNLElBQUksS0FBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUU7TUFDbkMsS0FBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUN6RCxDQUFDLE1BQU07TUFDTixLQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBRSxLQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBUSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUN4RztJQUNBO0lBQ0EsS0FBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWTtJQUNyQyxLQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUUsVUFBQSxjQUFjO01BQUEsT0FBSSxjQUFjLENBQUMsSUFBSTtJQUFBLENBQUMsQ0FBQztJQUNwRixLQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRO0lBQzdCO0lBQ0EsS0FBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0VBQ2xCLENBQUMsRUFBRSxJQUFLLENBQUM7QUFDWCxDQUFDOztBQUVEO0FBQ0EsVUFBVSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEdBQUcsVUFBVyxJQUFJLEVBQUc7RUFBQSxJQUFBLE1BQUE7RUFDeEQsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7RUFDakIsT0FBTyxVQUFVLFNBQU0sQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBRSxJQUFJLEVBQUUsSUFBSyxDQUFDLENBQ2xFLElBQUksQ0FBRTtJQUFBLE9BQU0sTUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7RUFBQSxDQUFDLENBQUM7QUFDOUMsQ0FBQzs7QUFFRDtBQUNBLFVBQVUsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEdBQUcsVUFBVyxNQUFNLEVBQUc7RUFBQSxJQUFBLE1BQUE7RUFDM0QsSUFBSyxNQUFNLEtBQUssV0FBVyxFQUFHO0lBQzdCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQztJQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBRSxJQUFJLENBQUMsV0FBWSxDQUFDO0lBQzVDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztJQUM3QixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7RUFFbEIsQ0FBQyxNQUFNLElBQUssTUFBTSxLQUFLLFdBQVcsRUFBRztJQUNwQyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzVDLE9BQU8sSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUM5QixJQUFBLGVBQVcsRUFBQyxZQUFZLENBQUMsQ0FBQyxJQUFJO0lBQzdCO0lBQ0EsWUFBTTtNQUNMLE1BQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDO01BQ2pDLE1BQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztNQUM1QixNQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBRSxNQUFJLENBQUMsVUFBVyxDQUFDO01BQzNDLE1BQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztNQUM5QixNQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbEIsQ0FBQztJQUNEO0lBQ0EsVUFBQyxJQUFJLEVBQUUsR0FBRztNQUFBLE9BQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUNqQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUNkLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQ2hCLENBQUMsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxFQUN4RSxDQUFDLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxJQUFJLENBQUUsSUFBQSxpQkFBWSxFQUFDLElBQUksRUFBRSxHQUFHLENBQUUsQ0FDOUQsQ0FDRCxDQUNELENBQUM7SUFBQSxDQUNGLENBQ0QsQ0FBQztFQUVGLENBQUMsTUFBTSxJQUFLLE1BQU0sS0FBSyxZQUFZLEVBQUc7SUFDckMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBTTtNQUNyQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7TUFDckIsTUFBSSxDQUFDLEtBQUssQ0FBQztRQUFDLE9BQU8sRUFBRTtNQUFJLENBQUMsQ0FBQztJQUM1QixDQUFDLENBQUM7RUFHSCxDQUFDLE1BQU0sSUFBSyxNQUFNLEtBQUssWUFBWSxFQUFHO0lBQ3JDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUM1QixJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBRSxJQUFJLENBQUMsVUFBVyxDQUFDO0lBQzNDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztJQUM5QixJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzlDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztFQUVsQixDQUFDLE1BQU0sSUFBSyxNQUFNLEtBQUssTUFBTSxFQUFHO0lBQy9CLE9BQU8sSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUM5QixlQUFHLENBQUMsYUFBYSxDQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQy9CO01BQUMsU0FBUyxFQUFFO0lBQUMsQ0FBQyxFQUNkLFVBQUEsUUFBUTtNQUFBLE9BQUs7UUFDWixPQUFPLEVBQUUsQ0FBQztRQUNWLElBQUksRUFBRSxNQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztRQUNsRCxPQUFPLEVBQUUsTUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQy9CLFNBQVMsRUFBRSxNQUFJLENBQUMsV0FBVyxDQUFDO01BQzdCLENBQUM7SUFBQSxDQUNGLENBQUMsU0FBTSxDQUFDLFVBQUMsSUFBSSxFQUFFLEdBQUc7TUFBQSxPQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FDekMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FDZCxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUNoQixDQUFDLENBQUMsaUNBQWlDLENBQUMsQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsRUFDekUsQ0FBQyxDQUFDLDJCQUEyQixDQUFDLENBQUMsSUFBSSxDQUFFLElBQUEsaUJBQVksRUFBQyxJQUFJLEVBQUUsR0FBRyxDQUFFLENBQzlELENBQ0QsQ0FDRCxDQUFDO0lBQUEsQ0FBQyxDQUNILENBQUMsQ0FBQyxJQUFJLENBQUU7TUFBQSxPQUFNLE1BQUksQ0FBQyxLQUFLLENBQUM7UUFDeEIsT0FBTyxFQUFFLElBQUk7UUFDYixZQUFZLEVBQUUsTUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLElBQUksTUFBSSxDQUFDLGlCQUFpQixDQUFDO01BQ2xFLENBQUMsQ0FBQztJQUFBLENBQUMsQ0FBQztFQUVMLENBQUMsTUFBTSxJQUFLLE1BQU0sS0FBSyxTQUFTLEVBQUc7SUFDbEMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQzlCLGVBQUcsQ0FBQyxJQUFJLENBQUM7TUFDUixNQUFNLEVBQUUsT0FBTztNQUNmLFlBQVksRUFBRSxVQUFVO01BQ3hCLElBQUksRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLFVBQVUsR0FBRyxzQkFBc0IsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7TUFDbEgsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7TUFDdEMsR0FBRyxFQUFFO0lBQ04sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFFLFVBQUEsTUFBTSxFQUFJO01BQ2xCLElBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRztRQUNoRixPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUM7TUFDM0M7TUFDQSxJQUFJLGtCQUFrQixHQUFHLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7TUFFdEUsTUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztNQUNyRCxNQUFJLENBQUMsc0JBQXNCLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztNQUNoRCxNQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7TUFDL0IsTUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUUsTUFBSSxDQUFDLG1CQUFvQixDQUFDO01BQ3BELE1BQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztNQUM3QixNQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbEIsQ0FBQyxDQUFDLFNBQ0ssQ0FBRSxVQUFDLElBQUksRUFBRSxHQUFHO01BQUEsT0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQ3pDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQ2QsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FDaEIsQ0FBQyxDQUFDLGlDQUFpQyxDQUFDLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEVBQ3BFLENBQUMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLElBQUksQ0FBRSxJQUFBLGlCQUFZLEVBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBRSxDQUM5RCxDQUNELENBQ0QsQ0FBQztJQUFBLENBQUMsQ0FDSixDQUFDO0VBRUYsQ0FBQyxNQUFNLElBQUssTUFBTSxLQUFLLFNBQVMsRUFBRztJQUNsQyxPQUFPLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FDOUIsZUFBRyxDQUFDLElBQUksQ0FBQztNQUNSLE1BQU0sRUFBRSxTQUFTO01BQ2pCLE1BQU0sRUFBRSxNQUFNO01BQ2QsUUFBUSxFQUFFLElBQUksQ0FBQyxZQUFZO01BQzNCLGdCQUFnQixFQUFFLFVBQVU7TUFDNUIsTUFBTSxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO01BQ3JELGNBQWMsRUFBRSxVQUFVO01BQzFCLElBQUksRUFBRTtJQUNQLENBQUMsQ0FBQyxDQUNBLElBQUksQ0FBRSxVQUFBLE1BQU0sRUFBSTtNQUNoQixJQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUc7UUFDekQsT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDO01BQzNDO01BQ0EsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FDcEUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FDZixDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQUMsU0FBUyxFQUFDLEdBQUc7UUFBRSxPQUFPLEVBQUM7TUFBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUMxRixDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQUMsU0FBUyxFQUFDLEdBQUc7UUFBRSxPQUFPLEVBQUM7TUFBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQ25GLENBQUMsRUFDRCxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUNuQixDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUNsQixDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUNmLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLE1BQU0sQ0FDM0IsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUNwQyxNQUFJLENBQUMsZUFBZSxDQUFDLENBQ3RCLENBQ0QsQ0FDRCxDQUNELENBQUM7TUFFRCxNQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztNQUN4QyxNQUFJLENBQUMsc0JBQXNCLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztNQUNoRCxNQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7TUFDNUIsTUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUUsTUFBSSxDQUFDLG1CQUFvQixDQUFDO01BQ3BELE1BQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztNQUM3QixNQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDbEIsQ0FBRSxDQUFDLFNBQ0csQ0FBRSxVQUFDLElBQUksRUFBRSxHQUFHO01BQUEsT0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQ3pDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQ2QsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FDaEIsQ0FBQyxDQUFDLGlDQUFpQyxDQUFDLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEVBQ3BFLENBQUMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLElBQUksQ0FBRSxJQUFBLGlCQUFZLEVBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBRSxDQUM5RCxDQUNELENBQ0QsQ0FBQztJQUFBLENBQUMsQ0FDSixDQUFDO0VBRUYsQ0FBQyxNQUFNLElBQUssTUFBTSxLQUFLLE1BQU0sRUFBRztJQUMvQixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDNUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUUsSUFBSSxDQUFDLFVBQVcsQ0FBQztJQUMzQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUM7SUFDOUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0VBRWxCLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFO0lBQzlDO0lBQ0EsT0FBTyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQzlCLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLGlDQUFpQyxFQUFFO01BQUMsS0FBSyxFQUFDO0lBQWMsQ0FBQyxDQUFDLENBQ3RFLElBQUksQ0FBQyxVQUFBLFNBQVM7TUFBQSxPQUFJLFNBQVMsR0FBRyxNQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJO0lBQUEsRUFDcEQsQ0FBQztFQUNGO0VBRUEsT0FBTyxVQUFVLFNBQU0sQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFFLElBQUksRUFBRSxNQUFPLENBQUM7QUFDeEUsQ0FBQzs7QUFFRDtBQUNBO0FBQ0EsVUFBVSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsR0FBRyxVQUFXLElBQUksRUFBRztFQUFBLElBQUEsTUFBQTtFQUMzRCxPQUFPLFVBQVUsU0FBTSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUUsSUFBSSxFQUFFLElBQUssQ0FBQyxDQUNyRSxLQUFLLENBQUUsWUFBTTtJQUNiLE1BQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDNUIsTUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztJQUNsQyxNQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBRSxNQUFJLENBQUMsVUFBVyxDQUFDO0lBQzNDLE1BQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztJQUM5QixNQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckUsTUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztJQUU3QyxNQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUMsRUFBRSxDQUFDO0lBQzdELE1BQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLCtCQUErQixDQUFDLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQztJQUN4RSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQztFQUMvQixDQUFFLENBQUM7QUFDTCxDQUFDO0FBRUQsVUFBVSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEdBQUcsVUFBUyxLQUFLLEVBQUU7RUFDckQsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLGtCQUFTLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQztFQUM5RDtFQUNBLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7QUFDakQsQ0FBQztBQUVELFVBQVUsQ0FBQyxTQUFTLENBQUMsWUFBWSxHQUFHLFlBQVc7RUFDOUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUM7QUFDakMsQ0FBQztBQUVELFVBQVUsQ0FBQyxTQUFTLENBQUMsY0FBYyxHQUFHLFVBQVMsSUFBSSxFQUFFO0VBQUEsSUFBQSxNQUFBO0VBQ3BELElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0VBQ25DLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7RUFDbEQsSUFBSSxDQUFDLElBQUksRUFBRTtJQUNWLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUM7RUFDRDtFQUNBLElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFBLE1BQU0sRUFBSTtJQUN6RCxPQUFPLE1BQU0sQ0FBQyxRQUFRLEtBQUssSUFBSSxJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsS0FBSyxJQUFJO0VBQzFFLENBQUMsQ0FBQzs7RUFFRjtFQUNBLElBQUksY0FBYyxFQUFFO0lBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2xDLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxHQUFHLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7RUFDOUY7O0VBRUE7RUFDQSxJQUFJLFdBQVc7RUFDZixJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO0lBQzNDLFdBQVcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUNsQyxJQUFJLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcseUVBQy9CLENBQUM7RUFDRixDQUFDLE1BQU0sSUFBSSxJQUFJLEtBQUssNEJBQTRCLElBQUksQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtJQUN6SDtJQUNBLFdBQVcsR0FBRyx3SEFBd0g7RUFDdkk7RUFDQSxDQUFDLENBQUMsSUFBSSxDQUFFLFdBQVcsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FDdEQsSUFBSSxDQUFFLFVBQUEsU0FBUyxFQUFJO0lBQ25CLElBQUksQ0FBQyxTQUFTLEVBQUU7SUFDaEI7SUFDQSxPQUFPLHdCQUFZLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRTtNQUNuRCxXQUFXLEVBQUUsTUFBSSxDQUFDLFdBQVc7TUFDN0IsUUFBUSxFQUFFLE1BQUksQ0FBQyxRQUFRO01BQ3ZCLFNBQVMsRUFBRSxNQUFJLENBQUMsUUFBUSxDQUFDO0lBQzFCLENBQUMsQ0FBQyxDQUNBLElBQUksQ0FBQyxVQUFBLE1BQU0sRUFBSTtNQUNmLE1BQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFFLENBQUMsTUFBTSxDQUFFLENBQUM7TUFDcEMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO01BQ25CLE1BQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNsQixDQUFDLENBQUM7RUFDSixDQUFDLENBQUMsQ0FDRCxJQUFJLENBQUU7SUFBQSxPQUFNLE1BQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0VBQUEsQ0FBQyxDQUFDO0FBQ3hFLENBQUM7QUFFRCxVQUFVLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxVQUFTLFFBQVEsRUFBRTtFQUN0RCxJQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsZUFBZTtFQUFBLEVBQUM7RUFDbEYsSUFBSSxhQUFhLEVBQUU7SUFDbEIsYUFBYSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQztJQUNoRSxhQUFhLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7RUFDakQ7RUFDQSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBQSxNQUFNLEVBQUk7SUFDdkMsSUFBSSxNQUFNLENBQUMsZUFBZSxJQUFHLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRTtNQUNyRCxNQUFNLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxHQUFHLElBQUksR0FBRyxRQUFRLENBQUM7TUFDaEYsTUFBTSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDO0lBQzFDO0VBQ0QsQ0FBQyxDQUFDO0FBQ0gsQ0FBQztBQUVELFVBQVUsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEdBQUcsVUFBUyxhQUFhLEVBQUU7RUFDL0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQUEsTUFBTSxFQUFJO0lBQ3ZDLElBQUksTUFBTSxDQUFDLG9CQUFvQixFQUFFO01BQ2hDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQztNQUNuRSxNQUFNLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztJQUMvQztFQUNELENBQUMsQ0FBQztBQUNILENBQUM7QUFFRCxVQUFVLENBQUMsU0FBUyxDQUFDLFdBQVcsR0FBRyxZQUFXO0VBQzdDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDN0IsQ0FBQztBQUVELFVBQVUsQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLFlBQVc7RUFDNUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFFLFVBQUEsTUFBTTtJQUFBLE9BQUksTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7RUFBQSxDQUFDLENBQUM7QUFDdkUsQ0FBQztBQUVELFVBQVUsQ0FBQyxTQUFTLENBQUMscUJBQXFCLEdBQUcsVUFBUyxZQUFZLEVBQUU7RUFBQSxJQUFBLE1BQUE7RUFDbkUsSUFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztFQUNwRCxJQUFJLENBQUMsWUFBWSxFQUFFO0lBQ2xCLE9BQU8sZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0VBQzlCO0VBQ0E7RUFDQSxJQUFJLGFBQWEsR0FBRyxJQUFBLHdCQUFjLEVBQUMsWUFBWSxFQUFFLElBQUksQ0FBQztFQUN0RDtFQUNBLGFBQWEsQ0FBQyxPQUFPLENBQUMsVUFBQSxRQUFRLEVBQUk7SUFDakMsSUFBSSxNQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRTtNQUNyRCxZQUFZLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQztJQUMvRDtFQUNELENBQUMsQ0FBQztFQUNGO0VBQ0EsWUFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQztFQUNuRDtFQUNBO0VBQ0EsWUFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsMkJBQTJCLEVBQUMsRUFBRSxDQUFDO0VBQ25FO0VBQ0EsSUFBSSxvQkFBb0IsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUM7SUFBQSxPQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztFQUFBLEVBQUM7RUFDeEUsSUFBSSxvQkFBb0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO0lBQ3RDO0lBQ0EsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7RUFDekc7RUFDQTtFQUNBLElBQUksT0FBTyxHQUFHLFlBQVk7RUFDMUIsYUFBYSxDQUFDLE9BQU8sQ0FBQyxVQUFBLFFBQVEsRUFBSTtJQUNqQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQztFQUNqRCxDQUFDLENBQUM7RUFDRixJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRTtJQUN4RDtJQUNBLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztFQUMzRCxDQUFDLE1BQU07SUFDTjtJQUNBLE9BQU8sZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztFQUMzRDtBQUNELENBQUM7QUFFRCxVQUFVLENBQUMsU0FBUyxDQUFDLGlCQUFpQixHQUFHLFlBQVc7RUFDbkQsSUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUEsTUFBTTtJQUFBLE9BQzFELE1BQU0sQ0FBQyxlQUFlLElBQ3RCLE1BQU0sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsSUFDL0IsTUFBTSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLE1BQU07RUFBQSxDQUMzQyxDQUFDO0VBQ0QsT0FBTyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUM7QUFDbEMsQ0FBQztBQUVELFVBQVUsQ0FBQyxTQUFTLENBQUMsZUFBZSxHQUFHLFlBQVc7RUFBQSxJQUFBLE1BQUE7RUFDakQsSUFBTSxjQUFjLEdBQUcsRUFBRTtFQUN6QixJQUFNLGFBQWEsR0FBRyxFQUFFO0VBQ3hCLElBQU0sVUFBVSxHQUFHLEVBQUU7RUFDckIsSUFBTSxTQUFTLEdBQUcsU0FBWixTQUFTLENBQUcsSUFBSTtJQUFBLE9BQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBQyxFQUFFLENBQUM7RUFBQTs7RUFFOUU7RUFDQSxJQUFNLFVBQVUsR0FBRyxJQUFBLGlCQUFXLEVBQzdCLElBQUEsa0JBQVksRUFBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFDakMsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsZUFBZSxJQUFJLE1BQU0sQ0FBQyxlQUFlO0VBQUEsR0FDMUQsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0VBQUEsQ0FDMUMsQ0FDRCxDQUFDO0VBQ0QsSUFBSSxZQUFZLEdBQUcsVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQztFQUMzRCxJQUFNLGNBQWMsR0FBRyxJQUFBLGlCQUFXLEVBQ2pDLElBQUEsa0JBQVksRUFBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFDakMsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsb0JBQW9CO0VBQUEsR0FDckMsVUFBQSxNQUFNO0lBQUEsT0FBSSxNQUFNLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7RUFBQSxDQUMvQyxDQUNELENBQUM7RUFDRCxJQUFJLGlCQUFpQixHQUFHLGNBQWMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLGNBQWMsQ0FBQyxDQUFDLENBQUM7RUFDeEU7RUFDQSxJQUFJLGtCQUFrQixHQUFHLEtBQUs7RUFDOUIsSUFBSSxzQkFBc0IsR0FBRyxLQUFLOztFQUVsQztFQUNBLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsVUFBQSxJQUFJLEVBQUk7SUFDeEMsSUFBTSxNQUFNLEdBQUcsTUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFFLFVBQUEsTUFBTTtNQUFBLE9BQUksTUFBTSxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLFlBQVksS0FBSyxJQUFJO0lBQUEsQ0FBQyxDQUFDO0lBQzNHLElBQUksQ0FBQyxNQUFNLEVBQUU7TUFDWixjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0M7RUFDRCxDQUFDLENBQUM7RUFDRjtFQUNBLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBRSxVQUFBLE1BQU0sRUFBSTtJQUN4QyxJQUFNLEtBQUssR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNoQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtNQUM5QjtNQUNBO0lBQ0Q7SUFDQSxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsZUFBZSxLQUFNLEtBQUssSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksTUFBTSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMzRyxJQUFJLFFBQVEsRUFBRTtNQUFFLGtCQUFrQixHQUFHLElBQUk7SUFBRTtJQUMzQyxJQUFJLFlBQVksRUFBRTtNQUFFLFFBQVEsR0FBRyxJQUFJO0lBQUU7SUFFckMsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixLQUFLLEtBQUssSUFBSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsSUFBSSxNQUFNLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUgsSUFBSSxhQUFhLEVBQUU7TUFBRSxzQkFBc0IsR0FBRyxJQUFJO0lBQUU7SUFDcEQsSUFBSSxpQkFBaUIsRUFBRTtNQUFFLGFBQWEsR0FBRyxJQUFJO0lBQUU7SUFFL0MsSUFBSSxNQUFNLEdBQUksUUFBUSxJQUFJLGFBQWEsR0FDcEMsUUFBUSxHQUFHLEdBQUcsR0FBRyxhQUFhLEdBQzlCLFFBQVEsSUFBSSxhQUFhLElBQUksRUFBRTtJQUNsQyxJQUFJLE1BQU0sRUFBRTtNQUFFLE1BQU0sR0FBRyxJQUFJLEdBQUcsTUFBTSxHQUFHLEdBQUc7SUFBRTtJQUU1QyxJQUFJLEtBQUssRUFBRTtNQUNWLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDO0lBQ3ZELENBQUMsTUFBTTtNQUNOLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUM7SUFDcEQ7RUFDRCxDQUFDLENBQUM7RUFDRjtFQUNBLElBQUksYUFBYSxHQUFJLGtCQUFrQixJQUFJLFlBQVksSUFBSSxzQkFBc0IsSUFBSSxpQkFBaUIsR0FDbkcsWUFBWSxHQUFHLEdBQUcsR0FBRyxpQkFBaUIsR0FDckMsa0JBQWtCLElBQUksWUFBWSxJQUFNLHNCQUFzQixJQUFJLGlCQUFrQixJQUFJLEVBQUU7RUFDOUYsSUFBSSxhQUFhLEVBQUU7SUFBRSxhQUFhLEdBQUcsSUFBSSxHQUFHLGFBQWEsR0FBRyxHQUFHO0VBQUU7RUFFakUsb0JBQUEsTUFBQSxDQUFvQixhQUFhLFFBQUEsTUFBQSxDQUFLLEdBQUEsTUFBQSxDQUFJLGFBQWEsRUFBSyxVQUFVLEVBQUssY0FBYyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBQSxNQUFBLENBQUcsa0JBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTTtBQUNoSSxDQUFDO0FBQUMsSUFBQSxRQUFBLEdBQUEsT0FBQSxjQUVhLFVBQVUsRUFDekI7Ozs7Ozs7OztBQ3B2QkEsSUFBQSxPQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQThCLFNBQUEsdUJBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxHQUFBLENBQUEsZ0JBQUEsQ0FBQTtBQUFBLFNBQUEsUUFBQSxDQUFBLHNDQUFBLE9BQUEsd0JBQUEsTUFBQSx1QkFBQSxNQUFBLENBQUEsUUFBQSxhQUFBLENBQUEsa0JBQUEsQ0FBQSxnQkFBQSxDQUFBLFdBQUEsQ0FBQSx5QkFBQSxNQUFBLElBQUEsQ0FBQSxDQUFBLFdBQUEsS0FBQSxNQUFBLElBQUEsQ0FBQSxLQUFBLE1BQUEsQ0FBQSxTQUFBLHFCQUFBLENBQUEsS0FBQSxPQUFBLENBQUEsQ0FBQTtBQUM5Qjs7QUFFQSxJQUFJLEdBQUcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUU7RUFDckIsSUFBSSxFQUFFO0lBQ0wsT0FBTyxFQUFFO01BQ1IsZ0JBQWdCLEVBQUUsUUFBUSxHQUFHLGtCQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sR0FDakQ7SUFDRjtFQUNEO0FBQ0QsQ0FBRSxDQUFDOztBQUVIO0FBQ0EsR0FBRyxDQUFDLE9BQU8sR0FBRyxVQUFTLFVBQVUsRUFBRTtFQUNsQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsMkVBQTJFLEdBQUMsVUFBVSxDQUFDO0FBQ3JHLENBQUM7O0FBRUQ7QUFDQSxHQUFHLENBQUMsTUFBTSxHQUFHLFVBQVMsSUFBSSxFQUFFO0VBQzNCLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEdBQUcsa0JBQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRTtJQUFDLE1BQU0sRUFBQztFQUFLLENBQUMsQ0FBQyxDQUFDLENBQ2hGLElBQUksQ0FBQyxVQUFTLElBQUksRUFBRTtJQUNwQixJQUFLLENBQUMsSUFBSSxFQUFHO01BQ1osT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDO0lBQzNDO0lBQ0EsT0FBTyxJQUFJO0VBQ1osQ0FBQyxDQUFDO0FBQ0osQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE9BQU8sR0FBRyxTQUFWLE9BQU8sQ0FBWSxLQUFLLEVBQUUsTUFBTSxFQUFFO0VBQ3JDLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FDYixDQUFDLENBQUMsTUFBTSxDQUNQO0lBQ0MsUUFBUSxFQUFFLE9BQU87SUFDakIsUUFBUSxFQUFFLE1BQU07SUFDaEIsY0FBYyxFQUFFLENBQUM7SUFDakIsUUFBUSxFQUFFLEtBQUs7SUFDZixNQUFNLEVBQUUsZ0JBQWdCO0lBQ3hCLFFBQVEsRUFBRSxtQkFBbUI7SUFDN0IsU0FBUyxFQUFFO0VBQ1osQ0FBQyxFQUNELE1BQ0QsQ0FDRCxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQUEsUUFBUSxFQUFJO0lBQ2xCLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakQsSUFBSSxTQUFTLEdBQUcsUUFBUSxDQUFDLFlBQVk7SUFDckMsT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQztFQUM3QyxDQUFDLENBQUM7QUFDSCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxXQUFXLEdBQUcsU0FBZCxXQUFXLENBQVksSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUU7RUFDdEQsSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7RUFDakUsSUFBSSxjQUFjLEdBQUc7SUFDcEIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO0lBQ25CLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxLQUFLLEVBQUU7SUFDNUIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEtBQUssRUFBRTtJQUM5QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7SUFDM0IsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO0lBQ1gsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0lBQ2pCLE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHO0VBQzVELENBQUM7RUFDRCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUUsU0FBUyxDQUFDLGNBQWMsQ0FBRSxDQUFDLENBQ3hDLElBQUksQ0FBRSxVQUFBLFVBQVU7SUFBQSxPQUNoQixDQUFDLENBQUMsTUFBTSxDQUFFO01BQ1QsTUFBTSxFQUFFLE1BQU07TUFDZCxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7TUFDakI7TUFDQSxNQUFNLEVBQUUsTUFBTTtNQUNkLGFBQWEsRUFBRSxhQUFhO01BQzVCLGNBQWMsRUFBRTtJQUNqQixDQUFDLEVBQUUsVUFBVyxDQUFDO0VBQUEsQ0FDaEIsQ0FBQztBQUNILENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHLENBQUMsYUFBYSxHQUFHLFVBQVMsS0FBSyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUU7RUFDekQsT0FBTyxPQUFPLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUM5QixJQUFJO0VBQ0w7RUFDQyxVQUFDLElBQUksRUFBRSxTQUFTO0lBQUEsT0FBSyxXQUFXLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUM7RUFBQTtFQUM1RDtFQUNBO0lBQUEsT0FBTSxPQUFPLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsU0FBUyxDQUFDO0VBQUEsQ0FDN0QsQ0FBQyxDQUNBLElBQUksQ0FBQyxVQUFBLFVBQVU7SUFBQSxPQUNmLEdBQUcsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxTQUM5QixDQUFFLFVBQUEsU0FBUyxFQUFJO01BQ3BCLElBQUssU0FBUyxLQUFLLGNBQWMsRUFBRztRQUNuQztRQUNBLE9BQU8sR0FBRyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQztNQUN0RDtNQUNBO01BQ0EsT0FBTyxHQUFHLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUM7SUFDN0MsQ0FBQyxDQUFDO0VBQUEsQ0FDSixDQUFDO0FBQ0gsQ0FBQztBQUVELElBQUksWUFBWSxHQUFBLE9BQUEsQ0FBQSxZQUFBLEdBQUcsU0FBZixZQUFZLENBQVksS0FBSyxFQUFFLE1BQU0sRUFBRTtFQUMxQyxJQUFJLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTztFQUN0QixJQUFLLE9BQUEsQ0FBTyxLQUFLLE1BQUssUUFBUSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRztJQUM5RDtJQUNBLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLO0lBQzdELElBQUssUUFBUSxFQUFHO01BQ2Y7TUFDQSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUk7TUFDcEIsT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPO0lBQzNCLENBQUMsTUFBTTtNQUNOLEdBQUcsR0FBRyxLQUFLO0lBQ1o7RUFDRCxDQUFDLE1BQU0sSUFBSyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksT0FBQSxDQUFPLE1BQU0sTUFBSyxRQUFRLEVBQUc7SUFDckU7SUFDQSxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsS0FBSztJQUM3QixJQUFJLFVBQVUsRUFBRTtNQUNmO01BQ0EsSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJO01BQ3BCLE9BQU8sR0FBRyxRQUFRLENBQUMsSUFBSTtJQUN4QixDQUFDLE1BQU0sSUFBSSxLQUFLLEtBQUssY0FBYyxFQUFFO01BQ3BDLElBQUksR0FBRyxJQUFJO01BQ1gsT0FBTyxHQUFHLHVDQUF1QztJQUNsRCxDQUFDLE1BQU07TUFDTixHQUFHLEdBQUcsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHO0lBQzNCO0VBQ0Q7RUFFQSxJQUFJLElBQUksSUFBSSxPQUFPLEVBQUU7SUFDcEIsb0JBQUEsTUFBQSxDQUFvQixJQUFJLFFBQUEsTUFBQSxDQUFLLE9BQU87RUFDckMsQ0FBQyxNQUFNLElBQUksT0FBTyxFQUFFO0lBQ25CLHFCQUFBLE1BQUEsQ0FBcUIsT0FBTztFQUM3QixDQUFDLE1BQU0sSUFBSSxHQUFHLEVBQUU7SUFDZixxQkFBQSxNQUFBLENBQXFCLEdBQUcsQ0FBQyxNQUFNO0VBQ2hDLENBQUMsTUFBTSxJQUNOLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLEtBQUssT0FBTyxJQUM5QyxPQUFPLE1BQU0sS0FBSyxRQUFRLElBQUksTUFBTSxLQUFLLE9BQU8sRUFDL0M7SUFDRCxnQkFBQSxNQUFBLENBQWdCLEtBQUssUUFBQSxNQUFBLENBQUssTUFBTTtFQUNqQyxDQUFDLE1BQU0sSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLE9BQU8sRUFBRTtJQUMxRCxpQkFBQSxNQUFBLENBQWlCLEtBQUs7RUFDdkIsQ0FBQyxNQUFNO0lBQ04sT0FBTyxtQkFBbUI7RUFDM0I7QUFDRCxDQUFDO0FBQUMsSUFBQSxRQUFBLEdBQUEsT0FBQSxjQUVhLEdBQUcsRUFFbEI7Ozs7Ozs7Ozs7QUM3S0EsSUFBQSxPQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxNQUFBLEdBQUEsT0FBQTtBQUNBLElBQUEsSUFBQSxHQUFBLHVCQUFBLENBQUEsT0FBQTtBQUNBLElBQUEsTUFBQSxHQUFBLHNCQUFBLENBQUEsT0FBQTtBQUFpQyxTQUFBLHdCQUFBLENBQUEsRUFBQSxDQUFBLDZCQUFBLE9BQUEsTUFBQSxDQUFBLE9BQUEsT0FBQSxJQUFBLENBQUEsT0FBQSxPQUFBLFlBQUEsdUJBQUEsWUFBQSx3QkFBQSxDQUFBLEVBQUEsQ0FBQSxTQUFBLENBQUEsSUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFVBQUEsU0FBQSxDQUFBLE1BQUEsQ0FBQSxFQUFBLENBQUEsRUFBQSxDQUFBLEtBQUEsU0FBQSxtQkFBQSxDQUFBLGlCQUFBLENBQUEsZ0JBQUEsT0FBQSxDQUFBLENBQUEsMEJBQUEsQ0FBQSxTQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsQ0FBQSxHQUFBLENBQUEsR0FBQSxDQUFBLFFBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLFVBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLEVBQUEsQ0FBQSxjQUFBLEVBQUEsSUFBQSxDQUFBLGdCQUFBLEVBQUEsT0FBQSxjQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxFQUFBLE9BQUEsQ0FBQSxJQUFBLENBQUEsR0FBQSxNQUFBLENBQUEsY0FBQSxLQUFBLE1BQUEsQ0FBQSx3QkFBQSxDQUFBLENBQUEsRUFBQSxFQUFBLE9BQUEsQ0FBQSxDQUFBLEdBQUEsSUFBQSxDQUFBLENBQUEsR0FBQSxJQUFBLENBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxFQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLFdBQUEsQ0FBQSxLQUFBLENBQUEsRUFBQSxDQUFBO0FBQUEsU0FBQSx1QkFBQSxDQUFBLFdBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxVQUFBLEdBQUEsQ0FBQSxnQkFBQSxDQUFBO0FBQ2pDOztBQUVBLElBQUksU0FBUyxHQUFHLFNBQVMsU0FBUyxDQUFBLEVBQUc7RUFFcEMsT0FBTyxJQUFBLGVBQVEsRUFBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQUEsS0FBSyxFQUFJO0lBQy9CO0lBQ0EsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7TUFDckI7SUFDRDtJQUNBO0lBQ0EsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUU7TUFDaEY7SUFDRDtJQUNBO0lBQ0EsSUFBSSxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRTtNQUN2RDtJQUNEO0lBQ0EsSUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsa0JBQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDaEY7SUFDQSxJQUFJLFlBQVksQ0FBQyxlQUFlLENBQUMsQ0FBQyxLQUFLLFdBQVcsRUFBRTtNQUNuRDtJQUNEO0lBQ0E7SUFDQSxJQUNDLEtBQUssQ0FBQyxtQkFBbUIsSUFDekIsS0FBSyxDQUFDLG1CQUFtQixDQUFDLE1BQU0sSUFDaEMsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLGtCQUFNLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLEVBQy9EO01BQ0Q7SUFDRDs7SUFFQTtJQUNBLElBQUssQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sRUFBRztNQUMvQixPQUFPLElBQUEsaUJBQVUsRUFBQyxDQUFDO0lBQ3BCOztJQUVBO0FBQ0Y7QUFDQTtBQUNBO0lBQ0UsSUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsa0JBQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDMUUsT0FBTyxlQUFHLENBQUMsR0FBRyxDQUFDO01BQ2QsTUFBTSxFQUFFLE9BQU87TUFDZixNQUFNLEVBQUUsTUFBTTtNQUNkLElBQUksRUFBRSxXQUFXO01BQ2pCLE1BQU0sRUFBRSxTQUFTLENBQUMsZUFBZSxDQUFDLENBQUM7TUFDbkMsV0FBVyxFQUFFLElBQUk7TUFDakIsT0FBTyxFQUFFLEtBQUs7TUFDZCxZQUFZLEVBQUU7SUFDZixDQUFDLENBQUMsQ0FDQSxJQUFJLENBQUMsVUFBUyxNQUFNLEVBQUU7TUFDdEIsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPO01BQzdCLElBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVM7TUFFaEQsSUFBSyxDQUFDLFNBQVMsRUFBRztRQUNqQixPQUFPLElBQUEsaUJBQVUsRUFBQyxDQUFDO01BQ3BCO01BRUEsSUFBSSxjQUFjLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFBLFFBQVE7UUFBQSxPQUFJLHdCQUF3QixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO01BQUEsRUFBQztNQUU5RixJQUFLLENBQUMsY0FBYyxFQUFHO1FBQ3RCLE9BQU8sSUFBQSxpQkFBVSxFQUFDLENBQUM7TUFDcEI7SUFFRCxDQUFDLEVBQ0QsVUFBUyxJQUFJLEVBQUUsS0FBSyxFQUFFO01BQ3RCO01BQ0MsT0FBTyxDQUFDLElBQUksQ0FDWCxvREFBb0QsSUFDbkQsSUFBSSxJQUFJLElBQUksQ0FBRSxHQUFHLEVBQUUsR0FBRyxHQUFHLEdBQUcsSUFBQSxpQkFBWSxFQUFDLElBQUksRUFBRSxLQUFLLENBQ3RELENBQUM7TUFDRCxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdCLENBQUMsQ0FBQztFQUNKLENBQUMsQ0FBQztBQUVILENBQUM7QUFBQyxJQUFBLFFBQUEsR0FBQSxPQUFBLGNBRWEsU0FBUyxFQUN4Qjs7Ozs7Ozs7O0FDbEZBLElBQUEsS0FBQSxHQUFBLE9BQUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQU0sS0FBSyxHQUFBLE9BQUEsQ0FBQSxLQUFBLEdBQUcsU0FBUixLQUFLLENBQVksR0FBRyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFO0VBQ3ZELElBQUk7SUFDSCxJQUFNLGdCQUFnQixHQUFHLENBQUM7SUFDMUIsSUFBTSxpQkFBaUIsR0FBRyxFQUFFO0lBQzVCLElBQU0sa0JBQWtCLEdBQUcsRUFBRSxHQUFDLEVBQUUsR0FBQyxFQUFFLEdBQUMsSUFBSTtJQUV4QyxJQUFNLGFBQWEsR0FBRyxDQUFDLFNBQVMsSUFBSSxnQkFBZ0IsSUFBRSxrQkFBa0I7SUFDeEUsSUFBTSxjQUFjLEdBQUcsQ0FBQyxVQUFVLElBQUksaUJBQWlCLElBQUUsa0JBQWtCO0lBRTNFLElBQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7TUFDaEMsS0FBSyxFQUFFLEdBQUc7TUFDVixTQUFTLEVBQUUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7TUFDN0QsVUFBVSxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztJQUMvRCxDQUFDLENBQUM7SUFDRixZQUFZLENBQUMsT0FBTyxDQUFDLFFBQVEsR0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDO0VBQzlDLENBQUMsQ0FBRSxPQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNoQixDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQU0sSUFBSSxHQUFBLE9BQUEsQ0FBQSxJQUFBLEdBQUcsU0FBUCxJQUFJLENBQVksR0FBRyxFQUFFO0VBQzFCLElBQUksR0FBRztFQUNQLElBQUk7SUFDSCxJQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLFFBQVEsR0FBQyxHQUFHLENBQUM7SUFDcEQsSUFBSyxTQUFTLEtBQUssRUFBRSxFQUFHO01BQ3ZCLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztJQUM1QjtFQUNELENBQUMsQ0FBRSxPQUFNLENBQUMsRUFBRTtJQUNYLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLEdBQUcsR0FBRyxHQUFHLDJCQUEyQixDQUFDO0lBQ3pFLE9BQU8sQ0FBQyxHQUFHLENBQ1YsSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLEdBQUcsWUFBWSxHQUFHLENBQUMsQ0FBQyxPQUFPLElBQ3RDLENBQUMsQ0FBQyxFQUFFLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQzNCLENBQUMsQ0FBQyxJQUFJLEdBQUcsU0FBUyxHQUFHLENBQUMsQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUNuQyxDQUFDO0VBQ0Y7RUFDQSxPQUFPLEdBQUcsSUFBSSxJQUFJO0FBQ25CLENBQUM7QUFFRCxJQUFNLFVBQVUsR0FBRyxTQUFiLFVBQVUsQ0FBRyxHQUFHO0VBQUEsT0FBSSxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO0FBQUE7QUFFNUQsSUFBTSxrQkFBa0IsR0FBQSxPQUFBLENBQUEsa0JBQUEsR0FBRyxTQUFyQixrQkFBa0IsQ0FBWSxHQUFHLEVBQUU7RUFDeEMsSUFBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRztJQUN2QjtFQUNEO0VBQ0EsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFDLEVBQUUsQ0FBQyxDQUFDO0VBQzNDLElBQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFBLGlCQUFXLEVBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztFQUMzRSxJQUFLLFNBQVMsRUFBRztJQUNoQixZQUFZLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztFQUM3QjtBQUNELENBQUM7QUFFRCxJQUFNLGlCQUFpQixHQUFBLE9BQUEsQ0FBQSxpQkFBQSxHQUFHLFNBQXBCLGlCQUFpQixDQUFBLEVBQWM7RUFDcEM7RUFDQSxLQUFLLElBQUksQ0FBQyxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUM5QyxVQUFVLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDekQ7QUFDRCxDQUFDO0FBRUQsSUFBTSxhQUFhLEdBQUEsT0FBQSxDQUFBLGFBQUEsR0FBRyxTQUFoQixhQUFhLENBQUEsRUFBYztFQUNoQztFQUNBLEtBQUssSUFBSSxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO0lBQzlDLElBQUksR0FBRyxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzdCLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO01BQ3BCLFlBQVksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO0lBQzdCO0VBQ0Q7QUFDRCxDQUFDOztBQUdEOzs7Ozs7Ozs7QUNqRkE7QUFDQSxJQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7QUFDOUMsSUFBSSxPQUFPLEdBQUcsV0FBVyxDQUFDLE9BQU87O0FBRWpDO0FBQ0EsSUFBSSxNQUFNLEdBQUc7RUFDWjtFQUNBLE1BQU0sRUFBRTtJQUNQO0lBQ0EsTUFBTSxrQkFBQSxNQUFBLENBQW1CLE9BQU8sY0FBVztJQUMzQyxPQUFPLEVBQUU7RUFDVixDQUFDO0VBQ0Q7RUFDQSxZQUFZLEVBQUU7SUFDYixXQUFXLEVBQUUsS0FBSztJQUNsQixvQkFBb0IsRUFBRSxLQUFLO0lBQzNCLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzFCLGFBQWEsRUFBRSxDQUFDO0lBQ2hCLGlCQUFpQixFQUFFLElBQUk7SUFDdkIseUJBQXlCLEVBQUUsSUFBSTtJQUMvQix1QkFBdUIsRUFBRSxJQUFJO0lBQzdCLG9CQUFvQixFQUFFLElBQUk7SUFDMUIsMEJBQTBCLEVBQUUsQ0FBQztJQUM3QixXQUFXLEVBQUU7RUFDZCxDQUFDO0VBQ0Q7RUFDQSxFQUFFLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUUsQ0FDbEIsTUFBTSxFQUNOLFlBQVksRUFDWixtQkFBbUIsRUFDbkIsWUFBWSxFQUNaLHVCQUF1QixFQUN2QixjQUFjLEVBQ2QsY0FBYyxFQUNkLGNBQWMsRUFDZCxVQUFVLEVBQ1YsY0FBYyxFQUNkLGNBQWMsQ0FDYixDQUFDO0VBQ0gsY0FBYyxFQUFFO0lBQ2YsT0FBTyxFQUFFLENBQ1IsSUFBSSxFQUNKLElBQUksRUFDSixHQUFHLEVBQ0gsSUFBSSxFQUNKLEdBQUcsRUFDSCxHQUFHLEVBQ0gsT0FBTyxFQUNQLE1BQU0sRUFDTixNQUFNLENBQ047SUFDRCxXQUFXLEVBQUUsQ0FDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLEtBQUssRUFDTCxLQUFLLENBQ0w7SUFDRCxlQUFlLEVBQUUsQ0FDaEIsVUFBVSxFQUNWLE9BQU8sRUFDUCxNQUFNLEVBQ04sSUFBSSxFQUNKLFFBQVEsRUFDUixTQUFTLEVBQ1QsVUFBVSxFQUNWLE9BQU8sRUFDUCxRQUFRLEVBQ1IsU0FBUyxFQUNULFVBQVUsRUFDVixJQUFJLEVBQ0osVUFBVSxFQUNWLE1BQU0sQ0FDTjtJQUNELG1CQUFtQixFQUFFLENBQ3BCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLEtBQUssRUFDTCxRQUFRLEVBQ1IsSUFBSTtFQUVOLENBQUM7RUFDRCxhQUFhLEVBQUU7SUFDZCw4QkFBOEIsRUFBRTtNQUMvQixPQUFPLEVBQUUsQ0FDUixJQUFJLEVBQ0osSUFBSSxFQUNKLEdBQUcsRUFDSCxJQUFJLEVBQ0osR0FBRyxFQUNILEdBQUcsRUFDSCxPQUFPLEVBQ1AsTUFBTSxFQUNOLE1BQU0sRUFDTixJQUFJLEVBQ0osSUFBSSxFQUNKLElBQUksRUFDSixVQUFVLEVBQ1YsT0FBTyxFQUNQLE1BQU0sRUFDTixRQUFRLEVBQ1IsU0FBUyxFQUNULFVBQVUsRUFDVixVQUFVLEVBQ1YsVUFBVSxFQUNWLE1BQU0sQ0FDTjtNQUNELFdBQVcsRUFBRTtJQUNkLENBQUM7SUFDRCxxQkFBcUIsRUFBRTtNQUN0QixPQUFPLEVBQUUsQ0FDUixLQUFLLEVBQ0wsVUFBVSxFQUNWLGFBQWEsRUFDYixPQUFPLEVBQ1AsWUFBWSxFQUNaLE1BQU0sRUFDTixNQUFNLEVBQ04sVUFBVSxFQUNWLE9BQU8sRUFDUCxNQUFNLEVBQ04sU0FBUyxFQUNULFVBQVUsRUFDVixVQUFVLEVBQ1YsSUFBSSxFQUNKLFVBQVUsQ0FDVjtNQUNELFdBQVcsRUFBRSxDQUNaLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLEtBQUssRUFDTCxRQUFRLEVBQ1IsSUFBSTtJQUVOLENBQUM7SUFDRCx5QkFBeUIsRUFBRTtNQUMxQixPQUFPLEVBQUUsQ0FDUixJQUFJLEVBQUMsSUFBSSxFQUFDLElBQUksRUFBQyxJQUFJLEVBQUMsR0FBRyxFQUFDLEdBQUcsRUFBQyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sRUFBQyxVQUFVLEVBQUMsT0FBTyxFQUFDLE1BQU0sRUFBQyxRQUFRLEVBQUMsU0FBUyxFQUFDLFVBQVUsRUFBQyxVQUFVLEVBQUMsVUFBVSxDQUMvSDtNQUNELFdBQVcsRUFBRSxDQUNaLEtBQUssRUFBQyxNQUFNLEVBQUMsS0FBSyxFQUFDLEtBQUssRUFBQyxJQUFJO0lBRS9CO0VBQ0QsQ0FBQztFQUNELGNBQWMsRUFBRSxDQUNmLDBCQUEwQixFQUMxQixvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLEtBQUssRUFDTCxNQUFNLEVBQ04sd0JBQXdCLEVBQ3hCLDBCQUEwQixFQUMxQixLQUFLLEVBQ0wsZUFBZSxFQUNmLE1BQU0sRUFDTixvQkFBb0IsRUFDcEIsaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQixhQUFhLEVBQ2IsMEJBQTBCLEVBQzFCLDJCQUEyQixFQUMzQix5QkFBeUIsRUFDekIsd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6Qix3QkFBd0IsRUFDeEIsbUNBQW1DLEVBQ25DLG1CQUFtQixFQUNuQixjQUFjLEVBQ2QsYUFBYSxFQUNiLGVBQWUsRUFDZixvQkFBb0IsQ0FDcEI7RUFDRCxvQkFBb0IsRUFBRTtJQUNyQixNQUFNLEVBQUU7TUFDUCxPQUFPLEVBQUU7UUFDUixJQUFJLEVBQUU7TUFDUCxDQUFDO01BQ0QsYUFBYSxFQUFFO1FBQ2QsSUFBSSxFQUFFO01BQ1AsQ0FBQztNQUNELFdBQVcsRUFBRTtJQUNkLENBQUM7SUFDRCxRQUFRLEVBQUU7TUFDVCxPQUFPLEVBQUU7UUFDUixJQUFJLEVBQUU7TUFDUCxDQUFDO01BQ0QsYUFBYSxFQUFFO1FBQ2QsSUFBSSxFQUFFO01BQ1A7SUFDRCxDQUFDO0lBQ0QsT0FBTyxFQUFFO01BQ1IsT0FBTyxFQUFFO1FBQ1IsSUFBSSxFQUFFO01BQ1AsQ0FBQztNQUNELGFBQWEsRUFBRTtRQUNkLElBQUksRUFBRTtNQUNQLENBQUM7TUFDRCxXQUFXLEVBQUU7SUFDZCxDQUFDO0lBQ0QsV0FBVyxFQUFFO01BQ1osT0FBTyxFQUFFO1FBQ1IsSUFBSSxFQUFFO01BQ1AsQ0FBQztNQUNELGFBQWEsRUFBRTtRQUNkLElBQUksRUFBRTtNQUNQLENBQUM7TUFDRCxXQUFXLEVBQUU7SUFDZCxDQUFDO0lBQ0QsYUFBYSxFQUFFO01BQ2QsT0FBTyxFQUFFO1FBQ1IsSUFBSSxFQUFFO01BQ1AsQ0FBQztNQUNELGFBQWEsRUFBRTtRQUNkLElBQUksRUFBRTtNQUNQLENBQUM7TUFDRCxTQUFTLEVBQUUsQ0FDVixhQUFhLENBQ2I7TUFDRCxXQUFXLEVBQUUsS0FBSztNQUNsQixXQUFXLEVBQUU7SUFDZCxDQUFDO0lBQ0QsZUFBZSxFQUFFO01BQ2hCLE9BQU8sRUFBRTtRQUNSLElBQUksRUFBRTtNQUNQLENBQUM7TUFDRCxhQUFhLEVBQUU7UUFDZCxJQUFJLEVBQUU7TUFDUCxDQUFDO01BQ0QsU0FBUyxFQUFFLENBQ1YsYUFBYSxDQUNiO01BQ0QsV0FBVyxFQUFFLEtBQUs7TUFDbEIsV0FBVyxFQUFFO0lBQ2Q7RUFDRDtBQUNELENBQUM7QUFBQyxJQUFBLFFBQUEsR0FBQSxPQUFBLGNBRWEsTUFBTSxFQUNyQjs7Ozs7Ozs7O0FDL09BOztBQUVBO0FBQ0EsSUFBTSxNQUFNLEdBQUcsNmxEQTZCZjtBQUNBO0FBQ0E7QUFDQTtBQUFBLHFOQVFFLEdBQ0Y7QUFDQTtBQUNBO0FBQUEsMExBS0M7QUFBQyxJQUFBLFFBQUEsR0FBQSxPQUFBLGNBRWEsTUFBTSxFQUNyQjs7Ozs7Ozs7OztBQ3REQSxJQUFBLElBQUEsR0FBQSx1QkFBQSxDQUFBLE9BQUE7QUFDQSxJQUFBLEtBQUEsR0FBQSxPQUFBO0FBQ0EsSUFBQSxLQUFBLEdBQUEsdUJBQUEsQ0FBQSxPQUFBO0FBQWlDLFNBQUEsd0JBQUEsQ0FBQSxFQUFBLENBQUEsNkJBQUEsT0FBQSxNQUFBLENBQUEsT0FBQSxPQUFBLElBQUEsQ0FBQSxPQUFBLE9BQUEsWUFBQSx1QkFBQSxZQUFBLHdCQUFBLENBQUEsRUFBQSxDQUFBLFNBQUEsQ0FBQSxJQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxTQUFBLENBQUEsTUFBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLENBQUEsS0FBQSxTQUFBLG1CQUFBLENBQUEsaUJBQUEsQ0FBQSxnQkFBQSxPQUFBLENBQUEsQ0FBQSwwQkFBQSxDQUFBLFNBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxDQUFBLEdBQUEsQ0FBQSxHQUFBLENBQUEsUUFBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsVUFBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsRUFBQSxDQUFBLGNBQUEsRUFBQSxJQUFBLENBQUEsZ0JBQUEsRUFBQSxPQUFBLGNBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsT0FBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLE1BQUEsQ0FBQSxjQUFBLEtBQUEsTUFBQSxDQUFBLHdCQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsT0FBQSxDQUFBLENBQUEsR0FBQSxJQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsQ0FBQSxDQUFBLENBQUEsRUFBQSxFQUFBLEVBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsV0FBQSxDQUFBLEtBQUEsQ0FBQSxFQUFBLENBQUE7QUFDakM7O0FBRUEsSUFBSSxZQUFZLEdBQUcsU0FBZixZQUFZLENBQVksT0FBTyxFQUFFO0VBQ3BDLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0FBQ3ZDLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksdUJBQXVCLEdBQUcsU0FBMUIsdUJBQXVCLENBQUEsRUFBYztFQUV4QyxJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7RUFFbEMsSUFBSSxhQUFhLEdBQUc7SUFDbkIsTUFBTSxFQUFFLE9BQU87SUFDZixNQUFNLEVBQUUsTUFBTTtJQUNkLElBQUksRUFBRSxpQkFBaUI7SUFDdkIsTUFBTSxFQUFFLE9BQU87SUFDZixXQUFXLEVBQUUsSUFBSTtJQUNqQixPQUFPLEVBQUU7RUFDVixDQUFDO0VBRUQsSUFBSSxVQUFVLEdBQUcsQ0FDaEI7SUFDQyxLQUFLLEVBQUUsc0RBQXNEO0lBQzdELFlBQVksRUFBRSxhQUFhO0lBQzNCLE9BQU8sRUFBRSxFQUFFO0lBQ1gsU0FBUyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUM7RUFDdkIsQ0FBQyxFQUNEO0lBQ0MsS0FBSyxFQUFFLHlEQUF5RDtJQUNoRSxZQUFZLEVBQUUsZ0JBQWdCO0lBQzlCLE9BQU8sRUFBRSxFQUFFO0lBQ1gsU0FBUyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUM7RUFDdkIsQ0FBQyxFQUNEO0lBQ0MsS0FBSyxFQUFFLCtDQUErQztJQUN0RCxZQUFZLEVBQUUsVUFBVTtJQUN4QixPQUFPLEVBQUUsRUFBRTtJQUNYLFNBQVMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDO0VBQ3ZCLENBQUMsRUFDRDtJQUNDLEtBQUssRUFBRSxpRUFBaUU7SUFDeEUsWUFBWSxFQUFFLFNBQVM7SUFDdkIsT0FBTyxFQUFFLEVBQUU7SUFDWCxTQUFTLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQztFQUN2QixDQUFDLEVBQ0Q7SUFDQyxLQUFLLEVBQUUsdUNBQXVDO0lBQzlDLFlBQVksRUFBRSxVQUFVO0lBQ3hCLE9BQU8sRUFBRSxFQUFFO0lBQ1gsU0FBUyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUM7RUFDdkIsQ0FBQyxFQUNEO0lBQ0MsS0FBSyxFQUFFLHlEQUF5RDtJQUNoRSxZQUFZLEVBQUUsS0FBSztJQUNuQixPQUFPLEVBQUUsRUFBRTtJQUNYLFNBQVMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDO0VBQ3ZCLENBQUMsQ0FDRDtFQUVELElBQUksWUFBWSxHQUFHLFNBQWYsWUFBWSxDQUFZLE1BQU0sRUFBRSxRQUFRLEVBQUU7SUFDN0MsSUFBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsRUFBRztNQUNyRDtNQUNBO01BQ0EsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO01BQ3hCO0lBQ0Q7O0lBRUE7SUFDQSxJQUFJLFlBQVksR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsVUFBUyxJQUFJLEVBQUU7TUFDbEUsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDM0IsQ0FBQyxDQUFDO0lBQ0YsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDOztJQUV0RTtJQUNBLElBQUssTUFBTSxZQUFTLEVBQUc7TUFDdEIsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLFlBQVMsQ0FBQyxFQUFFLFFBQVEsQ0FBQztNQUMzRTtJQUNEO0lBRUEsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztFQUN6QyxDQUFDO0VBRUQsSUFBSSxVQUFVLEdBQUcsU0FBYixVQUFVLENBQVksQ0FBQyxFQUFFLFFBQVEsRUFBRTtJQUN0QyxlQUFHLENBQUMsR0FBRyxDQUFFLENBQUUsQ0FBQyxDQUNWLElBQUksQ0FBRSxVQUFTLE1BQU0sRUFBRTtNQUN2QixZQUFZLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQztJQUMvQixDQUFFLENBQUMsQ0FDRixJQUFJLENBQUUsVUFBUyxJQUFJLEVBQUUsS0FBSyxFQUFFO01BQzVCLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUEsaUJBQVksRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLG1DQUFtQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUM7TUFDNUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3pCLENBQUUsQ0FBQztFQUNMLENBQUM7RUFFRCxVQUFVLENBQUMsT0FBTyxDQUFDLFVBQVMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUU7SUFDNUMsR0FBRyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFFO01BQUUsU0FBUyxFQUFDLEdBQUcsQ0FBQztJQUFNLENBQUMsRUFBRSxhQUFjLENBQUM7SUFDOUQsQ0FBQyxDQUFDLElBQUksQ0FBRSxHQUFHLENBQUMsS0FBSyxHQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxLQUFLLEdBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxJQUFJLElBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFVO01BQ3ZFLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQztJQUM3QixDQUFDLENBQUM7RUFDSCxDQUFDLENBQUM7RUFFRixVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVU7SUFDeEQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBQSxTQUFTLEVBQUk7TUFDL0IsT0FBTyxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsR0FBRyxTQUFTLENBQUMsT0FBTztJQUNwRCxDQUFDLENBQUM7SUFFRixlQUFlLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQztFQUNqQyxDQUFDLENBQUM7RUFFRixPQUFPLGVBQWU7QUFDdkIsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxtQkFBbUIsR0FBRyxTQUF0QixtQkFBbUIsQ0FBQSxFQUFjO0VBQ3BDLElBQUksYUFBYSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO0VBQ3pDLElBQ0MsQ0FBQyxhQUFhLElBQ2QsQ0FBQyxhQUFhLENBQUMsS0FBSyxJQUNwQixDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQ3ZCO0lBQ0QsT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztFQUM3QjtFQUNBLElBQUssSUFBQSxpQkFBVyxFQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsRUFBRztJQUMzQztJQUNBLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO0VBQzdDO0VBQ0EsT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztBQUNqRCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxjQUFjLEdBQUEsT0FBQSxDQUFBLGNBQUEsR0FBRyxTQUFqQixjQUFjLENBQUE7RUFBQSxPQUFTLG1CQUFtQixDQUFDLENBQUMsQ0FDOUMsSUFBSSxDQUFFLFVBQUEsT0FBTyxFQUFJO0lBQ2pCO0lBQ0EsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRTtNQUNsSSx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztNQUM1QyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQ2Q7UUFBRSxXQUFXLEVBQUUsRUFBRTtRQUFFLGNBQWMsRUFBRSxFQUFFO1FBQUUsUUFBUSxFQUFFLEVBQUU7UUFBRSxPQUFPLEVBQUUsRUFBRTtRQUFFLFFBQVEsRUFBRSxFQUFFO1FBQUUsR0FBRyxFQUFFO01BQUcsQ0FBQyxFQUN6RixPQUNELENBQUM7SUFDRjtJQUNBO0lBQ0EsT0FBTyxPQUFPO0VBQ2YsQ0FBRSxDQUFDLFNBQ0csQ0FBRSxZQUFNO0lBQ2I7SUFDQSxJQUFJLGNBQWMsR0FBRyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzlDLGNBQWMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQ2pDLE9BQU8sY0FBYztFQUN0QixDQUFFLENBQUM7QUFBQTs7QUFHSjs7Ozs7Ozs7OztBQ3JLQSxJQUFBLElBQUEsR0FBQSxzQkFBQSxDQUFBLE9BQUE7QUFDQSxJQUFBLEtBQUEsR0FBQSxPQUFBO0FBQ0EsSUFBQSxPQUFBLEdBQUEsc0JBQUEsQ0FBQSxPQUFBO0FBQ0EsSUFBQSxLQUFBLEdBQUEsdUJBQUEsQ0FBQSxPQUFBO0FBQWlDLFNBQUEsd0JBQUEsQ0FBQSxFQUFBLENBQUEsNkJBQUEsT0FBQSxNQUFBLENBQUEsT0FBQSxPQUFBLElBQUEsQ0FBQSxPQUFBLE9BQUEsWUFBQSx1QkFBQSxZQUFBLHdCQUFBLENBQUEsRUFBQSxDQUFBLFNBQUEsQ0FBQSxJQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxTQUFBLENBQUEsTUFBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLENBQUEsS0FBQSxTQUFBLG1CQUFBLENBQUEsaUJBQUEsQ0FBQSxnQkFBQSxPQUFBLENBQUEsQ0FBQSwwQkFBQSxDQUFBLFNBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxDQUFBLEdBQUEsQ0FBQSxHQUFBLENBQUEsUUFBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsVUFBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsR0FBQSxDQUFBLENBQUEsRUFBQSxDQUFBLGNBQUEsRUFBQSxJQUFBLENBQUEsZ0JBQUEsRUFBQSxPQUFBLGNBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsT0FBQSxDQUFBLElBQUEsQ0FBQSxHQUFBLE1BQUEsQ0FBQSxjQUFBLEtBQUEsTUFBQSxDQUFBLHdCQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsT0FBQSxDQUFBLENBQUEsR0FBQSxJQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsQ0FBQSxDQUFBLENBQUEsRUFBQSxFQUFBLEVBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsV0FBQSxDQUFBLEtBQUEsQ0FBQSxFQUFBLENBQUE7QUFBQSxTQUFBLHVCQUFBLENBQUEsV0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFVBQUEsR0FBQSxDQUFBLGdCQUFBLENBQUE7QUFDakM7O0FBRUEsSUFBTSxTQUFTLFdBQUEsTUFBQSxDQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxD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LE9BQUEsY0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxPQUFBLENBQUEsSUFBQSxDQUFBLEdBQUEsTUFBQSxDQUFBLGNBQUEsS0FBQSxNQUFBLENBQUEsd0JBQUEsQ0FBQSxDQUFBLEVBQUEsRUFBQSxPQUFBLENBQUEsQ0FBQSxHQUFBLElBQUEsQ0FBQSxDQUFBLEdBQUEsSUFBQSxDQUFBLENBQUEsQ0FBQSxFQUFBLEVBQUEsRUFBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLEVBQUEsSUFBQSxDQUFBLENBQUEsRUFBQSxXQUFBLENBQUEsS0FBQSxDQUFBLEVBQUEsQ0FBQTtBQUFBLFNBQUEsdUJBQUEsQ0FBQSxXQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsVUFBQSxHQUFBLENBQUEsZ0JBQUEsQ0FBQTtBQUFBLFNBQUEsUUFBQSxDQUFBLEVBQUEsQ0FBQSxRQUFBLENBQUEsR0FBQSxNQUFBLENBQUEsSUFBQSxDQUFBLENBQUEsT0FBQSxNQUFBLENBQUEscUJBQUEsUUFBQSxDQUFBLEdBQUEsTUFBQSxDQUFBLHFCQUFBLENBQUEsQ0FBQSxHQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsQ0FBQSxDQUFBLE1BQUEsV0FBQSxDQUFBLFdBQUEsTUFBQSxDQUFBLHdCQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsRUFBQSxVQUFBLE9BQUEsQ0FBQSxDQUFBLElBQUEsQ0FBQSxLQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsWUFBQSxDQUFBO0FBQUEsU0FBQSxjQUFBLENBQUEsYUFBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLFNBQUEsQ0FBQSxNQUFBLEVBQUEsQ0FBQSxVQUFBLENBQUEsV0FBQSxTQUFBLENBQUEsQ0FBQSxJQUFBLFNBQUEsQ0FBQSxDQUFBLFFBQUEsQ0FBQSxPQUFBLE9BQUEsQ0FBQSxNQUFBLENBQUEsQ0FBQSxPQUFBLE9BQUEsV0FBQSxDQUFBLElBQUEsZUFBQSxDQUFBLENBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQSxDQUFBLENBQUEsU0FBQSxNQUFBLENBQUEseUJBQUEsR0FBQSxNQUFBLENBQUEsZ0JBQUEsQ0FBQSxDQUFBLEVBQUEsTUFBQSxDQUFBLHlCQUFBLENBQUEsQ0FBQSxLQUFBLE9BQUEsQ0FBQSxNQUFBLENBQUEsQ0FBQSxHQUFBLE9BQUEsV0FBQSxDQUFBLElBQUEsTUFBQSxDQUFBLGNBQUEsQ0FBQSxDQUFBLEVBQUEsQ0FBQSxFQUFBLE1BQUEsQ0FBQSx3QkFBQSxDQUFBLENBQUEsRUFBQSxDQUFBLGlCQUFBLENBQUE7QUFBQSxTQUFBLGdCQUFBLENBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQSxZQUFBLENBQUEsR0FBQSxjQUFBLENBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxNQUFBLENBQUEsY0FBQSxDQUFBLENBQUEsRUFBQSxDQUFBLElBQUEsS0FBQSxFQUFBLENBQUEsRUFBQSxVQUFBLE1BQUEsWUFBQSxNQUFBLFFBQUEsVUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsRUFBQSxDQUFBO0FBQUEsU0FBQSxlQUFBLENBQUEsUUFBQSxDQUFBLEdBQUEsWUFBQSxDQUFBLENBQUEsZ0NBQUEsT0FBQSxDQUFBLENBQUEsSUFBQSxDQUFBLEdBQUEsQ0FBQTtBQUFBLFNBQUEsYUFBQSxDQUFBLEVBQUEsQ0FBQSxvQkFBQSxPQUFBLENBQUEsQ0FBQSxNQUFBLENBQUEsU0FBQSxDQUFBLE1BQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxNQUFBLENBQUEsV0FBQSxrQkFBQSxDQUFBLFFBQUEsQ0FBQSxHQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxFQUFBLENBQUEsZ0NBQUEsT0FBQSxDQUFBLENBQUEsVUFBQSxDQUFBLFlBQUEsU0FBQSx5RUFBQSxDQUFBLEdBQUEsTUFBQSxHQUFBLE1BQUEsRUFBQSxDQUFBO0FBQUEsU0FBQSxtQkFBQSxDQUFBLFdBQUEsa0JBQUEsQ0FBQSxDQUFBLEtBQUEsZ0JBQUEsQ0FBQSxDQUFBLEtBQUEsMkJBQUEsQ0FBQSxDQUFBLEtBQUEsa0JBQUE7QUFBQSxTQUFBLG1CQUFBLGNBQUEsU0FBQTtBQUFBLFNBQUEsNEJBQUEsQ0FBQSxFQUFBLENBQUEs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OUM7O0FBRUEsSUFBSSxPQUFPLEdBQUcsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUM7O0FBRTlCO0FBQ0EsT0FBTyxDQUFDLFFBQVEsQ0FBQyxzQkFBVSxDQUFDO0FBQzVCLE9BQU8sQ0FBQyxRQUFRLENBQUMsc0JBQVUsQ0FBQztBQUU1QixJQUFJLE9BQU8sR0FBRyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFFO0VBQ3RDLFNBQVMsRUFBRTtBQUNaLENBQUUsQ0FBQztBQUNIO0FBQ0E7QUFDQSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBRSxxQkFBc0IsQ0FBQztBQUNsRCxDQUFDLENBQUUsUUFBUSxDQUFDLElBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBRSxPQUFPLENBQUMsUUFBUyxDQUFDO0FBQUMsSUFBQSxRQUFBLEdBQUEsT0FBQSxjQUUvQixPQUFPLEVBQ3RCIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIm5hbWVcIjogXCJyYXRlclwiLFxuICBcInZlcnNpb25cIjogXCIyLjcuMlwiLFxuICBcImRlc2NyaXB0aW9uXCI6IFwiV2lraXBlZGlhIHVzZXJzY3JpcHQgdGhhdCBoZWxwcyBhc3Nlc3MgcGFnZXMgZm9yIFdpa2lQcm9qZWN0c1wiLFxuICBcImhvbWVwYWdlXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2V2YWQzNy9yYXRlclwiLFxuICBcImJyb3dzZXJcIjogXCJpbmRleC5qc1wiLFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwidGVzdFwiOiBcImVjaG8gXFxcIkVycm9yOiBubyB0ZXN0IHNwZWNpZmllZFxcXCIgJiYgZXhpdCAxXCIsXG4gICAgXCJsaW50OmVzNVwiOiBcImpzaGludCBpbmRleC5qc1wiLFxuICAgIFwibGludDplczZcIjogXCJlc2xpbnQgaW5kZXguanMgXFxcInJhdGVyLXNyYy8qKlxcXCJcIixcbiAgICBcImxpbnQ6Zml4XCI6IFwiZXNsaW50IGluZGV4LmpzIFxcXCJyYXRlci1zcmMvKipcXFwiIC0tZml4XCIsXG4gICAgXCJsaW50XCI6IFwibnBtIHJ1biBsaW50OmVzNiAmJiBucG0gcnVuIGxpbnQ6ZXM1XCIsXG4gICAgXCJidWlsZDpidW5kbGVcIjogXCJicm93c2VyaWZ5IHJhdGVyLXNyYy9BcHAuanMgLS1kZWJ1ZyAtdCBiYWJlbGlmeSAtLW91dGZpbGUgZGlzdC9yYXRlci5qc1wiLFxuICAgIFwiYnVpbGQ6bWluaWZ5XCI6IFwidWdsaWZ5anMgZGlzdC9yYXRlci5qcyAtLWNvbXByZXNzIC1iIGFzY2lpX29ubHk9dHJ1ZSxiZWF1dGlmeT1mYWxzZSAtLW91dHB1dCBkaXN0L3JhdGVyLm1pbi5qc1wiLFxuICAgIFwiYnVpbGQ6Y29uY2F0XCI6IFwiY29uY2F0LWNsaSAtZiBcXFwiY29tbWVudC10b3AuanNcXFwiIGRpc3QvcmF0ZXIubWluLmpzIFxcXCJjb21tZW50LWJvdHRvbS5qc1xcXCIgLW8gZGlzdC9yYXRlci5taW4uanNcIixcbiAgICBcImJ1aWxkXCI6IFwibnBtIHJ1biBsaW50ICYmIG5wbSBydW4gYnVpbGQ6YnVuZGxlICYmIG5wbSBydW4gYnVpbGQ6bWluaWZ5ICYmIG5wbSBydW4gYnVpbGQ6Y29uY2F0XCJcbiAgfSxcbiAgXCJhdXRob3JcIjoge1xuICAgIFwibmFtZVwiOiBcIkV2YWQzN1wiLFxuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVXNlcjpFdmFkMzdcIlxuICB9LFxuICBcInJlcG9zaXRvcnlcIjoge1xuICAgIFwidHlwZVwiOiBcImdpdFwiLFxuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2V2YWQzNy9yYXRlci5naXRcIlxuICB9LFxuICBcImxpY2Vuc2VcIjogXCIoTUlUIE9SIENDLUJZLTQuMClcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQGJhYmVsL2NvcmVcIjogXCJeNy45LjBcIixcbiAgICBcIkBiYWJlbC9wcmVzZXQtZW52XCI6IFwiXjcuOS4wXCIsXG4gICAgXCJiYWJlbGlmeVwiOiBcIl4xMC4wLjBcIixcbiAgICBcImJyb3dzZXJpZnlcIjogXCJeMTYuNS4wXCIsXG4gICAgXCJjb25jYXQtY2xpXCI6IFwiXjQuMC4wXCIsXG4gICAgXCJlc2xpbnRcIjogXCJeNi44LjBcIixcbiAgICBcImpzaGludFwiOiBcIl4yLjExLjBcIixcbiAgICBcInVnbGlmeS1qc1wiOiBcIl4zLjguMFwiXG4gIH1cbn1cbiIsImltcG9ydCBzZXR1cFJhdGVyIGZyb20gXCIuL3NldHVwXCI7XHJcbmltcG9ydCBhdXRvU3RhcnQgZnJvbSBcIi4vYXV0b3N0YXJ0XCI7XHJcbmltcG9ydCBzdHlsZXMgZnJvbSBcIi4vY3NzLmpzXCI7XHJcbmltcG9ydCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQgd2luZG93TWFuYWdlciBmcm9tIFwiLi93aW5kb3dNYW5hZ2VyXCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG4oZnVuY3Rpb24gQXBwKCkge1xyXG5cdGxldCBzdHlsZXNoZWV0O1xyXG5cclxuXHRjb25zdCBzaG93TWFpbldpbmRvdyA9IGRhdGEgPT4ge1xyXG5cdFx0aWYgKCFkYXRhIHx8ICFkYXRhLnN1Y2Nlc3MpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0aWYgKHN0eWxlc2hlZXQpIHtcclxuXHRcdFx0c3R5bGVzaGVldC5kaXNhYmxlZCA9IGZhbHNlO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c3R5bGVzaGVldCA9IG13LnV0aWwuYWRkQ1NTKHN0eWxlcyk7XHJcblx0XHR9XHJcblx0XHQvLyBBZGQgY3NzIGNsYXNzIHRvIGJvZHkgdG8gZW5hYmxlIGJhY2tncm91bmQgc2Nyb2xsaW5nXHJcblx0XHRkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImJvZHlcIilbMF0uY2xhc3NMaXN0LmFkZChcInJhdGVyLW1haW5XaW5kb3ctb3BlblwiKTtcclxuXHRcdC8vIE9wZW4gdGhlIHdpbmRvd1xyXG5cdFx0d2luZG93TWFuYWdlci5vcGVuV2luZG93KFwibWFpblwiLCBkYXRhKVxyXG5cdFx0XHQuY2xvc2VkLnRoZW4oIHJlc3VsdCA9PiB7XHJcblx0XHRcdFx0Ly8gRGlzYWJsZS9yZW1vdmUgdGhlIGNzcyBzdHlsZXMsIHNvIGFzIHRvIG5vdCBpbnRlcmZlcmUgd2l0aCBvdGhlciBzY3JpcHRzL2NvbnRlbnQvT09VSSB3aW5kb3dzXHJcblx0XHRcdFx0aWYgKHN0eWxlc2hlZXQpIHsgc3R5bGVzaGVldC5kaXNhYmxlZCA9IHRydWU7IH1cclxuXHRcdFx0XHRkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImJvZHlcIilbMF0uY2xhc3NMaXN0LnJlbW92ZShcInJhdGVyLW1haW5XaW5kb3ctb3BlblwiKTtcclxuXHRcdFx0XHQvLyBSZXN0YXJ0IGlmIG5lZWRlZFxyXG5cdFx0XHRcdGlmIChyZXN1bHQgJiYgcmVzdWx0LnJlc3RhcnQpIHtcclxuXHRcdFx0XHRcdHdpbmRvd01hbmFnZXIucmVtb3ZlV2luZG93cyhbXCJtYWluXCJdKVxyXG5cdFx0XHRcdFx0XHQudGhlbihzZXR1cFJhdGVyKVxyXG5cdFx0XHRcdFx0XHQudGhlbihzaG93TWFpbldpbmRvdywgc2hvd1NldHVwRXJyb3IpO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHQvLyBTaG93IG5vdGlmaWNhdGlvbiB3aGVuIHNhdmVkIHN1Y2Nlc3NmdWxseVxyXG5cdFx0XHRcdGlmIChyZXN1bHQgJiYgcmVzdWx0LnN1Y2Nlc3MpIHtcclxuXHRcdFx0XHRcdGNvbnN0ICRtZXNzYWdlID0gJChcIjxzcGFuPlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nPlwiKS50ZXh0KFwiUmF0aW5ncyBzYXZlZCBzdWNjZXNzZnVsbHkuXCIpXHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdFx0aWYgKHJlc3VsdC51cGdyYWRlZFN0dWIpIHtcclxuXHRcdFx0XHRcdFx0JG1lc3NhZ2UuYXBwZW5kKFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8YnI+XCIpLFxyXG5cdFx0XHRcdFx0XHRcdC8vIFRPRE86IFRoZXJlIHNob3VsZCBiZSBhIGxpbmsgdGhhdCB3aWxsIGVkaXQgdGhlIGFydGljbGUgZm9yIHlvdVxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8c3Bhbj5cIikudGV4dChcIk5vdGUgdGhhdCB0aGUgYXJ0aWNsZSBhcHBlYXJzIHRvIGJlIHRhZ2dlZCBhcyBhIHN0dWIuXCIpXHJcblx0XHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRtdy5ub3RpZnkoXHJcblx0XHRcdFx0XHRcdCRtZXNzYWdlLFxyXG5cdFx0XHRcdFx0XHR7IGF1dG9IaWRlOiB0cnVlLCBhdXRvSGlkZVNlY29uZHM6IFwibG9uZ1wiLCB0YWc6IFwiUmF0ZXItc2F2ZWRcIiB9XHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApO1xyXG5cdH07XHJcblxyXG5cdGNvbnN0IHNob3dTZXR1cEVycm9yID0gKGNvZGUsIGpxeGhyKSA9PiBPTy51aS5hbGVydChcclxuXHRcdG1ha2VFcnJvck1zZyhjb2RlLCBqcXhociksXHR7XHJcblx0XHRcdHRpdGxlOiBcIlJhdGVyIGZhaWxlZCB0byBvcGVuXCJcclxuXHRcdH1cclxuXHQpO1xyXG5cclxuXHQvLyBJbnZvY2F0aW9uIGJ5IHBvcnRsZXQgbGluayBcclxuXHRtdy51dGlsLmFkZFBvcnRsZXRMaW5rKFxyXG5cdFx0XCJwLWNhY3Rpb25zXCIsXHJcblx0XHRcIiNcIixcclxuXHRcdFwiUmF0ZXJcIixcclxuXHRcdFwiY2EtcmF0ZXJcIixcclxuXHRcdFwiUmF0ZSBxdWFsaXR5IGFuZCBpbXBvcnRhbmNlXCIsXHJcblx0XHRcIjVcIlxyXG5cdCk7XHJcblx0JChcIiNjYS1yYXRlclwiKS5jbGljayhldmVudCA9PiB7XHJcblx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0c2V0dXBSYXRlcigpLnRoZW4oc2hvd01haW5XaW5kb3csIHNob3dTZXR1cEVycm9yKTtcclxuXHR9KTtcclxuXHJcblx0Ly8gSW52b2NhdGlvbiBieSBhdXRvLXN0YXJ0IChkbyBub3Qgc2hvdyBtZXNzYWdlIG9uIGVycm9yKVxyXG5cdGF1dG9TdGFydCgpLnRoZW4oc2hvd01haW5XaW5kb3cpO1xyXG59KSgpO1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgQVBJIGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQge2lzQWZ0ZXJEYXRlLCBtb3N0RnJlcXVlbnQsIGZpbHRlckFuZE1hcH0gZnJvbSBcIi4vdXRpbFwiO1xyXG5pbXBvcnQgY29uZmlnIGZyb20gXCIuL2NvbmZpZ1wiO1xyXG5pbXBvcnQgKiBhcyBjYWNoZSBmcm9tIFwiLi9jYWNoZVwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxuLyoqIFRlbXBsYXRlXHJcbiAqXHJcbiAqIEBjbGFzc1xyXG4gKiBSZXByZXNlbnRzIHRoZSB3aWtpdGV4dCBvZiB0ZW1wbGF0ZSB0cmFuc2NsdXNpb24uIFVzZWQgYnkgI3BhcnNlVGVtcGxhdGVzLlxyXG4gKiBAcHJvcCB7U3RyaW5nfSBuYW1lIE5hbWUgb2YgdGhlIHRlbXBsYXRlXHJcbiAqIEBwcm9wIHtTdHJpbmd9IHdpa2l0ZXh0IEZ1bGwgd2lraXRleHQgb2YgdGhlIHRyYW5zY2x1c2lvblxyXG4gKiBAcHJvcCB7T2JqZWN0W119IHBhcmFtZXRlcnMgUGFyYW1ldGVycyB1c2VkIGluIHRoZSB0cmFuc2xjdXNpb24sIGluIG9yZGVyLCBvZiBmb3JtOlxyXG5cdHtcclxuXHRcdG5hbWU6IHtTdHJpbmd8TnVtYmVyfSBwYXJhbWV0ZXIgbmFtZSwgb3IgcG9zaXRpb24gZm9yIHVubmFtZWQgcGFyYW1ldGVycyxcclxuXHRcdHZhbHVlOiB7U3RyaW5nfSBXaWtpdGV4dCBwYXNzZWQgdG8gdGhlIHBhcmFtZXRlciAod2hpdGVzcGFjZSB0cmltbWVkKSxcclxuXHRcdHdpa2l0ZXh0OiB7U3RyaW5nfSBGdWxsIHdpa2l0ZXh0IChpbmNsdWRpbmcgbGVhZGluZyBwaXBlLCBwYXJhbWV0ZXIgbmFtZS9lcXVhbHMgc2lnbiAoaWYgYXBwbGljYWJsZSksIHZhbHVlLCBhbmQgYW55IHdoaXRlc3BhY2UpXHJcblx0fVxyXG4gKiBAY29uc3RydWN0b3JcclxuICogQHBhcmFtIHtTdHJpbmd9IHdpa2l0ZXh0IFdpa2l0ZXh0IG9mIGEgdGVtcGxhdGUgdHJhbnNjbHVzaW9uLCBzdGFydGluZyB3aXRoICd7eycgYW5kIGVuZGluZyB3aXRoICd9fScuXHJcbiAqL1xyXG52YXIgVGVtcGxhdGUgPSBmdW5jdGlvbih3aWtpdGV4dCkge1xyXG5cdHRoaXMud2lraXRleHQgPSB3aWtpdGV4dDtcclxuXHR0aGlzLnBhcmFtZXRlcnMgPSBbXTtcclxuXHQvLyBTcGFjaW5nIGFyb3VuZCBwaXBlcywgZXF1YWxzIHNpZ25zLCBlbmQgYnJhY2VzIChkZWZhdWx0cylcclxuXHR0aGlzLnBpcGVTdHlsZSA9IFwiIHxcIjtcclxuXHR0aGlzLmVxdWFsc1N0eWxlID0gXCI9XCI7XHJcblx0dGhpcy5lbmRCcmFjZXNTdHlsZSA9IFwifX1cIjtcclxufTtcclxuVGVtcGxhdGUucHJvdG90eXBlLmFkZFBhcmFtID0gZnVuY3Rpb24obmFtZSwgdmFsLCB3aWtpdGV4dCkge1xyXG5cdHRoaXMucGFyYW1ldGVycy5wdXNoKHtcclxuXHRcdFwibmFtZVwiOiBuYW1lLFxyXG5cdFx0XCJ2YWx1ZVwiOiB2YWwsIFxyXG5cdFx0XCJ3aWtpdGV4dFwiOiBcInxcIiArIHdpa2l0ZXh0XHJcblx0fSk7XHJcbn07XHJcbi8qKlxyXG4gKiBHZXQgYSBwYXJhbWV0ZXIgZGF0YSBieSBwYXJhbWV0ZXIgbmFtZVxyXG4gKi8gXHJcblRlbXBsYXRlLnByb3RvdHlwZS5nZXRQYXJhbSA9IGZ1bmN0aW9uKHBhcmFtTmFtZSkge1xyXG5cdHJldHVybiB0aGlzLnBhcmFtZXRlcnMuZmluZChmdW5jdGlvbihwKSB7IHJldHVybiBwLm5hbWUgPT0gcGFyYW1OYW1lOyB9KTtcclxufTtcclxuVGVtcGxhdGUucHJvdG90eXBlLnNldE5hbWUgPSBmdW5jdGlvbihuYW1lKSB7XHJcblx0dGhpcy5uYW1lID0gbmFtZS50cmltKCk7XHJcbn07XHJcblRlbXBsYXRlLnByb3RvdHlwZS5nZXRUaXRsZSA9IGZ1bmN0aW9uKCkge1xyXG5cdHJldHVybiBtdy5UaXRsZS5uZXdGcm9tVGV4dChcIlRlbXBsYXRlOlwiICsgdGhpcy5uYW1lKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBwYXJzZVRlbXBsYXRlc1xyXG4gKlxyXG4gKiBQYXJzZXMgdGVtcGxhdGVzIGZyb20gd2lraXRleHQuXHJcbiAqIEJhc2VkIG9uIFNEMDAwMSdzIHZlcnNpb24gYXQgPGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VzZXI6U0QwMDAxL3BhcnNlQWxsVGVtcGxhdGVzLmpzPi5cclxuICogUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoZSB0ZW1wbGF0ZSBkZXRhaWxzOlxyXG4gKiAgdmFyIHRlbXBsYXRlcyA9IHBhcnNlVGVtcGxhdGVzKFwiSGVsbG8ge3tmb28gfEJhcnxiYXo9cXV4IHwyPWxvcmVtaXBzdW18Mz19fSB3b3JsZFwiKTtcclxuICogIGNvbnNvbGUubG9nKHRlbXBsYXRlc1swXSk7IC8vIC0tPiBvYmplY3RcclxuXHR7XHJcblx0XHRuYW1lOiBcImZvb1wiLFxyXG5cdFx0d2lraXRleHQ6XCJ7e2ZvbyB8QmFyfGJhej1xdXggfCAyID0gbG9yZW1pcHN1bSAgfDM9fX1cIixcclxuXHRcdHBhcmFtZXRlcnM6IFtcclxuXHRcdFx0e1xyXG5cdFx0XHRcdG5hbWU6IDEsXHJcblx0XHRcdFx0dmFsdWU6ICdCYXInLFxyXG5cdFx0XHRcdHdpa2l0ZXh0OiAnfEJhcidcclxuXHRcdFx0fSxcclxuXHRcdFx0e1xyXG5cdFx0XHRcdG5hbWU6ICdiYXonLFxyXG5cdFx0XHRcdHZhbHVlOiAncXV4JyxcclxuXHRcdFx0XHR3aWtpdGV4dDogJ3xiYXo9cXV4ICdcclxuXHRcdFx0fSxcclxuXHRcdFx0e1xyXG5cdFx0XHRcdG5hbWU6ICcyJyxcclxuXHRcdFx0XHR2YWx1ZTogJ2xvcmVtaXBzdW0nLFxyXG5cdFx0XHRcdHdpa2l0ZXh0OiAnfCAyID0gbG9yZW1pcHN1bSAgJ1xyXG5cdFx0XHR9LFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0bmFtZTogJzMnLFxyXG5cdFx0XHRcdHZhbHVlOiAnJyxcclxuXHRcdFx0XHR3aWtpdGV4dDogJ3wzPSdcclxuXHRcdFx0fVxyXG5cdFx0XSxcclxuXHRcdGdldFBhcmFtOiBmdW5jdGlvbihwYXJhbU5hbWUpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMucGFyYW1ldGVycy5maW5kKGZ1bmN0aW9uKHApIHsgcmV0dXJuIHAubmFtZSA9PSBwYXJhbU5hbWU7IH0pO1xyXG5cdFx0fVxyXG5cdH1cclxuICogICAgXHJcbiAqIFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gd2lraXRleHRcclxuICogQHBhcmFtIHtCb29sZWFufSByZWN1cnNpdmUgU2V0IHRvIGB0cnVlYCB0byBhbHNvIHBhcnNlIHRlbXBsYXRlcyB0aGF0IG9jY3VyIHdpdGhpbiBvdGhlciB0ZW1wbGF0ZXMsXHJcbiAqICByYXRoZXIgdGhhbiBqdXN0IHRvcC1sZXZlbCB0ZW1wbGF0ZXMuIFxyXG4gKiBAcmV0dXJuIHtUZW1wbGF0ZVtdfSB0ZW1wbGF0ZXNcclxuKi9cclxudmFyIHBhcnNlVGVtcGxhdGVzID0gZnVuY3Rpb24od2lraXRleHQsIHJlY3Vyc2l2ZSkgeyAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb250cm9sLXJlZ2V4ICovXHJcblx0aWYgKCF3aWtpdGV4dCkge1xyXG5cdFx0cmV0dXJuIFtdO1xyXG5cdH1cclxuXHR2YXIgc3RyUmVwbGFjZUF0ID0gZnVuY3Rpb24oc3RyaW5nLCBpbmRleCwgY2hhcikge1xyXG5cdFx0cmV0dXJuIHN0cmluZy5zbGljZSgwLGluZGV4KSArIGNoYXIgKyBzdHJpbmcuc2xpY2UoaW5kZXggKyAxKTtcclxuXHR9O1xyXG5cclxuXHR2YXIgcmVzdWx0ID0gW107XHJcblx0XHJcblx0dmFyIHByb2Nlc3NUZW1wbGF0ZVRleHQgPSBmdW5jdGlvbiAoc3RhcnRJZHgsIGVuZElkeCkge1xyXG5cdFx0dmFyIHRleHQgPSB3aWtpdGV4dC5zbGljZShzdGFydElkeCwgZW5kSWR4KTtcclxuXHJcblx0XHR2YXIgdGVtcGxhdGUgPSBuZXcgVGVtcGxhdGUoXCJ7e1wiICsgdGV4dC5yZXBsYWNlKC9cXHgwMS9nLFwifFwiKSArIFwifX1cIik7XHJcblx0XHRcclxuXHRcdC8vIHN3YXAgb3V0IHBpcGUgaW4gbGlua3Mgd2l0aCBcXHgwMSBjb250cm9sIGNoYXJhY3RlclxyXG5cdFx0Ly8gW1tGaWxlOiBdXSBjYW4gaGF2ZSBtdWx0aXBsZSBwaXBlcywgc28gbWlnaHQgbmVlZCBtdWx0aXBsZSBwYXNzZXNcclxuXHRcdHdoaWxlICggLyhcXFtcXFtbXlxcXV0qPylcXHwoLio/XFxdXFxdKS9nLnRlc3QodGV4dCkgKSB7XHJcblx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2UoLyhcXFtcXFtbXlxcXV0qPylcXHwoLio/XFxdXFxdKS9nLCBcIiQxXFx4MDEkMlwiKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBGaWd1cmUgb3V0IG1vc3QtdXNlZCBzcGFjaW5nIHN0eWxlcyBmb3IgcGlwZXMvZXF1YWxzXHJcblx0XHR0ZW1wbGF0ZS5waXBlU3R5bGUgPSBtb3N0RnJlcXVlbnQoIHRleHQubWF0Y2goL1tcXHNcXG5dKlxcfFtcXHNcXG5dKi9nKSApIHx8IFwiIHxcIjtcclxuXHRcdHRlbXBsYXRlLmVxdWFsc1N0eWxlID0gbW9zdEZyZXF1ZW50KCB0ZXh0LnJlcGxhY2UoLyg9W158XSopPSsvZywgXCIkMVwiKS5tYXRjaCgvW1xcc1xcbl0qPVtcXHNcXG5dKi9nKSApIHx8IFwiPVwiO1xyXG5cdFx0Ly8gRmlndXJlIG91dCBlbmQtYnJhY2VzIHN0eWxlXHJcblx0XHR2YXIgZW5kU3BhY2luZyA9IHRleHQubWF0Y2goL1tcXHNcXG5dKiQvKTtcclxuXHRcdHRlbXBsYXRlLmVuZEJyYWNlc1N0eWxlID0gKGVuZFNwYWNpbmcgPyBlbmRTcGFjaW5nWzBdIDogXCJcIikgKyBcIn19XCI7XHJcblxyXG5cdFx0dmFyIGNodW5rcyA9IHRleHQuc3BsaXQoXCJ8XCIpLm1hcChmdW5jdGlvbihjaHVuaykge1xyXG5cdFx0XHQvLyBjaGFuZ2UgJ1xceDAxJyBjb250cm9sIGNoYXJhY3RlcnMgYmFjayB0byBwaXBlc1xyXG5cdFx0XHRyZXR1cm4gY2h1bmsucmVwbGFjZSgvXFx4MDEvZyxcInxcIik7IFxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGVtcGxhdGUuc2V0TmFtZShjaHVua3NbMF0pO1xyXG5cdFx0XHJcblx0XHR2YXIgcGFyYW1ldGVyQ2h1bmtzID0gY2h1bmtzLnNsaWNlKDEpO1xyXG5cclxuXHRcdHZhciB1bm5hbWVkSWR4ID0gMTtcclxuXHRcdHBhcmFtZXRlckNodW5rcy5mb3JFYWNoKGZ1bmN0aW9uKGNodW5rKSB7XHJcblx0XHRcdHZhciBpbmRleE9mRXF1YWxUbyA9IGNodW5rLmluZGV4T2YoXCI9XCIpO1xyXG5cdFx0XHR2YXIgaW5kZXhPZk9wZW5CcmFjZXMgPSBjaHVuay5pbmRleE9mKFwie3tcIik7XHJcblx0XHRcdFxyXG5cdFx0XHR2YXIgaXNXaXRob3V0RXF1YWxzID0gIWNodW5rLmluY2x1ZGVzKFwiPVwiKTtcclxuXHRcdFx0dmFyIGhhc0JyYWNlc0JlZm9yZUVxdWFscyA9IGNodW5rLmluY2x1ZGVzKFwie3tcIikgJiYgaW5kZXhPZk9wZW5CcmFjZXMgPCBpbmRleE9mRXF1YWxUbztcdFxyXG5cdFx0XHR2YXIgaXNVbm5hbWVkUGFyYW0gPSAoIGlzV2l0aG91dEVxdWFscyB8fCBoYXNCcmFjZXNCZWZvcmVFcXVhbHMgKTtcclxuXHRcdFx0XHJcblx0XHRcdHZhciBwTmFtZSwgcE51bSwgcFZhbDtcclxuXHRcdFx0aWYgKCBpc1VubmFtZWRQYXJhbSApIHtcclxuXHRcdFx0XHQvLyBHZXQgdGhlIG5leHQgbnVtYmVyIG5vdCBhbHJlYWR5IHVzZWQgYnkgZWl0aGVyIGFuIHVubmFtZWQgcGFyYW1ldGVyLCBvciBieSBhXHJcblx0XHRcdFx0Ly8gbmFtZWQgcGFyYW1ldGVyIGxpa2UgYHwxPXZhbGBcclxuXHRcdFx0XHR3aGlsZSAoIHRlbXBsYXRlLmdldFBhcmFtKHVubmFtZWRJZHgpICkge1xyXG5cdFx0XHRcdFx0dW5uYW1lZElkeCsrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRwTnVtID0gdW5uYW1lZElkeDtcclxuXHRcdFx0XHRwVmFsID0gY2h1bmsudHJpbSgpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHBOYW1lID0gY2h1bmsuc2xpY2UoMCwgaW5kZXhPZkVxdWFsVG8pLnRyaW0oKTtcclxuXHRcdFx0XHRwVmFsID0gY2h1bmsuc2xpY2UoaW5kZXhPZkVxdWFsVG8gKyAxKS50cmltKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0dGVtcGxhdGUuYWRkUGFyYW0ocE5hbWUgfHwgcE51bSwgcFZhbCwgY2h1bmspO1xyXG5cdFx0fSk7XHJcblx0XHRcclxuXHRcdHJlc3VsdC5wdXNoKHRlbXBsYXRlKTtcclxuXHR9O1xyXG5cclxuXHRcclxuXHR2YXIgbiA9IHdpa2l0ZXh0Lmxlbmd0aDtcclxuXHRcclxuXHQvLyBudW1iZXIgb2YgdW5jbG9zZWQgYnJhY2VzXHJcblx0dmFyIG51bVVuY2xvc2VkID0gMDtcclxuXHJcblx0Ly8gYXJlIHdlIGluc2lkZSBhIGNvbW1lbnQsIG9yIGJldHdlZW4gbm93aWtpIHRhZ3MsIG9yIGluIGEge3t7cGFyYW1ldGVyfX19P1xyXG5cdHZhciBpbkNvbW1lbnQgPSBmYWxzZTtcclxuXHR2YXIgaW5Ob3dpa2kgPSBmYWxzZTtcclxuXHR2YXIgaW5QYXJhbWV0ZXIgPSBmYWxzZTtcclxuXHJcblx0dmFyIHN0YXJ0SWR4LCBlbmRJZHg7XHJcblx0XHJcblx0Zm9yICh2YXIgaT0wOyBpPG47IGkrKykge1xyXG5cdFx0XHJcblx0XHRpZiAoICFpbkNvbW1lbnQgJiYgIWluTm93aWtpICYmICFpblBhcmFtZXRlciApIHtcclxuXHJcblx0XHRcdGlmICh3aWtpdGV4dFtpXSA9PT0gXCJ7XCIgJiYgd2lraXRleHRbaSsxXSA9PT0gXCJ7XCIgJiYgd2lraXRleHRbaSsyXSA9PT0gXCJ7XCIgJiYgd2lraXRleHRbaSszXSAhPT0gXCJ7XCIpIHtcclxuXHRcdFx0XHRpblBhcmFtZXRlciA9IHRydWU7XHJcblx0XHRcdFx0aSArPSAyO1xyXG5cdFx0XHR9IGVsc2UgaWYgKHdpa2l0ZXh0W2ldID09PSBcIntcIiAmJiB3aWtpdGV4dFtpKzFdID09PSBcIntcIikge1xyXG5cdFx0XHRcdGlmIChudW1VbmNsb3NlZCA9PT0gMCkge1xyXG5cdFx0XHRcdFx0c3RhcnRJZHggPSBpKzI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdG51bVVuY2xvc2VkICs9IDI7XHJcblx0XHRcdFx0aSsrO1xyXG5cdFx0XHR9IGVsc2UgaWYgKHdpa2l0ZXh0W2ldID09PSBcIn1cIiAmJiB3aWtpdGV4dFtpKzFdID09PSBcIn1cIikge1xyXG5cdFx0XHRcdGlmIChudW1VbmNsb3NlZCA9PT0gMikge1xyXG5cdFx0XHRcdFx0ZW5kSWR4ID0gaTtcclxuXHRcdFx0XHRcdHByb2Nlc3NUZW1wbGF0ZVRleHQoc3RhcnRJZHgsIGVuZElkeCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdG51bVVuY2xvc2VkIC09IDI7XHJcblx0XHRcdFx0aSsrO1xyXG5cdFx0XHR9IGVsc2UgaWYgKHdpa2l0ZXh0W2ldID09PSBcInxcIiAmJiBudW1VbmNsb3NlZCA+IDIpIHtcclxuXHRcdFx0XHQvLyBzd2FwIG91dCBwaXBlcyBpbiBuZXN0ZWQgdGVtcGxhdGVzIHdpdGggXFx4MDEgY2hhcmFjdGVyXHJcblx0XHRcdFx0d2lraXRleHQgPSBzdHJSZXBsYWNlQXQod2lraXRleHQsIGksXCJcXHgwMVwiKTtcclxuXHRcdFx0fSBlbHNlIGlmICggL148IS0tLy50ZXN0KHdpa2l0ZXh0LnNsaWNlKGksIGkgKyA0KSkgKSB7XHJcblx0XHRcdFx0aW5Db21tZW50ID0gdHJ1ZTtcclxuXHRcdFx0XHRpICs9IDM7XHJcblx0XHRcdH0gZWxzZSBpZiAoIC9ePG5vd2lraSA/Pi8udGVzdCh3aWtpdGV4dC5zbGljZShpLCBpICsgOSkpICkge1xyXG5cdFx0XHRcdGluTm93aWtpID0gdHJ1ZTtcclxuXHRcdFx0XHRpICs9IDc7XHJcblx0XHRcdH0gXHJcblxyXG5cdFx0fSBlbHNlIHsgLy8gd2UgYXJlIGluIGEgY29tbWVudCBvciBub3dpa2kgb3Ige3t7cGFyYW1ldGVyfX19XHJcblx0XHRcdGlmICh3aWtpdGV4dFtpXSA9PT0gXCJ8XCIpIHtcclxuXHRcdFx0XHQvLyBzd2FwIG91dCBwaXBlcyB3aXRoIFxceDAxIGNoYXJhY3RlclxyXG5cdFx0XHRcdHdpa2l0ZXh0ID0gc3RyUmVwbGFjZUF0KHdpa2l0ZXh0LCBpLFwiXFx4MDFcIik7XHJcblx0XHRcdH0gZWxzZSBpZiAoL14tLT4vLnRlc3Qod2lraXRleHQuc2xpY2UoaSwgaSArIDMpKSkge1xyXG5cdFx0XHRcdGluQ29tbWVudCA9IGZhbHNlO1xyXG5cdFx0XHRcdGkgKz0gMjtcclxuXHRcdFx0fSBlbHNlIGlmICgvXjxcXC9ub3dpa2kgPz4vLnRlc3Qod2lraXRleHQuc2xpY2UoaSwgaSArIDEwKSkpIHtcclxuXHRcdFx0XHRpbk5vd2lraSA9IGZhbHNlO1xyXG5cdFx0XHRcdGkgKz0gODtcclxuXHRcdFx0fSBlbHNlIGlmICh3aWtpdGV4dFtpXSA9PT0gXCJ9XCIgJiYgd2lraXRleHRbaSsxXSA9PT0gXCJ9XCIgJiYgd2lraXRleHRbaSsyXSA9PT0gXCJ9XCIpIHtcclxuXHRcdFx0XHRpblBhcmFtZXRlciA9IGZhbHNlO1xyXG5cdFx0XHRcdGkgKz0gMjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHR9XHJcblx0XHJcblx0aWYgKCByZWN1cnNpdmUgKSB7XHJcblx0XHR2YXIgc3VidGVtcGxhdGVzID0gZmlsdGVyQW5kTWFwKHJlc3VsdCxcclxuXHRcdFx0dGVtcGxhdGUgPT4gL1xce1xceyg/Oi58XFxuKSpcXH1cXH0vLnRlc3QodGVtcGxhdGUud2lraXRleHQuc2xpY2UoMiwtMikpLFxyXG5cdFx0XHR0ZW1wbGF0ZSA9PiBwYXJzZVRlbXBsYXRlcyh0ZW1wbGF0ZS53aWtpdGV4dC5zbGljZSgyLC0yKSwgdHJ1ZSlcclxuXHRcdCk7XHJcblx0XHRyZXR1cm4gcmVzdWx0LmNvbmNhdC5hcHBseShyZXN1bHQsIHN1YnRlbXBsYXRlcyk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gcmVzdWx0OyBcclxufTsgLyogZXNsaW50LWVuYWJsZSBuby1jb250cm9sLXJlZ2V4ICovXHJcblxyXG4vKipcclxuICogQHBhcmFtIHtUZW1wbGF0ZXxUZW1wbGF0ZVtdfSB0ZW1wbGF0ZXNcclxuICogQHJldHVybiB7UHJvbWlzZTxUZW1wbGF0ZT58UHJvbWlzZTxUZW1wbGF0ZVtdPn1cclxuICovXHJcbnZhciBnZXRXaXRoUmVkaXJlY3RUbyA9IGZ1bmN0aW9uKHRlbXBsYXRlcykge1xyXG5cdHZhciB0ZW1wbGF0ZXNBcnJheSA9IEFycmF5LmlzQXJyYXkodGVtcGxhdGVzKSA/IHRlbXBsYXRlcyA6IFt0ZW1wbGF0ZXNdO1xyXG5cdGlmICh0ZW1wbGF0ZXNBcnJheS5sZW5ndGggPT09IDApIHtcclxuXHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVzb2x2ZShbXSk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gQVBJLmdldCh7XHJcblx0XHRcImFjdGlvblwiOiBcInF1ZXJ5XCIsXHJcblx0XHRcImZvcm1hdFwiOiBcImpzb25cIixcclxuXHRcdFwidGl0bGVzXCI6IGZpbHRlckFuZE1hcCh0ZW1wbGF0ZXNBcnJheSxcclxuXHRcdFx0dGVtcGxhdGUgPT4gdGVtcGxhdGUuZ2V0VGl0bGUoKSAhPT0gbnVsbCxcclxuXHRcdFx0dGVtcGxhdGUgPT4gdGVtcGxhdGUuZ2V0VGl0bGUoKS5nZXRQcmVmaXhlZFRleHQoKVxyXG5cdFx0KSxcclxuXHRcdFwicmVkaXJlY3RzXCI6IDFcclxuXHR9KS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkge1xyXG5cdFx0aWYgKCAhcmVzdWx0IHx8ICFyZXN1bHQucXVlcnkgKSB7XHJcblx0XHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVqZWN0KFwiRW1wdHkgcmVzcG9uc2VcIik7XHJcblx0XHR9XHJcblx0XHRpZiAoIHJlc3VsdC5xdWVyeS5yZWRpcmVjdHMgKSB7XHJcblx0XHRcdHJlc3VsdC5xdWVyeS5yZWRpcmVjdHMuZm9yRWFjaChmdW5jdGlvbihyZWRpcmVjdCkge1xyXG5cdFx0XHRcdHZhciBpID0gdGVtcGxhdGVzQXJyYXkuZmluZEluZGV4KHRlbXBsYXRlID0+IHtcclxuXHRcdFx0XHRcdGxldCB0aXRsZSA9IHRlbXBsYXRlLmdldFRpdGxlKCk7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGl0bGUgJiYgdGl0bGUuZ2V0UHJlZml4ZWRUZXh0KCkgPT09IHJlZGlyZWN0LmZyb207XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdFx0aWYgKGkgIT09IC0xKSB7XHJcblx0XHRcdFx0XHR0ZW1wbGF0ZXNBcnJheVtpXS5yZWRpcmVjdFRhcmdldCA9IG13LlRpdGxlLm5ld0Zyb21UZXh0KHJlZGlyZWN0LnRvKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIEFycmF5LmlzQXJyYXkodGVtcGxhdGVzKSA/IHRlbXBsYXRlc0FycmF5IDogdGVtcGxhdGVzQXJyYXlbMF07XHJcblx0fSk7XHJcbn07XHJcblxyXG5UZW1wbGF0ZS5wcm90b3R5cGUuZ2V0RGF0YUZvclBhcmFtID0gZnVuY3Rpb24oa2V5LCBwYXJhTmFtZSkge1xyXG5cdGlmICggIXRoaXMucGFyYW1EYXRhICkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdC8vIElmIGFsaWFzLCBzd2l0Y2ggZnJvbSBhbGlhcyB0byBwcmVmZXJyZWQgcGFyYW1ldGVyIG5hbWVcclxuXHR2YXIgcGFyYSA9IHRoaXMucGFyYW1BbGlhc2VzW3BhcmFOYW1lXSB8fCBwYXJhTmFtZTtcdFxyXG5cdGlmICggIXRoaXMucGFyYW1EYXRhW3BhcmFdICkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHRcclxuXHR2YXIgZGF0YSA9IHRoaXMucGFyYW1EYXRhW3BhcmFdW2tleV07XHJcblx0Ly8gRGF0YSBtaWdodCBhY3R1YWxseSBiZSBhbiBvYmplY3Qgd2l0aCBrZXkgXCJlblwiXHJcblx0aWYgKCBkYXRhICYmIGRhdGEuZW4gJiYgIUFycmF5LmlzQXJyYXkoZGF0YSkgKSB7XHJcblx0XHRyZXR1cm4gZGF0YS5lbjtcclxuXHR9XHJcblx0cmV0dXJuIGRhdGE7XHJcbn07XHJcblxyXG5UZW1wbGF0ZS5wcm90b3R5cGUuaXNTaGVsbFRlbXBsYXRlID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIG1haW5UZXh0ID0gdGhpcy5yZWRpcmVjdFRhcmdldFxyXG5cdFx0PyB0aGlzLnJlZGlyZWN0VGFyZ2V0LmdldE1haW5UZXh0KClcclxuXHRcdDogdGhpcy5nZXRUaXRsZSgpLmdldE1haW5UZXh0KCk7XHJcblx0cmV0dXJuIGNvbmZpZy5zaGVsbFRlbXBsYXRlcy5pbmNsdWRlcyhtYWluVGV4dCk7XHJcbn07XHJcblxyXG5UZW1wbGF0ZS5wcm90b3R5cGUuc2V0UGFyYW1EYXRhQW5kU3VnZ2VzdGlvbnMgPSBmdW5jdGlvbigpIHtcclxuXHR2YXIgc2VsZiA9IHRoaXM7XHJcblx0dmFyIHBhcmFtRGF0YVNldCA9ICQuRGVmZXJyZWQoKTtcclxuXHRcclxuXHRpZiAoIHNlbGYucGFyYW1EYXRhICkgeyByZXR1cm4gcGFyYW1EYXRhU2V0LnJlc29sdmUoKTsgfVxyXG4gICAgXHJcblx0dmFyIHByZWZpeGVkVGV4dCA9IHNlbGYucmVkaXJlY3RUYXJnZXRcclxuXHRcdD8gc2VsZi5yZWRpcmVjdFRhcmdldC5nZXRQcmVmaXhlZFRleHQoKVxyXG5cdFx0OiBzZWxmLmdldFRpdGxlKCkuZ2V0UHJlZml4ZWRUZXh0KCk7XHJcblxyXG5cdHZhciBjYWNoZWRJbmZvID0gY2FjaGUucmVhZChwcmVmaXhlZFRleHQgKyBcIi1wYXJhbXNcIik7XHJcblx0XHJcblx0aWYgKFxyXG5cdFx0Y2FjaGVkSW5mbyAmJlxyXG5cdFx0Y2FjaGVkSW5mby52YWx1ZSAmJlxyXG5cdFx0Y2FjaGVkSW5mby5zdGFsZURhdGUgJiZcclxuXHRcdGNhY2hlZEluZm8udmFsdWUucGFyYW1EYXRhICE9IG51bGwgJiZcclxuXHRcdGNhY2hlZEluZm8udmFsdWUucGFyYW1ldGVyU3VnZ2VzdGlvbnMgIT0gbnVsbCAmJlxyXG5cdFx0Y2FjaGVkSW5mby52YWx1ZS5wYXJhbUFsaWFzZXMgIT0gbnVsbFxyXG5cdCkge1xyXG5cdFx0c2VsZi5ub3RlbXBsYXRlZGF0YSA9IGNhY2hlZEluZm8udmFsdWUubm90ZW1wbGF0ZWRhdGE7XHJcblx0XHRzZWxmLnBhcmFtRGF0YSA9IGNhY2hlZEluZm8udmFsdWUucGFyYW1EYXRhO1xyXG5cdFx0c2VsZi5wYXJhbWV0ZXJTdWdnZXN0aW9ucyA9IGNhY2hlZEluZm8udmFsdWUucGFyYW1ldGVyU3VnZ2VzdGlvbnM7XHJcblx0XHRzZWxmLnBhcmFtQWxpYXNlcyA9IGNhY2hlZEluZm8udmFsdWUucGFyYW1BbGlhc2VzO1xyXG5cdFx0XHJcblx0XHRwYXJhbURhdGFTZXQucmVzb2x2ZSgpO1xyXG5cdFx0aWYgKCAhaXNBZnRlckRhdGUoY2FjaGVkSW5mby5zdGFsZURhdGUpICkge1xyXG5cdFx0XHQvLyBKdXN0IHVzZSB0aGUgY2FjaGVkIGRhdGFcclxuXHRcdFx0cmV0dXJuIHBhcmFtRGF0YVNldDtcclxuXHRcdH0gLy8gZWxzZTogVXNlIHRoZSBjYWNoZSBkYXRhIGZvciBub3csIGJ1dCBhbHNvIGZldGNoIG5ldyBkYXRhIGZyb20gQVBJXHJcblx0fVxyXG5cdFxyXG5cdEFQSS5nZXQoe1xyXG5cdFx0YWN0aW9uOiBcInRlbXBsYXRlZGF0YVwiLFxyXG5cdFx0dGl0bGVzOiBwcmVmaXhlZFRleHQsXHJcblx0XHRyZWRpcmVjdHM6IDEsXHJcblx0XHRpbmNsdWRlTWlzc2luZ1RpdGxlczogMVxyXG5cdH0pXHJcblx0XHQudGhlbihcclxuXHRcdFx0ZnVuY3Rpb24ocmVzcG9uc2UpIHsgcmV0dXJuIHJlc3BvbnNlOyB9LFxyXG5cdFx0XHRmdW5jdGlvbigvKmVycm9yKi8pIHsgcmV0dXJuIG51bGw7IH0gLy8gSWdub3JlIGVycm9ycywgd2lsbCB1c2UgZGVmYXVsdCBkYXRhXHJcblx0XHQpXHJcblx0XHQudGhlbiggZnVuY3Rpb24ocmVzdWx0KSB7XHJcblx0XHQvLyBGaWd1cmUgb3V0IHBhZ2UgaWQgKGJlYWN1c2UgYWN0aW9uPXRlbXBsYXRlZGF0YSBkb2Vzbid0IGhhdmUgYW4gaW5kZXhwYWdlaWRzIG9wdGlvbilcclxuXHRcdFx0dmFyIGlkID0gcmVzdWx0ICYmICQubWFwKHJlc3VsdC5wYWdlcywgZnVuY3Rpb24oIF92YWx1ZSwga2V5ICkgeyByZXR1cm4ga2V5OyB9KTtcclxuXHRcdFxyXG5cdFx0XHRpZiAoICFyZXN1bHQgfHwgIXJlc3VsdC5wYWdlc1tpZF0gfHwgcmVzdWx0LnBhZ2VzW2lkXS5ub3RlbXBsYXRlZGF0YSB8fCAhcmVzdWx0LnBhZ2VzW2lkXS5wYXJhbXMgKSB7XHJcblx0XHRcdC8vIE5vIFRlbXBsYXRlRGF0YSwgc28gdXNlIGRlZmF1bHRzIChndWVzc2VzKVxyXG5cdFx0XHRcdHNlbGYubm90ZW1wbGF0ZWRhdGEgPSB0cnVlO1xyXG5cdFx0XHRcdHNlbGYudGVtcGxhdGVkYXRhQXBpRXJyb3IgPSAhcmVzdWx0O1xyXG5cdFx0XHRcdHNlbGYucGFyYW1EYXRhID0gY29uZmlnLmRlZmF1bHRQYXJhbWV0ZXJEYXRhO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHNlbGYucGFyYW1EYXRhID0gcmVzdWx0LnBhZ2VzW2lkXS5wYXJhbXM7XHJcblx0XHRcdH1cclxuICAgICAgICBcclxuXHRcdFx0c2VsZi5wYXJhbUFsaWFzZXMgPSB7fTtcclxuXHRcdFx0JC5lYWNoKHNlbGYucGFyYW1EYXRhLCBmdW5jdGlvbihwYXJhTmFtZSwgcGFyYURhdGEpIHtcclxuXHRcdFx0XHQvLyBFeHRyYWN0IGFsaWFzZXMgZm9yIGVhc2llciByZWZlcmVuY2UgbGF0ZXIgb25cclxuXHRcdFx0XHRpZiAoIHBhcmFEYXRhLmFsaWFzZXMgJiYgcGFyYURhdGEuYWxpYXNlcy5sZW5ndGggKSB7XHJcblx0XHRcdFx0XHRwYXJhRGF0YS5hbGlhc2VzLmZvckVhY2goZnVuY3Rpb24oYWxpYXMpe1xyXG5cdFx0XHRcdFx0XHRzZWxmLnBhcmFtQWxpYXNlc1thbGlhc10gPSBwYXJhTmFtZTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHQvLyBFeHRyYWN0IGFsbG93ZWQgdmFsdWVzIGFycmF5IGZyb20gZGVzY3JpcHRpb25cclxuXHRcdFx0XHRpZiAoIHBhcmFEYXRhLmRlc2NyaXB0aW9uICYmIC9cXFsuKicuKz8nLio/XFxdLy50ZXN0KHBhcmFEYXRhLmRlc2NyaXB0aW9uLmVuKSApIHtcclxuXHRcdFx0XHRcdHRyeSB7XHJcblx0XHRcdFx0XHRcdHZhciBhbGxvd2VkVmFscyA9IEpTT04ucGFyc2UoXHJcblx0XHRcdFx0XHRcdFx0cGFyYURhdGEuZGVzY3JpcHRpb24uZW5cclxuXHRcdFx0XHRcdFx0XHRcdC5yZXBsYWNlKC9eLipcXFsvLFwiW1wiKVxyXG5cdFx0XHRcdFx0XHRcdFx0LnJlcGxhY2UoL1wiL2csIFwiXFxcXFxcXCJcIilcclxuXHRcdFx0XHRcdFx0XHRcdC5yZXBsYWNlKC8nL2csIFwiXFxcIlwiKVxyXG5cdFx0XHRcdFx0XHRcdFx0LnJlcGxhY2UoLyxcXHMqXS8sIFwiXVwiKVxyXG5cdFx0XHRcdFx0XHRcdFx0LnJlcGxhY2UoL10uKiQvLCBcIl1cIilcclxuXHRcdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdFx0c2VsZi5wYXJhbURhdGFbcGFyYU5hbWVdLmFsbG93ZWRWYWx1ZXMgPSBhbGxvd2VkVmFscztcclxuXHRcdFx0XHRcdH0gY2F0Y2goZSkge1xyXG5cdFx0XHRcdFx0XHRjb25zb2xlLndhcm4oXCJbUmF0ZXJdIENvdWxkIG5vdCBwYXJzZSBhbGxvd2VkIHZhbHVlcyBpbiBkZXNjcmlwdGlvbjpcXG4gIFwiK1xyXG5cdFx0XHRcdFx0cGFyYURhdGEuZGVzY3JpcHRpb24uZW4gKyBcIlxcbiBDaGVjayBUZW1wbGF0ZURhdGEgZm9yIHBhcmFtZXRlciB8XCIgKyBwYXJhTmFtZSArXHJcblx0XHRcdFx0XHRcIj0gaW4gXCIgKyBzZWxmLmdldFRpdGxlKCkuZ2V0UHJlZml4ZWRUZXh0KCkpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHRcclxuXHRcdFx0Ly8gTWFrZSBzdWdnZXN0aW9ucyBmb3IgY29tYm9ib3hcclxuXHRcdFx0dmFyIGFsbFBhcmFtc0FycmF5ID0gKCAhc2VsZi5ub3RlbXBsYXRlZGF0YSAmJiByZXN1bHQucGFnZXNbaWRdLnBhcmFtT3JkZXIgKSB8fFxyXG5cdFx0XHQkLm1hcChzZWxmLnBhcmFtRGF0YSwgZnVuY3Rpb24oX3ZhbCwga2V5KXtcclxuXHRcdFx0XHRyZXR1cm4ga2V5O1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0c2VsZi5wYXJhbWV0ZXJTdWdnZXN0aW9ucyA9IGFsbFBhcmFtc0FycmF5LmZpbHRlcihmdW5jdGlvbihwYXJhbU5hbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gKCBwYXJhbU5hbWUgJiYgcGFyYW1OYW1lICE9PSBcImNsYXNzXCIgJiYgcGFyYW1OYW1lICE9PSBcImltcG9ydGFuY2VcIiApO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHRcdC5tYXAoZnVuY3Rpb24ocGFyYW1OYW1lKSB7XHJcblx0XHRcdFx0XHR2YXIgb3B0aW9uT2JqZWN0ID0ge2RhdGE6IHBhcmFtTmFtZX07XHJcblx0XHRcdFx0XHR2YXIgbGFiZWwgPSBzZWxmLmdldERhdGFGb3JQYXJhbShsYWJlbCwgcGFyYW1OYW1lKTtcclxuXHRcdFx0XHRcdGlmICggbGFiZWwgKSB7XHJcblx0XHRcdFx0XHRcdG9wdGlvbk9iamVjdC5sYWJlbCA9IGxhYmVsICsgXCIgKHxcIiArIHBhcmFtTmFtZSArIFwiPSlcIjtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiBvcHRpb25PYmplY3Q7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcclxuXHRcdFx0aWYgKCBzZWxmLnRlbXBsYXRlZGF0YUFwaUVycm9yICkge1xyXG5cdFx0XHRcdC8vIERvbid0IHNhdmUgZGVmYXVsdHMvZ3Vlc3NlcyB0byBjYWNoZTtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHJcblx0XHRcdGNhY2hlLndyaXRlKHByZWZpeGVkVGV4dCArIFwiLXBhcmFtc1wiLCB7XHJcblx0XHRcdFx0bm90ZW1wbGF0ZWRhdGE6IHNlbGYubm90ZW1wbGF0ZWRhdGEsXHJcblx0XHRcdFx0cGFyYW1EYXRhOiBzZWxmLnBhcmFtRGF0YSxcclxuXHRcdFx0XHRwYXJhbWV0ZXJTdWdnZXN0aW9uczogc2VsZi5wYXJhbWV0ZXJTdWdnZXN0aW9ucyxcclxuXHRcdFx0XHRwYXJhbUFsaWFzZXM6IHNlbGYucGFyYW1BbGlhc2VzXHJcblx0XHRcdH0sXHQxXHJcblx0XHRcdCk7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSlcclxuXHRcdC50aGVuKFxyXG5cdFx0XHRwYXJhbURhdGFTZXQucmVzb2x2ZSxcclxuXHRcdFx0cGFyYW1EYXRhU2V0LnJlamVjdFxyXG5cdFx0KTtcclxuXHRcclxuXHRyZXR1cm4gcGFyYW1EYXRhU2V0O1x0XHJcbn07XHJcblxyXG52YXIgbWFrZUxpc3RBcyA9IGZ1bmN0aW9uKHN1YmplY3RUaXRsZSkge1xyXG5cdHZhciBuYW1lID0gc3ViamVjdFRpdGxlLmdldE1haW5UZXh0KCkucmVwbGFjZSgvXFxzXFwoLipcXCkvLCBcIlwiKTtcclxuXHRpZiAoIG5hbWUuaW5kZXhPZihcIiBcIikgPT09IC0xICkge1xyXG5cdFx0cmV0dXJuIG5hbWU7XHJcblx0fVxyXG5cdHZhciBnZW5lcmF0aW9uYWxTdWZmaXggPSBcIlwiO1xyXG5cdGlmICggLyAoPzpbSlNdci4/fFtJVlhdKykkLy50ZXN0KG5hbWUpICkge1xyXG5cdFx0Z2VuZXJhdGlvbmFsU3VmZml4ID0gbmFtZS5zbGljZShuYW1lLmxhc3RJbmRleE9mKFwiIFwiKSk7XHJcblx0XHRuYW1lID0gbmFtZS5zbGljZSgwLCBuYW1lLmxhc3RJbmRleE9mKFwiIFwiKSk7XHJcblx0XHRpZiAoIG5hbWUuaW5kZXhPZihcIiBcIikgPT09IC0xICkge1xyXG5cdFx0XHRyZXR1cm4gbmFtZSArIGdlbmVyYXRpb25hbFN1ZmZpeDtcclxuXHRcdH1cclxuXHR9XHJcblx0dmFyIGxhc3ROYW1lID0gbmFtZS5zbGljZShuYW1lLmxhc3RJbmRleE9mKFwiIFwiKSsxKS5yZXBsYWNlKC8sJC8sIFwiXCIpO1xyXG5cdHZhciBvdGhlck5hbWVzID0gbmFtZS5zbGljZSgwLCBuYW1lLmxhc3RJbmRleE9mKFwiIFwiKSk7XHJcblx0cmV0dXJuIGxhc3ROYW1lICsgXCIsIFwiICsgb3RoZXJOYW1lcyArIGdlbmVyYXRpb25hbFN1ZmZpeDtcclxufTtcclxuXHJcblRlbXBsYXRlLnByb3RvdHlwZS5hZGRNaXNzaW5nUGFyYW1zID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIHRoaXNUZW1wbGF0ZSA9IHRoaXM7XHJcblxyXG5cdC8vIEF1dG9maWxsIGxpc3RhcyBwYXJhbWV0ZXIgZm9yIFdQOkJJT1xyXG5cdHZhciBpc0Jpb2dyYXBoeUJhbm5lciA9IHRoaXMuZ2V0VGl0bGUoKS5nZXRNYWluVGV4dCgpID09PSBcIldpa2lQcm9qZWN0IEJpb2dyYXBoeVwiIHx8XHJcblx0XHQodGhpcy5yZWRpcmVjdFRhcmdldCAmJiB0aGlzLnJlZGlyZWN0VGFyZ2V0LmdldE1haW5UZXh0KCkgPT09IFwiV2lraVByb2plY3QgQmlvZ3JhcGh5XCIpO1xyXG5cclxuXHRpZiAoaXNCaW9ncmFwaHlCYW5uZXIgJiYgIXRoaXMuZ2V0UGFyYW0oXCJsaXN0YXNcIikpIHtcclxuXHRcdHZhciBzdWJqZWN0VGl0bGUgPSBtdy5UaXRsZS5uZXdGcm9tVGV4dChjb25maWcubXcud2dQYWdlTmFtZSkuZ2V0U3ViamVjdFBhZ2UoKTtcclxuXHRcdHRoaXMucGFyYW1ldGVycy5wdXNoKHtcclxuXHRcdFx0bmFtZTogXCJsaXN0YXNcIixcclxuXHRcdFx0dmFsdWU6IG1ha2VMaXN0QXMoc3ViamVjdFRpdGxlKSxcclxuXHRcdFx0YXV0b2ZpbGxlZDogdHJ1ZSxcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Ly8gTWFrZSBzdXJlIHJlcXVpcmVkL3N1Z2dlc3RlZCBwYXJhbWV0ZXJzIGFyZSBwcmVzZW50XHJcblx0JC5lYWNoKHRoaXNUZW1wbGF0ZS5wYXJhbURhdGEsIGZ1bmN0aW9uKHBhcmFOYW1lLCBwYXJhRGF0YSkge1xyXG5cdFx0aWYgKCAocGFyYURhdGEucmVxdWlyZWQgfHwgcGFyYURhdGEuc3VnZ2VzdGVkKSAmJiAhdGhpc1RlbXBsYXRlLmdldFBhcmFtKHBhcmFOYW1lKSApIHtcclxuXHRcdFx0Ly8gQ2hlY2sgaWYgYWxyZWFkeSBwcmVzZW50IGluIGFuIGFsaWFzLCBpZiBhbnlcclxuXHRcdFx0aWYgKCBwYXJhRGF0YS5hbGlhc2VzLmxlbmd0aCApIHtcclxuXHRcdFx0XHR2YXIgYWxpYXNlcyA9IHRoaXNUZW1wbGF0ZS5wYXJhbWV0ZXJzLmZpbHRlcihwID0+IHtcclxuXHRcdFx0XHRcdHZhciBpc0FsaWFzID0gcGFyYURhdGEuYWxpYXNlcy5pbmNsdWRlcyhwLm5hbWUpO1xyXG5cdFx0XHRcdFx0dmFyIGlzRW1wdHkgPSAhcC52YWx1ZTtcclxuXHRcdFx0XHRcdHJldHVybiBpc0FsaWFzICYmICFpc0VtcHR5O1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGlmICggYWxpYXNlcy5sZW5ndGggKSB7XHJcblx0XHRcdFx0Ly8gQXQgbGVhc3Qgb25lIG5vbi1lbXB0eSBhbGlhcywgc28gZG8gbm90aGluZ1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHQvLyBObyBub24tZW1wdHkgYWxpYXNlcywgc28gYWRkIHRoaXMgdG8gdGhlIHBhcmFtZXRlcnMgbGlzdCAod2l0aFxyXG5cdFx0XHQvLyB2YWx1ZSBzZXQgcGFyYW1ldGVyIHRvIGVpdGhlciB0aGUgYXV0b3ZhdWxlLCBvciBhcyBudWxsKS5cclxuXHRcdFx0Ly8gQWxzbyBzZXQgdGhhdCBpdCB3YXMgYXV0b2ZpbGxlZC5cclxuXHRcdFx0dGhpc1RlbXBsYXRlLnBhcmFtZXRlcnMucHVzaCh7XHJcblx0XHRcdFx0bmFtZTpwYXJhTmFtZSxcclxuXHRcdFx0XHR2YWx1ZTogcGFyYURhdGEuYXV0b3ZhbHVlIHx8IG51bGwsXHJcblx0XHRcdFx0YXV0b2ZpbGxlZDogdHJ1ZSxcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0fSk7XHJcblxyXG5cdHJldHVybiB0aGlzVGVtcGxhdGU7XHJcbn07XHJcblxyXG5UZW1wbGF0ZS5wcm90b3R5cGUuc2V0Q2xhc3Nlc0FuZEltcG9ydGFuY2VzID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIHBhcnNlZCA9ICQuRGVmZXJyZWQoKTtcclxuXHJcblx0Ly8gRG9uJ3QgcmUtcGFyc2UgaWYgYWxyZWFkeSBwYXJzZWQ7IG5vIG5lZWQgdG8gcGFyc2Ugc2hlbGwgdGVtcGxhdGVzIG9yIGJhbm5lcnMgd2l0aG91dCByYXRpbmdzXHJcblx0aWYgKCB0aGlzLmlzU2hlbGxUZW1wbGF0ZSgpICkge1xyXG5cdFx0dGhpcy5jbGFzc2VzID0gWy4uLmNvbmZpZy5iYW5uZXJEZWZhdWx0cy5jbGFzc2VzXTtcclxuXHRcdHJldHVybiBwYXJzZWQucmVzb2x2ZSgpO1xyXG5cdH0gZWxzZSBpZiAoICh0aGlzLmNsYXNzZXMgJiYgdGhpcy5pbXBvcnRhbmNlcykgfHwgdGhpcy53aXRob3V0UmF0aW5ncyApIHtcclxuXHRcdHJldHVybiBwYXJzZWQucmVzb2x2ZSgpO1xyXG5cdH0gXHJcblxyXG5cdHZhciBtYWluVGV4dCA9IHRoaXMuZ2V0VGl0bGUoKS5nZXRNYWluVGV4dCgpO1xyXG5cclxuXHQvLyBTb21lIHByb2plY3RzIGhhdmUgaGFyZGNvZGVkIHZhbHVlcywgdG8gYXZvaWQgc3RhbmRhcmQgY2xhc3NlcyBvciB0byBwcmV2ZW50IEFQSSBpc3N1ZXMgKHRpbWVvdXQgYW5kL29yIG5vZGUgY291bnQgZXhjZWVkZWQpXHJcblx0Y29uc3QgcmVkaXJlY3RUYXJnZXRPck1haW5UZXh0ID0gdGhpcy5yZWRpcmVjdFRhcmdldCA/IHRoaXMucmVkaXJlY3RUYXJnZXQuZ2V0TWFpblRleHQoKSA6IG1haW5UZXh0O1xyXG5cdGlmICggY29uZmlnLmN1c3RvbUJhbm5lcnNbcmVkaXJlY3RUYXJnZXRPck1haW5UZXh0XSApIHtcclxuXHRcdHRoaXMuY2xhc3NlcyA9IGNvbmZpZy5jdXN0b21CYW5uZXJzW3JlZGlyZWN0VGFyZ2V0T3JNYWluVGV4dF0uY2xhc3NlcztcclxuXHRcdHRoaXMuaW1wb3J0YW5jZXMgPSBjb25maWcuY3VzdG9tQmFubmVyc1tyZWRpcmVjdFRhcmdldE9yTWFpblRleHRdLmltcG9ydGFuY2VzO1xyXG5cdFx0cmV0dXJuIHBhcnNlZC5yZXNvbHZlKCk7XHJcblx0fVxyXG5cclxuXHQvLyBPdGhlcndpc2UgdHJ5IHJlYWRpbmcgZnJvbSBjYWNoZWQgZGF0YVxyXG5cdHZhciBjYWNoZWRSYXRpbmdzID0gY2FjaGUucmVhZChtYWluVGV4dCtcIi1yYXRpbmdzXCIpO1xyXG5cdGlmIChcclxuXHRcdGNhY2hlZFJhdGluZ3MgJiZcclxuXHRcdGNhY2hlZFJhdGluZ3MudmFsdWUgJiZcclxuXHRcdGNhY2hlZFJhdGluZ3Muc3RhbGVEYXRlICYmXHJcblx0XHRjYWNoZWRSYXRpbmdzLnZhbHVlLmNsYXNzZXMhPW51bGwgJiZcclxuXHRcdGNhY2hlZFJhdGluZ3MudmFsdWUuaW1wb3J0YW5jZXMhPW51bGxcclxuXHQpIHtcclxuXHRcdHRoaXMuY2xhc3NlcyA9IGNhY2hlZFJhdGluZ3MudmFsdWUuY2xhc3NlcztcclxuXHRcdHRoaXMuaW1wb3J0YW5jZXMgPSBjYWNoZWRSYXRpbmdzLnZhbHVlLmltcG9ydGFuY2VzO1xyXG5cdFx0cGFyc2VkLnJlc29sdmUoKTtcclxuXHRcdGlmICggIWlzQWZ0ZXJEYXRlKGNhY2hlZFJhdGluZ3Muc3RhbGVEYXRlKSApIHtcclxuXHRcdFx0Ly8gSnVzdCB1c2UgdGhlIGNhY2hlZCBkYXRhXHJcblx0XHRcdHJldHVybiBwYXJzZWQ7XHJcblx0XHR9IC8vIGVsc2U6IFVzZSB0aGUgY2FjaGUgZGF0YSBmb3Igbm93LCBidXQgYWxzbyBmZXRjaCBuZXcgZGF0YSBmcm9tIEFQSVxyXG5cdH1cclxuXHJcblx0dmFyIHdpa2l0ZXh0VG9QYXJzZSA9IFwiXCI7XHRcclxuXHRjb25maWcuYmFubmVyRGVmYXVsdHMuZXh0ZW5kZWRDbGFzc2VzLmZvckVhY2goZnVuY3Rpb24oY2xhc3NuYW1lLCBpbmRleCkge1xyXG5cdFx0d2lraXRleHRUb1BhcnNlICs9IFwie3tcIiArIG1haW5UZXh0ICsgXCJ8Y2xhc3M9XCIgKyBjbGFzc25hbWUgKyBcInxpbXBvcnRhbmNlPVwiICtcclxuXHRcdChjb25maWcuYmFubmVyRGVmYXVsdHMuZXh0ZW5kZWRJbXBvcnRhbmNlc1tpbmRleF0gfHwgXCJcIikgKyBcIn19L25cIjtcclxuXHR9KTtcclxuXHRcclxuXHRyZXR1cm4gQVBJLmdldCh7XHJcblx0XHRhY3Rpb246IFwicGFyc2VcIixcclxuXHRcdHRpdGxlOiBcIlRhbGs6V2lraXBlZGlhXCIsXHJcblx0XHR0ZXh0OiB3aWtpdGV4dFRvUGFyc2UsXHJcblx0XHRwcm9wOiBcImNhdGVnb3JpZXNodG1sXCJcclxuXHR9KVxyXG5cdFx0LnRoZW4oKHJlc3VsdCkgPT4ge1xyXG5cdFx0XHR2YXIgY2F0c0h0bWwgPSByZXN1bHQucGFyc2UuY2F0ZWdvcmllc2h0bWxbXCIqXCJdO1xyXG5cdFx0XHR2YXIgZXh0ZW5kZWRDbGFzc2VzID0gY29uZmlnLmJhbm5lckRlZmF1bHRzLmV4dGVuZGVkQ2xhc3Nlcy5maWx0ZXIoZnVuY3Rpb24oY2wpIHtcclxuXHRcdFx0XHRyZXR1cm4gY2F0c0h0bWwuaW5kZXhPZihjbCtcIi1DbGFzc1wiKSAhPT0gLTE7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHR0aGlzLmNsYXNzZXMgPSBbLi4uY29uZmlnLmJhbm5lckRlZmF1bHRzLmNsYXNzZXMsIC4uLmV4dGVuZGVkQ2xhc3Nlc107XHJcblx0XHRcdHRoaXMuaW1wb3J0YW5jZXMgPSBjb25maWcuYmFubmVyRGVmYXVsdHMuZXh0ZW5kZWRJbXBvcnRhbmNlcy5maWx0ZXIoZnVuY3Rpb24oaW1wKSB7XHJcblx0XHRcdFx0cmV0dXJuIGNhdHNIdG1sLmluZGV4T2YoaW1wK1wiLWltcG9ydGFuY2VcIikgIT09IC0xO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0Y2FjaGUud3JpdGUobWFpblRleHQrXCItcmF0aW5nc1wiLFxyXG5cdFx0XHRcdHtcclxuXHRcdFx0XHRcdGNsYXNzZXM6IHRoaXMuY2xhc3NlcyxcclxuXHRcdFx0XHRcdGltcG9ydGFuY2VzOiB0aGlzLmltcG9ydGFuY2VzXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XHQxXHJcblx0XHRcdCk7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSk7XHJcbn07XHJcblxyXG5leHBvcnQge1RlbXBsYXRlLCBwYXJzZVRlbXBsYXRlcywgZ2V0V2l0aFJlZGlyZWN0VG99O1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgY29uZmlnIGZyb20gXCIuLi8uLi9jb25maWdcIjtcclxuaW1wb3J0IEJhbm5lcldpZGdldCBmcm9tIFwiLi9CYW5uZXJXaWRnZXRcIjtcclxuaW1wb3J0IHsgbm9ybWFsaXNlWWVzTm8sIGZpbHRlckFuZE1hcCwgdW5pcXVlQXJyYXkgfSBmcm9tIFwiLi4vLi4vdXRpbFwiO1xyXG5pbXBvcnQgUGFyYW1ldGVyV2lkZ2V0IGZyb20gXCIuL1BhcmFtZXRlcldpZGdldFwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxudmFyIEJhbm5lckxpc3RXaWRnZXQgPSBmdW5jdGlvbiBCYW5uZXJMaXN0V2lkZ2V0KCBjb25maWcgKSB7XHJcblx0Y29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG5cclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdEJhbm5lckxpc3RXaWRnZXQucGFyZW50LmNhbGwoIHRoaXMsIGNvbmZpZyApO1xyXG5cdE9PLnVpLm1peGluLkdyb3VwRWxlbWVudC5jYWxsKCB0aGlzLCB7XHJcblx0XHQkZ3JvdXA6IHRoaXMuJGVsZW1lbnRcclxuXHR9ICk7XHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLWJhbm5lckxpc3RXaWRnZXRcIikuY3NzKHtcInBhZGRpbmdcIjpcIjIwcHggMTBweCAxNnB4IDEwcHhcIn0pO1xyXG5cclxuXHQvLyBQcmVmc1xyXG5cdHRoaXMucHJlZmVyZW5jZXMgPSBjb25maWcucHJlZmVyZW5jZXM7XHJcblx0XHJcblx0dGhpcy5vcmVzQ2xhc3MgPSBjb25maWcub3Jlc0NsYXNzO1xyXG5cdFxyXG5cdHRoaXMuY2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuXHQvLyBFdmVudHNcclxuXHR0aGlzLmFnZ3JlZ2F0ZSgge1wicmVtb3ZlXCI6IFwiYmFubmVyUmVtb3ZlXCJ9ICk7XHJcblx0dGhpcy5jb25uZWN0KCB0aGlzLCB7XCJiYW5uZXJSZW1vdmVcIjogXCJvbkJhbm5lclJlbW92ZVwifSApO1xyXG5cclxuXHR0aGlzLmFnZ3JlZ2F0ZSgge1wiY2hhbmdlZFwiOiBcImJhbm5lckNoYW5nZWRcIn0gKTtcclxuXHR0aGlzLmNvbm5lY3QoIHRoaXMsIHtcImJhbm5lckNoYW5nZWRcIjogXCJzZXRDaGFuZ2VkXCJ9ICk7XHJcblxyXG5cdHRoaXMuYWdncmVnYXRlKCB7XCJiaW9ncmFwaHlCYW5uZXJDaGFuZ2VcIjogXCJiaW9ncmFwaHlCYW5uZXJDaGFuZ2VkXCJ9ICk7XHJcblx0dGhpcy5jb25uZWN0KCB0aGlzLCB7XCJiaW9ncmFwaHlCYW5uZXJDaGFuZ2VkXCI6IFwic3luY1NoZWxsVGVtcGxhdGVXaXRoQmlvZ3JhcGh5QmFubmVyXCJ9ICk7XHJcblxyXG5cdHRoaXMuYWdncmVnYXRlKCB7XCJ1cGRhdGVkU2l6ZVwiOiBcImJhbm5lclVwZGF0ZWRTaXplXCJ9ICk7XHJcblx0dGhpcy5jb25uZWN0KCB0aGlzLCB7XCJiYW5uZXJVcGRhdGVkU2l6ZVwiOiBcIm9uVXBkYXRlZFNpemVcIn0gKTtcclxufTtcclxuXHJcbk9PLmluaGVyaXRDbGFzcyggQmFubmVyTGlzdFdpZGdldCwgT08udWkuV2lkZ2V0ICk7XHJcbk9PLm1peGluQ2xhc3MoIEJhbm5lckxpc3RXaWRnZXQsIE9PLnVpLm1peGluLkdyb3VwRWxlbWVudCApO1xyXG4vKlxyXG5tZXRob2RzIGZyb20gbWl4aW46XHJcbiAtIGFkZEl0ZW1zKCBpdGVtcywgW2luZGV4XSApIDogT08udWkuRWxlbWVudCAgKENIQUlOQUJMRSlcclxuIC0gY2xlYXJJdGVtcyggKSA6IE9PLnVpLkVsZW1lbnQgIChDSEFJTkFCTEUpXHJcbiAtIGZpbmRJdGVtRnJvbURhdGEoIGRhdGEgKSA6IE9PLnVpLkVsZW1lbnR8bnVsbFxyXG4gLSBmaW5kSXRlbXNGcm9tRGF0YSggZGF0YSApIDogT08udWkuRWxlbWVudFtdXHJcbiAtIHJlbW92ZUl0ZW1zKCBpdGVtcyApIDogT08udWkuRWxlbWVudCAgKENIQUlOQUJMRSlcclxuKi9cclxuXHJcbkJhbm5lckxpc3RXaWRnZXQucHJvdG90eXBlLm9uVXBkYXRlZFNpemUgPSBmdW5jdGlvbigpIHtcclxuXHQvLyBFbWl0IGFuIFwidXBkYXRlZFNpemVcIiBldmVudCBzbyB0aGUgcGFyZW50IHdpbmRvdyBjYW4gdXBkYXRlIHNpemUsIGlmIG5lZWRlZFxyXG5cdHRoaXMuZW1pdChcInVwZGF0ZWRTaXplXCIpO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuc2V0Q2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuY2hhbmdlZCA9IHRydWU7XHJcbn07XHJcblxyXG5CYW5uZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5vbkJhbm5lclJlbW92ZSA9IGZ1bmN0aW9uICggYmFubmVyICkge1xyXG5cdHRoaXMucmVtb3ZlSXRlbXMoW2Jhbm5lcl0pO1xyXG5cdHRoaXMuc2V0Q2hhbmdlZCgpO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuc3luY1NoZWxsVGVtcGxhdGVXaXRoQmlvZ3JhcGh5QmFubmVyID0gZnVuY3Rpb24oIGJpb2dyYXBoeUJhbm5lciApIHtcclxuXHRiaW9ncmFwaHlCYW5uZXIgPSBiaW9ncmFwaHlCYW5uZXIgfHwgdGhpcy5pdGVtcy5maW5kKFxyXG5cdFx0YmFubmVyID0+IGJhbm5lci5tYWluVGV4dCA9PT0gXCJXaWtpUHJvamVjdCBCaW9ncmFwaHlcIiB8fCBiYW5uZXIucmVkaXJlY3RUYXJnZXRNYWluVGV4dCA9PT0gXCJXaWtpUHJvamVjdCBCaW9ncmFwaHlcIlxyXG5cdCk7XHJcblx0aWYgKCFiaW9ncmFwaHlCYW5uZXIpIHJldHVybjtcclxuXHJcblx0Y29uc3QgYmFubmVyU2hlbGxUZW1wbGF0ZSA9IHRoaXMuaXRlbXMuZmluZChcclxuXHRcdGJhbm5lciA9PiBiYW5uZXIubWFpblRleHQgPT09IGNvbmZpZy5zaGVsbFRlbXBsYXRlc1swXSB8fCBiYW5uZXIucmVkaXJlY3RUYXJnZXRNYWluVGV4dCA9PT0gY29uZmlnLnNoZWxsVGVtcGxhdGVzWzBdXHJcblx0KTtcclxuXHRpZiAoIWJhbm5lclNoZWxsVGVtcGxhdGUpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblxyXG5cdGNvbnN0IHBhcmFtc1RvU3luYyA9IFtcclxuXHRcdHsgbmFtZTogXCJsaXZpbmdcIiwgbm9ybWFsaXNlOiB0cnVlIH0sXHJcblx0XHR7IG5hbWU6IFwiYmxwb1wiLCBub3JtYWxpc2U6IHRydWUgfSxcclxuXHRcdHsgbmFtZTogXCJhY3RpdmVwb2xcIiwgbm9ybWFsaXNlOiB0cnVlIH0sXHJcblx0XHR7IG5hbWU6IFwibGlzdGFzXCIsIG5vcm1hbGlzZTogZmFsc2UgfSxcclxuXHRdO1xyXG5cdHBhcmFtc1RvU3luYy5mb3JFYWNoKHBhcmFtVG9TeW5jID0+IHtcclxuXHRcdGNvbnN0IFtiaW9ncmFwaHlQYXJhbSwgc2hlbGxQYXJhbV0gPSBbYmlvZ3JhcGh5QmFubmVyLCBiYW5uZXJTaGVsbFRlbXBsYXRlXS5tYXAoYmFubmVyID0+XHJcblx0XHRcdGJhbm5lci5wYXJhbWV0ZXJMaXN0LmdldFBhcmFtZXRlckl0ZW1zKClcclxuXHRcdFx0XHQuZmluZChwYXJhbWV0ZXIgPT5cclxuXHRcdFx0XHRcdHBhcmFtZXRlci5uYW1lID09PSBwYXJhbVRvU3luYy5uYW1lIHx8XHJcblx0XHRcdFx0XHRiYW5uZXIucGFyYW1BbGlhc2VzW3BhcmFtZXRlci5uYW1lXSA9PT0gcGFyYW1Ub1N5bmMubmFtZVxyXG5cdFx0XHRcdClcclxuXHRcdCk7XHJcblx0XHRpZiAoIWJpb2dyYXBoeVBhcmFtKSByZXR1cm47XHJcblxyXG5cdFx0Y29uc3QgcGFyYW1TeW5jVmFsdWUgPSBwYXJhbVRvU3luYy5ub3JtYWxpc2UgPyBub3JtYWxpc2VZZXNObyhiaW9ncmFwaHlQYXJhbS52YWx1ZSkgOiBiaW9ncmFwaHlQYXJhbS52YWx1ZTtcclxuXHRcdGJpb2dyYXBoeVBhcmFtLmRlbGV0ZSgpO1xyXG5cclxuXHRcdGlmICghc2hlbGxQYXJhbSAmJiBwYXJhbVN5bmNWYWx1ZSkge1xyXG5cdFx0XHRjb25zdCBpbmRleCA9IGJhbm5lclNoZWxsVGVtcGxhdGUuYWRkUGFyYW1ldGVyTGF5b3V0LmlzVmlzaWJsZSgpXHJcblx0XHRcdFx0PyAtMSAvLyBJbnNlcnQgYXQgdGhlIHZlcnkgZW5kXHJcblx0XHRcdFx0OiBiYW5uZXJTaGVsbFRlbXBsYXRlLnBhcmFtZXRlckxpc3QuaXRlbXMubGVuZ3RoLTE7IC8vIEluc2VydCBwcmlvciB0byB0aGUgXCJhZGQgcGFyYW1ldGVyXCIgYnV0dG9uXHJcblx0XHRcdGJhbm5lclNoZWxsVGVtcGxhdGUucGFyYW1ldGVyTGlzdC5hZGRJdGVtcyhbXHJcblx0XHRcdFx0bmV3IFBhcmFtZXRlcldpZGdldCgge1xyXG5cdFx0XHRcdFx0XCJuYW1lXCI6IHBhcmFtVG9TeW5jLm5hbWUsXHJcblx0XHRcdFx0XHRcInZhbHVlXCI6IHBhcmFtU3luY1ZhbHVlLFxyXG5cdFx0XHRcdFx0XCJhdXRvZmlsbGVkXCI6IHRydWVcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdGJhbm5lclNoZWxsVGVtcGxhdGUucGFyYW1EYXRhICYmIGJhbm5lclNoZWxsVGVtcGxhdGUucGFyYW1EYXRhW3BhcmFtVG9TeW5jLm5hbWVdXHJcblx0XHRcdFx0KVxyXG5cdFx0XHRdLCBpbmRleCk7XHJcblx0XHR9IGVsc2UgaWYgKCFiaW9ncmFwaHlQYXJhbS5hdXRvZmlsbGVkICYmIHBhcmFtU3luY1ZhbHVlKSB7XHJcblx0XHRcdHNoZWxsUGFyYW0uc2V0VmFsdWUoIHBhcmFtU3luY1ZhbHVlICk7XHJcblx0XHRcdHNoZWxsUGFyYW0uc2V0QXV0b2ZpbGxlZCgpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuYWRkU2hlbGxUZW1wbGF0ZUlmTmVlZWRlZCA9IGZ1bmN0aW9uICgpIHtcclxuXHRpZiAoXHJcblx0XHQhdGhpcy5pdGVtcy5zb21lKGJhbm5lciA9PiBiYW5uZXIuaXNTaGVsbFRlbXBsYXRlKVxyXG5cdCkge1xyXG5cdFx0QmFubmVyV2lkZ2V0Lm5ld0Zyb21UZW1wbGF0ZU5hbWUoXHJcblx0XHRcdGNvbmZpZy5zaGVsbFRlbXBsYXRlc1swXSxcclxuXHRcdFx0e3dpdGhvdXRSYXRpbmdzOiB0cnVlfSxcclxuXHRcdFx0e3ByZWZlcmVuY2VzOiB0aGlzLnByZWZlcmVuY2VzLCBpc0FydGljbGU6IHRoaXMucGFnZUluZm8uaXNBcnRpY2xlfVxyXG5cdFx0KS50aGVuKHNoZWxsQmFubmVyV2lkZ2V0ID0+IHtcclxuXHRcdFx0T08udWkubWl4aW4uR3JvdXBFbGVtZW50LnByb3RvdHlwZS5hZGRJdGVtcy5jYWxsKCB0aGlzLCBbc2hlbGxCYW5uZXJXaWRnZXRdLCAwICk7XHJcblx0XHRcdC8vIEF1dG9maWxsIHJhdGluZ3MgKGlmIGFibGUgdG8pXHJcblx0XHRcdHRoaXMuYXV0b2ZpbGxDbGFzc1JhdGluZ3Moe2ZvckJhbm5lclNoZWxsOiB0cnVlfSk7XHJcblx0XHRcdC8vIGVtaXQgdXBkYXRlZFNpemUgZXZlbnQgXHJcblx0XHRcdHRoaXMub25VcGRhdGVkU2l6ZSgpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcclxuXHJcblxyXG5CYW5uZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5hZGRJdGVtcyA9IGZ1bmN0aW9uICggaXRlbXMsIGluZGV4ICkge1xyXG5cclxuXHRpZiAoIGl0ZW1zLmxlbmd0aCA9PT0gMCApIHtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHJcblx0Ly8gQ2FsbCBtaXhpbiBtZXRob2QgdG8gZG8gdGhlIGFkZGluZ1xyXG5cdE9PLnVpLm1peGluLkdyb3VwRWxlbWVudC5wcm90b3R5cGUuYWRkSXRlbXMuY2FsbCggdGhpcywgaXRlbXMsIGluZGV4ICk7XHJcblxyXG5cdC8vIEF1dG9maWxsIHJhdGluZ3MgKGlmIGFibGUgdG8sIGFuZCBpZiBlbmFibGVkIGluIHByZWZlcmVuY2VzKVxyXG5cdGlmICghdGhpcy5pdGVtcy5zb21lKGJhbm5lciA9PiBiYW5uZXIuaXNTaGVsbFRlbXBsYXRlKSkge1xyXG5cdFx0dGhpcy5hdXRvZmlsbENsYXNzUmF0aW5ncygpO1xyXG5cdH1cclxuXHR0aGlzLmF1dG9maWxsSW1wb3J0YW5jZVJhdGluZ3MoKTtcclxuXHJcblx0Ly8gZW1pdCB1cGRhdGVkU2l6ZSBldmVudCBcclxuXHR0aGlzLm9uVXBkYXRlZFNpemUoKTtcclxuXHJcblx0cmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5CYW5uZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5hdXRvZmlsbENsYXNzUmF0aW5ncyA9IGZ1bmN0aW9uKGNvbmZpZykge1xyXG5cdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcclxuXHQvLyBPbmx5IGF1dG9maWxsIGlmIHNldCBpbiBwcmVmZXJlbmNlc1xyXG5cdGlmICghdGhpcy5wcmVmZXJlbmNlcy5hdXRvZmlsbENsYXNzRnJvbU90aGVycyAmJiAhdGhpcy5wcmVmZXJlbmNlcy5hdXRvZmlsbENsYXNzRnJvbU9yZXMgJiYgIWNvbmZpZy5mb3JCYW5uZXJTaGVsbCkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHQvLyBDaGVjayB3aGF0IGJhbm5lcnMgYWxyZWFkeSBoYXZlXHJcblx0Y29uc3QgdW5pcXVlQ2xhc3NSYXRpbmdzID0gdW5pcXVlQXJyYXkoIGZpbHRlckFuZE1hcChcclxuXHRcdHRoaXMuaXRlbXMsXHJcblx0XHRiYW5uZXIgPT4ge1xyXG5cdFx0XHRpZiAoYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSB8fCAhYmFubmVyLmhhc0NsYXNzUmF0aW5ncykge1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjb25zdCBjbGFzc0l0ZW0gPSBiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuZmluZFNlbGVjdGVkSXRlbSgpO1xyXG5cdFx0XHRyZXR1cm4gY2xhc3NJdGVtICYmIGNsYXNzSXRlbS5nZXREYXRhKCk7XHJcblx0XHR9LFxyXG5cdFx0YmFubmVyID0+IGJhbm5lci5jbGFzc0Ryb3Bkb3duLmdldE1lbnUoKS5maW5kU2VsZWN0ZWRJdGVtKCkuZ2V0RGF0YSgpXHJcblx0KSk7XHJcblx0Ly8gQ2FuJ3QgYXV0b2ZpbGwgaWYgdGhlcmUgaXNuJ3QgZWl0aGVyIGEgc2luZ2xlIHZhbHVlLCBvciBubyB2YWx1ZVxyXG5cdGlmICh1bmlxdWVDbGFzc1JhdGluZ3MubGVuZ3RoID4gMSkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHQvLyBEZXRlcm1pbmUgd2hhdCB0byBhdXRvZmlsbCB3aXRoXHJcblx0bGV0IGF1dG9DbGFzcztcclxuXHRpZiAodW5pcXVlQ2xhc3NSYXRpbmdzLmxlbmd0aCA9PT0gMSAmJiAodGhpcy5wcmVmZXJlbmNlcy5hdXRvZmlsbENsYXNzRnJvbU90aGVycyB8fCBjb25maWcuZm9yQmFubmVyU2hlbGwpKSB7XHJcblx0XHRhdXRvQ2xhc3MgPSB1bmlxdWVDbGFzc1JhdGluZ3NbMF07XHJcblx0fSBlbHNlIGlmICh1bmlxdWVDbGFzc1JhdGluZ3MubGVuZ3RoID09PSAwICYmIHRoaXMucHJlZmVyZW5jZXMuYXV0b2ZpbGxDbGFzc0Zyb21PcmVzICYmIHRoaXMub3Jlc0NsYXNzKSB7XHJcblx0XHQvLyBEb24ndCBhdXRvZmlsbCBhYm92ZSBDLWNsYXNzXHJcblx0XHRzd2l0Y2godGhpcy5vcmVzQ2xhc3MpIHtcclxuXHRcdGNhc2UgXCJTdHViXCI6IGNhc2UgXCJTdGFydFwiOiBjYXNlIFwiQ1wiOiBjYXNlIFwiTGlzdFwiOlxyXG5cdFx0XHRhdXRvQ2xhc3MgPSB0aGlzLm9yZXNDbGFzcztcclxuXHRcdH1cclxuXHR9IGVsc2Uge1xyXG5cdFx0Ly8gbm90aGluZyB0byBkb1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHQvLyBEbyB0aGUgYXV0b2ZpbGxpbmdcclxuXHR0aGlzLml0ZW1zLmZvckVhY2goYmFubmVyID0+IHtcclxuXHRcdGlmICghYmFubmVyLmhhc0NsYXNzUmF0aW5ncyAmJiAhYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRjb25zdCBjbGFzc0l0ZW0gPSBiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuZmluZFNlbGVjdGVkSXRlbSgpO1xyXG5cdFx0aWYgKGNsYXNzSXRlbSAmJiBjbGFzc0l0ZW0uZ2V0RGF0YSgpICYmICFjb25maWcuZm9yQmFubmVyU2hlbGwpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0aWYgKGNvbmZpZy5mb3JCYW5uZXJTaGVsbCAmJiAhYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSAmJiBjbGFzc0l0ZW0uZ2V0RGF0YSgpID09PSBhdXRvQ2xhc3MpIHtcclxuXHRcdFx0YmFubmVyLmNsYXNzRHJvcGRvd24uZ2V0TWVudSgpLnNlbGVjdEl0ZW1CeURhdGEobnVsbCk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGJhbm5lci5jbGFzc0Ryb3Bkb3duLmdldE1lbnUoKS5zZWxlY3RJdGVtQnlEYXRhKGF1dG9DbGFzcyk7XHJcblx0XHRiYW5uZXIuY2xhc3NEcm9wZG93bi5zZXRBdXRvZmlsbGVkKHRydWUpO1xyXG5cdH0pO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuYXV0b2ZpbGxJbXBvcnRhbmNlUmF0aW5ncyA9IGZ1bmN0aW9uKCkge1xyXG5cdGlmICghdGhpcy5wcmVmZXJlbmNlcy5hdXRvZmlsbEltcG9ydGFuY2UpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0Y29uc3QgaXNSZWd1bGFyQXJ0aWNsZSA9IHRoaXMucGFnZUluZm8gJiYgdGhpcy5wYWdlSW5mby5pc0FydGljbGUgJiYgIXRoaXMucGFnZUluZm8ucmVkaXJlY3QgJiYgIXRoaXMucGFnZUluZm8uaXNEaXNhbWJpZztcclxuXHRpZiAoIWlzUmVndWxhckFydGljbGUpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0Ly8gVE9ETzogU2hvdWxkIHRyeSB0byBmaW5kIGEgc21hcnRlciwgYmFubmVyLXNwZWNpZmljIHdheSBvZiBkZXRlcm1pbmluZyBpbXBvcnRhbmNlLlxyXG5cdC8vIE1heWJlIGRvIHNvbWV0aGluZyB3aXRoICBPUkVTJ3MgXCJkcmFmdHRvcGljXCIgbW9kZWwuXHJcblx0Y29uc3QgYXV0b0ltcG9ydGFuY2UgPSBcIkxvd1wiO1xyXG5cdHRoaXMuaXRlbXMuZm9yRWFjaChiYW5uZXIgPT4ge1xyXG5cdFx0aWYgKCFiYW5uZXIuaGFzSW1wb3J0YW5jZVJhdGluZ3MpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgaW1wb3J0YW5jZUl0ZW0gPSBiYW5uZXIuaW1wb3J0YW5jZURyb3Bkb3duLmdldE1lbnUoKS5maW5kU2VsZWN0ZWRJdGVtKCk7XHJcblx0XHRpZiAoaW1wb3J0YW5jZUl0ZW0gJiYgaW1wb3J0YW5jZUl0ZW0uZ2V0RGF0YSgpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGJhbm5lci5pbXBvcnRhbmNlRHJvcGRvd24uZ2V0TWVudSgpLnNlbGVjdEl0ZW1CeURhdGEoYXV0b0ltcG9ydGFuY2UpO1xyXG5cdFx0YmFubmVyLmltcG9ydGFuY2VEcm9wZG93bi5zZXRBdXRvZmlsbGVkKHRydWUpO1xyXG5cdH0pO1xyXG59O1xyXG5cclxuQmFubmVyTGlzdFdpZGdldC5wcm90b3R5cGUuc2V0UHJlZmVyZW5jZXMgPSBmdW5jdGlvbihwcmVmcykge1xyXG5cdHRoaXMucHJlZmVyZW5jZXMgPSBwcmVmcztcclxuXHR0aGlzLml0ZW1zLmZvckVhY2goYmFubmVyID0+IGJhbm5lci5zZXRQcmVmZXJlbmNlcyhwcmVmcykpO1xyXG5cdHRoaXMuYXV0b2ZpbGxDbGFzc1JhdGluZ3MoKTtcclxuXHR0aGlzLmF1dG9maWxsSW1wb3J0YW5jZVJhdGluZ3MoKTtcclxufTtcclxuXHJcbkJhbm5lckxpc3RXaWRnZXQucHJvdG90eXBlLm1ha2VXaWtpdGV4dCA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciBiYW5uZXJzV2lraXRleHQgPSBmaWx0ZXJBbmRNYXAoXHJcblx0XHR0aGlzLml0ZW1zLFxyXG5cdFx0YmFubmVyID0+ICFiYW5uZXIuaXNTaGVsbFRlbXBsYXRlLFxyXG5cdFx0YmFubmVyID0+IGJhbm5lci5tYWtlV2lraXRleHQoKVxyXG5cdCkuam9pbihcIlxcblwiKTtcclxuXHR2YXIgc2hlbGxUZW1wbGF0ZSA9IHRoaXMuaXRlbXMuZmluZChiYW5uZXIgPT4gYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSk7XHJcblx0aWYgKCFzaGVsbFRlbXBsYXRlKSB7XHJcblx0XHRyZXR1cm4gYmFubmVyc1dpa2l0ZXh0O1xyXG5cdH1cclxuXHR2YXIgc2hlbGxQYXJhbTEgPSBuZXcgUGFyYW1ldGVyV2lkZ2V0KHtcclxuXHRcdG5hbWU6XCIxXCIsXHJcblx0XHR2YWx1ZTogXCJcXG5cIiArIGJhbm5lcnNXaWtpdGV4dCArIFwiXFxuXCIgK1xyXG5cdFx0XHQoc2hlbGxUZW1wbGF0ZS5ub25TdGFuZGFyZFRlbXBsYXRlc1x0PyBzaGVsbFRlbXBsYXRlLm5vblN0YW5kYXJkVGVtcGxhdGVzICsgXCJcXG5cIiA6IFwiXCIpXHJcblx0fSk7XHJcblx0c2hlbGxUZW1wbGF0ZS5wYXJhbWV0ZXJMaXN0LmFkZEl0ZW1zKFsgc2hlbGxQYXJhbTEgXSk7XHJcblx0dmFyIHNoZWxsV2lraXRleHQgPSBzaGVsbFRlbXBsYXRlLm1ha2VXaWtpdGV4dCgpO1xyXG5cdHNoZWxsVGVtcGxhdGUucGFyYW1ldGVyTGlzdC5yZW1vdmVJdGVtcyhbIHNoZWxsUGFyYW0xIF0pO1xyXG5cdHJldHVybiBzaGVsbFdpa2l0ZXh0O1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQmFubmVyTGlzdFdpZGdldDtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IFBhcmFtZXRlckxpc3RXaWRnZXQgZnJvbSBcIi4vUGFyYW1ldGVyTGlzdFdpZGdldFwiO1xyXG5pbXBvcnQgUGFyYW1ldGVyV2lkZ2V0IGZyb20gXCIuL1BhcmFtZXRlcldpZGdldFwiO1xyXG5pbXBvcnQgRHJvcGRvd25QYXJhbWV0ZXJXaWRnZXQgZnJvbSBcIi4vRHJvcGRvd25QYXJhbWV0ZXJXaWRnZXRcIjtcclxuaW1wb3J0IFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQgZnJvbSBcIi4vU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldFwiO1xyXG5pbXBvcnQgeyBmaWx0ZXJBbmRNYXAsIGNsYXNzTWFzaywgaW1wb3J0YW5jZU1hc2sgfSBmcm9tIFwiLi4vLi4vdXRpbFwiO1xyXG5pbXBvcnQge1RlbXBsYXRlLCBnZXRXaXRoUmVkaXJlY3RUb30gZnJvbSBcIi4uLy4uL1RlbXBsYXRlXCI7XHJcbmltcG9ydCBIb3Jpem9udGFsTGF5b3V0V2lkZ2V0IGZyb20gXCIuL0hvcml6b250YWxMYXlvdXRXaWRnZXRcIjtcclxuaW1wb3J0IGdsb2JhbENvbmZpZyBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG5mdW5jdGlvbiBCYW5uZXJXaWRnZXQoIHRlbXBsYXRlLCBjb25maWcgKSB7XHJcblx0Ly8gQ29uZmlndXJhdGlvbiBpbml0aWFsaXphdGlvblxyXG5cdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdEJhbm5lcldpZGdldC5zdXBlci5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxuXHR0aGlzLiRvdmVybGF5ID0gY29uZmlnLiRvdmVybGF5O1xyXG5cclxuXHQvKiAtLS0gUFJFRlMgLS0tICovXHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IGNvbmZpZy5wcmVmZXJlbmNlcztcclxuXHRcclxuXHQvKiAtLS0gUFJPUFMgLS0tICovXHJcblx0dGhpcy5wYXJhbURhdGEgPSB0ZW1wbGF0ZS5wYXJhbURhdGE7XHJcblx0dGhpcy5wYXJhbUFsaWFzZXMgPSB0ZW1wbGF0ZS5wYXJhbUFsaWFzZXMgfHwge307XHJcblx0dGhpcy5wYXJhbWV0ZXJTdWdnZXN0aW9ucyA9IHRlbXBsYXRlLnBhcmFtZXRlclN1Z2dlc3Rpb25zO1xyXG5cdHRoaXMubmFtZSA9IHRlbXBsYXRlLm5hbWU7XHJcblx0dGhpcy53aWtpdGV4dCA9IHRlbXBsYXRlLndpa2l0ZXh0O1xyXG5cdHRoaXMucGlwZVN0eWxlID0gdGVtcGxhdGUucGlwZVN0eWxlO1xyXG5cdHRoaXMuZXF1YWxzU3R5bGUgPSB0ZW1wbGF0ZS5lcXVhbHNTdHlsZTtcclxuXHR0aGlzLmVuZEJyYWNlc1N0eWxlID0gdGVtcGxhdGUuZW5kQnJhY2VzU3R5bGU7XHJcblx0dGhpcy5tYWluVGV4dCA9IHRlbXBsYXRlLmdldFRpdGxlKCkuZ2V0TWFpblRleHQoKTtcclxuXHR0aGlzLnJlZGlyZWN0VGFyZ2V0TWFpblRleHQgPSB0ZW1wbGF0ZS5yZWRpcmVjdFRhcmdldCAmJiB0ZW1wbGF0ZS5yZWRpcmVjdFRhcmdldC5nZXRNYWluVGV4dCgpO1xyXG5cdHRoaXMuaXNTaGVsbFRlbXBsYXRlID0gdGVtcGxhdGUuaXNTaGVsbFRlbXBsYXRlKCk7XHJcblx0dGhpcy5jaGFuZ2VkID0gdGVtcGxhdGUucGFyYW1ldGVycy5zb21lKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIuYXV0b2ZpbGxlZCk7IC8vIGluaXRpYWxseSBmYWxzZSwgdW5sZXNzIHNvbWUgcGFyYW1ldGVycyB3ZXJlIGF1dG9maWxsZWRcclxuXHR0aGlzLmhhc0NsYXNzUmF0aW5ncyA9IHRlbXBsYXRlLmNsYXNzZXMgJiYgdGVtcGxhdGUuY2xhc3Nlcy5sZW5ndGg7XHJcblx0dGhpcy5oYXNJbXBvcnRhbmNlUmF0aW5ncyA9IHRlbXBsYXRlLmltcG9ydGFuY2VzICYmIHRlbXBsYXRlLmltcG9ydGFuY2VzLmxlbmd0aDtcclxuXHR0aGlzLmluYWN0aXZlUHJvamVjdCA9IHRlbXBsYXRlLmluYWN0aXZlUHJvamVjdDtcclxuXHJcblx0LyogLS0tIFRJVExFIEFORCBSQVRJTkdTIC0tLSAqL1xyXG5cclxuXHR0aGlzLnJlbW92ZUJ1dHRvbiA9IG5ldyBPTy51aS5CdXR0b25XaWRnZXQoIHtcclxuXHRcdGljb246IFwidHJhc2hcIixcclxuXHRcdGxhYmVsOiBcIlJlbW92ZSBiYW5uZXJcIixcclxuXHRcdHRpdGxlOiBcIlJlbW92ZSBiYW5uZXJcIixcclxuXHRcdGZsYWdzOiBcImRlc3RydWN0aXZlXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxkaXYgc3R5bGU9XFxcIndpZHRoOjEwMCVcXFwiPlwiKVxyXG5cdH0gKTtcclxuXHR0aGlzLmNsZWFyQnV0dG9uID0gbmV3IE9PLnVpLkJ1dHRvbldpZGdldCgge1xyXG5cdFx0aWNvbjogXCJjYW5jZWxcIixcclxuXHRcdGxhYmVsOiBcIkNsZWFyIHBhcmFtZXRlcnNcIixcclxuXHRcdHRpdGxlOiBcIkNsZWFyIHBhcmFtZXRlcnNcIixcclxuXHRcdGZsYWdzOiBcImRlc3RydWN0aXZlXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxkaXYgc3R5bGU9XFxcIndpZHRoOjEwMCVcXFwiPlwiKVxyXG5cdH0gKTtcclxuXHR0aGlzLnJlbW92ZUJ1dHRvbi4kZWxlbWVudC5maW5kKFwiYVwiKS5jc3MoXCJ3aWR0aFwiLFwiMTAwJVwiKTtcclxuXHR0aGlzLmNsZWFyQnV0dG9uLiRlbGVtZW50LmZpbmQoXCJhXCIpLmNzcyhcIndpZHRoXCIsXCIxMDAlXCIpO1xyXG5cclxuXHR0aGlzLnRpdGxlQnV0dG9uc0dyb3VwID0gbmV3IE9PLnVpLkJ1dHRvbkdyb3VwV2lkZ2V0KCB7XHJcblx0XHRpdGVtczogWyB0aGlzLnJlbW92ZUJ1dHRvbixcdHRoaXMuY2xlYXJCdXR0b24gXSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J3dpZHRoOjEwMCU7Jz5cIiksXHJcblx0fSApO1xyXG5cclxuXHR0aGlzLm1haW5MYWJlbFBvcHVwQnV0dG9uID0gbmV3IE9PLnVpLlBvcHVwQnV0dG9uV2lkZ2V0KCB7XHJcblx0XHRsYWJlbDogYHt7JHt0ZW1wbGF0ZS5nZXRUaXRsZSgpLmdldE1haW5UZXh0KCl9fX0ke3RoaXMuaW5hY3RpdmVQcm9qZWN0ID8gXCIgKGluYWN0aXZlKVwiIDogXCJcIn1gLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NDglO21hcmdpbi1yaWdodDowO3BhZGRpbmctcmlnaHQ6OHB4Jz5cIiksXHJcblx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHRcdGluZGljYXRvcjpcImRvd25cIixcclxuXHRcdGZyYW1lZDpmYWxzZSxcclxuXHRcdHBvcHVwOiB7XHJcblx0XHRcdCRjb250ZW50OiB0aGlzLnRpdGxlQnV0dG9uc0dyb3VwLiRlbGVtZW50LFxyXG5cdFx0XHR3aWR0aDogMjAwLFxyXG5cdFx0XHRwYWRkZWQ6IGZhbHNlLFxyXG5cdFx0XHRhbGlnbjogXCJmb3JjZS1yaWdodFwiLFxyXG5cdFx0XHRhbmNob3I6IGZhbHNlXHJcblx0XHR9XHJcblx0fSApO1xyXG5cdHRoaXMubWFpbkxhYmVsUG9wdXBCdXR0b24uJGVsZW1lbnRcclxuXHRcdC5jaGlsZHJlbihcImFcIikuZmlyc3QoKS5jc3Moe1wiZm9udC1zaXplXCI6XCIxMTAlXCJ9KVxyXG5cdFx0LmZpbmQoXCJzcGFuLm9vLXVpLWxhYmVsRWxlbWVudC1sYWJlbFwiKS5jc3Moe1wid2hpdGUtc3BhY2VcIjpcIm5vcm1hbFwifSk7XHJcblxyXG5cdC8vIFJhdGluZyBkcm9wZG93bnNcclxuXHRpZiAodGhpcy5pc1NoZWxsVGVtcGxhdGUpIHtcclxuXHRcdHRoaXMuY2xhc3NEcm9wZG93biA9IG5ldyBEcm9wZG93blBhcmFtZXRlcldpZGdldCgge1xyXG5cdFx0XHRsYWJlbDogbmV3IE9PLnVpLkh0bWxTbmlwcGV0KFwiPHNwYW4gc3R5bGU9XFxcImNvbG9yOiM3NzdcXFwiPkNsYXNzPC9zcGFuPlwiKSxcclxuXHRcdFx0bWVudToge1xyXG5cdFx0XHRcdGl0ZW1zOiBbXHJcblx0XHRcdFx0XHRuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0XHRkYXRhOiBudWxsLFxyXG5cdFx0XHRcdFx0XHRsYWJlbDogbmV3IE9PLnVpLkh0bWxTbmlwcGV0KGA8c3BhbiBzdHlsZT1cImNvbG9yOiM3NzdcIj4oJHtjb25maWcuaXNBcnRpY2xlID8gXCJubyBjbGFzc1wiIDogXCJhdXRvLWRldGVjdFwifSk8L3NwYW4+YClcclxuXHRcdFx0XHRcdH0gKSxcclxuXHRcdFx0XHRcdC4uLmdsb2JhbENvbmZpZy5iYW5uZXJEZWZhdWx0cy5jbGFzc2VzLm1hcCggY2xhc3NuYW1lID0+XHJcblx0XHRcdFx0XHRcdG5ldyBPTy51aS5NZW51T3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRcdFx0ZGF0YTogY2xhc3NuYW1lLFxyXG5cdFx0XHRcdFx0XHRcdGxhYmVsOiBjbGFzc25hbWVcclxuXHRcdFx0XHRcdFx0fSApXHJcblx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XSxcclxuXHRcdFx0fSxcclxuXHRcdFx0JG92ZXJsYXk6IHRoaXMuJG92ZXJsYXksXHJcblx0XHR9ICk7XHJcblx0XHR2YXIgc2hlbGxDbGFzc1BhcmFtID0gdGVtcGxhdGUucGFyYW1ldGVycy5maW5kKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIubmFtZSA9PT0gXCJjbGFzc1wiKTtcclxuXHRcdHRoaXMuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YSggc2hlbGxDbGFzc1BhcmFtICYmIGNsYXNzTWFzayhzaGVsbENsYXNzUGFyYW0udmFsdWUpICk7XHJcblx0fSBlbHNlIGlmICh0aGlzLmhhc0NsYXNzUmF0aW5ncykge1xyXG5cdFx0dGhpcy5jbGFzc0Ryb3Bkb3duID0gbmV3IERyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBuZXcgT08udWkuSHRtbFNuaXBwZXQoXCI8c3BhbiBzdHlsZT1cXFwiY29sb3I6Izc3N1xcXCI+Q2xhc3M8L3NwYW4+XCIpLFxyXG5cdFx0XHRtZW51OiB7XHJcblx0XHRcdFx0aXRlbXM6IFtcclxuXHRcdFx0XHRcdG5ldyBPTy51aS5NZW51T3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRcdGRhdGE6IG51bGwsXHJcblx0XHRcdFx0XHRcdGxhYmVsOiBuZXcgT08udWkuSHRtbFNuaXBwZXQoYDxzcGFuIHN0eWxlPVwiY29sb3I6Izc3N1wiPigke2NvbmZpZy5pc0FydGljbGUgPyBcImluaGVyaXQgZnJvbSBzaGVsbFwiIDogXCJhdXRvLWRldGVjdFwifSk8L3NwYW4+YClcclxuXHRcdFx0XHRcdH0gKSxcclxuXHRcdFx0XHRcdC4uLnRlbXBsYXRlLmNsYXNzZXMubWFwKCBjbGFzc25hbWUgPT5cclxuXHRcdFx0XHRcdFx0bmV3IE9PLnVpLk1lbnVPcHRpb25XaWRnZXQoIHtcclxuXHRcdFx0XHRcdFx0XHRkYXRhOiBjbGFzc25hbWUsXHJcblx0XHRcdFx0XHRcdFx0bGFiZWw6IGNsYXNzbmFtZVxyXG5cdFx0XHRcdFx0XHR9IClcclxuXHRcdFx0XHRcdClcclxuXHRcdFx0XHRdLFxyXG5cdFx0XHR9LFxyXG5cdFx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHRcdH0gKTtcclxuXHRcdHZhciBjbGFzc1BhcmFtID0gdGVtcGxhdGUucGFyYW1ldGVycy5maW5kKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIubmFtZSA9PT0gXCJjbGFzc1wiKTtcclxuXHRcdHRoaXMuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YSggY2xhc3NQYXJhbSAmJiBjbGFzc01hc2soY2xhc3NQYXJhbS52YWx1ZSkgKTtcclxuXHR9XHJcblxyXG5cdGlmICh0aGlzLmhhc0ltcG9ydGFuY2VSYXRpbmdzKSB7XHJcblx0XHR0aGlzLmltcG9ydGFuY2VEcm9wZG93biA9IG5ldyBEcm9wZG93blBhcmFtZXRlcldpZGdldCgge1xyXG5cdFx0XHRsYWJlbDogbmV3IE9PLnVpLkh0bWxTbmlwcGV0KFwiPHNwYW4gc3R5bGU9XFxcImNvbG9yOiM3NzdcXFwiPkltcG9ydGFuY2U8L3NwYW4+XCIpLFxyXG5cdFx0XHRtZW51OiB7XHJcblx0XHRcdFx0aXRlbXM6IFtcclxuXHRcdFx0XHRcdG5ldyBPTy51aS5NZW51T3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRcdGRhdGE6IG51bGwsIGxhYmVsOiBuZXcgT08udWkuSHRtbFNuaXBwZXQoYDxzcGFuIHN0eWxlPVwiY29sb3I6Izc3N1wiPigke2NvbmZpZy5pc0FydGljbGUgPyBcIm5vIGltcG9ydGFuY2VcIiA6IFwiYXV0by1kZXRlY3RcIn0pPC9zcGFuPmApXHJcblx0XHRcdFx0XHR9ICksXHJcblx0XHRcdFx0XHQuLi50ZW1wbGF0ZS5pbXBvcnRhbmNlcy5tYXAoaW1wb3J0YW5jZSA9PlxyXG5cdFx0XHRcdFx0XHRuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0XHRcdGRhdGE6IGltcG9ydGFuY2UsXHJcblx0XHRcdFx0XHRcdFx0bGFiZWw6IGltcG9ydGFuY2VcclxuXHRcdFx0XHRcdFx0fSApXHJcblx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XVxyXG5cdFx0XHR9LFxyXG5cdFx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHRcdH0gKTtcclxuXHRcdHZhciBpbXBvcnRhbmNlUGFyYW0gPSB0ZW1wbGF0ZS5wYXJhbWV0ZXJzLmZpbmQocGFyYW1ldGVyID0+IHBhcmFtZXRlci5uYW1lID09PSBcImltcG9ydGFuY2VcIik7XHJcblx0XHR0aGlzLmltcG9ydGFuY2VEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YSggaW1wb3J0YW5jZVBhcmFtICYmIGltcG9ydGFuY2VNYXNrKGltcG9ydGFuY2VQYXJhbS52YWx1ZSkgKTtcclxuXHR9XHJcblxyXG5cdHRoaXMudGl0bGVMYXlvdXQgPSBuZXcgT08udWkuSG9yaXpvbnRhbExheW91dCgge1xyXG5cdFx0aXRlbXM6IFsgdGhpcy5tYWluTGFiZWxQb3B1cEJ1dHRvbiBdXHJcblx0fSApO1xyXG5cdGlmICh0aGlzLmhhc0NsYXNzUmF0aW5ncyB8fCB0aGlzLmlzU2hlbGxUZW1wbGF0ZSkge1xyXG5cdFx0dGhpcy50aXRsZUxheW91dC5hZGRJdGVtcyhbIHRoaXMuY2xhc3NEcm9wZG93biBdKTtcclxuXHR9XHJcblx0aWYgKHRoaXMuaGFzSW1wb3J0YW5jZVJhdGluZ3MpIHtcclxuXHRcdHRoaXMudGl0bGVMYXlvdXQuYWRkSXRlbXMoWyB0aGlzLmltcG9ydGFuY2VEcm9wZG93biBdKTtcclxuXHR9XHJcblxyXG5cdC8qIC0tLSBQQVJBTUVURVJTIExJU1QgLS0tICovXHJcblxyXG5cdHZhciBwYXJhbWV0ZXJXaWRnZXRzID0gZmlsdGVyQW5kTWFwKFxyXG5cdFx0dGVtcGxhdGUucGFyYW1ldGVycyxcclxuXHRcdHBhcmFtID0+IHtcclxuXHRcdFx0aWYgKCB0aGlzLmlzU2hlbGxUZW1wbGF0ZSApIHtcclxuXHRcdFx0XHRpZiAocGFyYW0ubmFtZSA9PSBcIjFcIikge1xyXG5cdFx0XHRcdFx0dGhpcy5zaGVsbFBhcmFtMVZhbHVlID0gcGFyYW0udmFsdWU7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiBwYXJhbS5uYW1lICE9PSBcImNsYXNzXCI7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHBhcmFtLm5hbWUgIT09IFwiY2xhc3NcIiAmJiBwYXJhbS5uYW1lICE9PSBcImltcG9ydGFuY2VcIjtcclxuXHRcdH0sXHJcblx0XHRwYXJhbSA9PiBuZXcgUGFyYW1ldGVyV2lkZ2V0KHBhcmFtLCB0ZW1wbGF0ZS5wYXJhbURhdGFbcGFyYW0ubmFtZV0sIHskb3ZlcmxheTogdGhpcy4kb3ZlcmxheX0pXHJcblx0KTtcclxuXHJcblx0dGhpcy5wYXJhbWV0ZXJMaXN0ID0gbmV3IFBhcmFtZXRlckxpc3RXaWRnZXQoIHtcclxuXHRcdGl0ZW1zOiBwYXJhbWV0ZXJXaWRnZXRzLFxyXG5cdFx0cHJlZmVyZW5jZXM6IHRoaXMucHJlZmVyZW5jZXNcclxuXHR9ICk7XHJcblxyXG5cdC8qIC0tLSBBREQgUEFSQU1FVEVSIFNFQ1RJT04gLS0tICovXHJcblxyXG5cdHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0ID0gbmV3IFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQoe1xyXG5cdFx0c3VnZ2VzdGlvbnM6IHRlbXBsYXRlLnBhcmFtZXRlclN1Z2dlc3Rpb25zLFxyXG5cdFx0cGxhY2Vob2xkZXI6IFwicGFyYW1ldGVyIG5hbWVcIixcclxuXHRcdCRlbGVtZW50OiAkKFwiPGRpdiBzdHlsZT0nZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NDAlJz5cIiksXHJcblx0XHR2YWxpZGF0ZTogZnVuY3Rpb24odmFsKSB7XHJcblx0XHRcdGxldCB7dmFsaWROYW1lLCBuYW1lLCB2YWx1ZX0gPSB0aGlzLmdldEFkZFBhcmFtZXRlcnNJbmZvKHZhbCk7XHJcblx0XHRcdHJldHVybiAoIW5hbWUgJiYgIXZhbHVlKSA/IHRydWUgOiB2YWxpZE5hbWU7XHJcblx0XHR9LmJpbmQodGhpcyksXHJcblx0XHRhbGxvd1N1Z2dlc3Rpb25zV2hlbkVtcHR5OiB0cnVlLFxyXG5cdFx0JG92ZXJsYXk6IHRoaXMuJG92ZXJsYXlcclxuXHR9KTtcclxuXHR0aGlzLnVwZGF0ZUFkZFBhcmFtZXRlck5hbWVTdWdnZXN0aW9ucygpO1xyXG5cdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWVJbnB1dCA9IG5ldyBTdWdnZXN0aW9uTG9va3VwVGV4dElucHV0V2lkZ2V0KHtcclxuXHRcdHBsYWNlaG9sZGVyOiBcInBhcmFtZXRlciB2YWx1ZVwiLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8ZGl2IHN0eWxlPSdkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDo0MCUnPlwiKSxcclxuXHRcdHZhbGlkYXRlOiBmdW5jdGlvbih2YWwpIHtcclxuXHRcdFx0bGV0IHt2YWxpZFZhbHVlLCBuYW1lLCB2YWx1ZX0gPSB0aGlzLmdldEFkZFBhcmFtZXRlcnNJbmZvKG51bGwsIHZhbCk7XHJcblx0XHRcdHJldHVybiAoIW5hbWUgJiYgIXZhbHVlKSA/IHRydWUgOiB2YWxpZFZhbHVlO1xyXG5cdFx0fS5iaW5kKHRoaXMpLFxyXG5cdFx0YWxsb3dTdWdnZXN0aW9uc1doZW5FbXB0eTogdHJ1ZSxcclxuXHRcdCRvdmVybGF5OiB0aGlzLiRvdmVybGF5XHJcblx0fSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KHtcclxuXHRcdGxhYmVsOiBcIkFkZFwiLFxyXG5cdFx0aWNvbjogXCJhZGRcIixcclxuXHRcdGZsYWdzOiBcInByb2dyZXNzaXZlXCJcclxuXHR9KS5zZXREaXNhYmxlZCh0cnVlKTtcclxuXHR0aGlzLmFkZFBhcmFtZXRlckNvbnRyb2xzID0gbmV3IEhvcml6b250YWxMYXlvdXRXaWRnZXQoIHtcclxuXHRcdGl0ZW1zOiBbXHJcblx0XHRcdHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0LFxyXG5cdFx0XHRuZXcgT08udWkuTGFiZWxXaWRnZXQoe2xhYmVsOlwiPVwifSksXHJcblx0XHRcdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWVJbnB1dCxcclxuXHRcdFx0dGhpcy5hZGRQYXJhbWV0ZXJCdXR0b25cclxuXHRcdF1cclxuXHR9ICk7XHJcblxyXG5cdHRoaXMuYWRkUGFyYW1ldGVyTGF5b3V0ID0gbmV3IE9PLnVpLkZpZWxkTGF5b3V0KHRoaXMuYWRkUGFyYW1ldGVyQ29udHJvbHMsIHtcclxuXHRcdGxhYmVsOiBcIkFkZCBwYXJhbWV0ZXI6XCIsXHJcblx0XHRhbGlnbjogXCJ0b3BcIlxyXG5cdH0pLnRvZ2dsZShmYWxzZSk7XHJcblx0Ly8gQSBoYWNrIHRvIG1ha2UgbWVzc2FnZXMgYXBwZWFyIG9uIHRoZWlyIG93biBsaW5lXHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJMYXlvdXQuJGVsZW1lbnQuZmluZChcIi5vby11aS1maWVsZExheW91dC1tZXNzYWdlc1wiKS5jc3Moe1xyXG5cdFx0XCJjbGVhclwiOiBcImJvdGhcIixcclxuXHRcdFwicGFkZGluZy10b3BcIjogMFxyXG5cdH0pO1xyXG5cclxuXHQvKiAtLS0gT1ZFUkFMTCBMQVlPVVQvRElTUExBWSAtLS0gKi9cclxuXHJcblx0Ly8gRGlzcGxheSB0aGUgbGF5b3V0IGVsZW1lbnRzLCBhbmQgYSBydWxlXHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLWJhbm5lcldpZGdldFwiKS5hcHBlbmQoXHJcblx0XHR0aGlzLnRpdGxlTGF5b3V0LiRlbGVtZW50LFxyXG5cdFx0dGhpcy5wYXJhbWV0ZXJMaXN0LiRlbGVtZW50LFxyXG5cdFx0dGhpcy5hZGRQYXJhbWV0ZXJMYXlvdXQuJGVsZW1lbnRcclxuXHQpO1xyXG5cdGlmICghdGhpcy5pc1NoZWxsVGVtcGxhdGUpIHtcclxuXHRcdHRoaXMuJGVsZW1lbnQuYXBwZW5kKCAkKFwiPGhyPlwiKSApO1xyXG5cdH1cclxuXHJcblx0aWYgKHRoaXMuaXNTaGVsbFRlbXBsYXRlKSB7XHJcblx0XHR0aGlzLiRlbGVtZW50LmNzcyh7XHJcblx0XHRcdFwiYmFja2dyb3VuZFwiOiBcIiNlZWVcIixcclxuXHRcdFx0XCJib3JkZXItcmFkaXVzXCI6IFwiMTBweFwiLFxyXG5cdFx0XHRcInBhZGRpbmdcIjogXCIwIDEwcHggNXB4XCIsXHJcblx0XHRcdFwibWFyZ2luLWJvdHRvbVwiOiBcIjEycHhcIixcclxuXHRcdFx0XCJmb250LXNpemVcIjogXCI5MiVcIlx0XHRcdFxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHQvKiAtLS0gRVZFTlQgSEFORExJTkcgLS0tICovXHJcblxyXG5cdGlmICh0aGlzLmhhc0NsYXNzUmF0aW5ncykge1xyXG5cdFx0dGhpcy5jbGFzc0Ryb3Bkb3duLmNvbm5lY3QoIHRoaXMsIHtcImNoYW5nZVwiOiBcIm9uQ2xhc3NDaGFuZ2VcIiB9ICk7XHJcblx0fVxyXG5cdGlmICh0aGlzLmhhc0ltcG9ydGFuY2VSYXRpbmdzKSB7XHJcblx0XHR0aGlzLmltcG9ydGFuY2VEcm9wZG93bi5jb25uZWN0KCB0aGlzLCB7XCJjaGFuZ2VcIjogXCJvbkltcG9ydGFuY2VDaGFuZ2VcIiB9ICk7XHJcblx0fVxyXG5cdHRoaXMucGFyYW1ldGVyTGlzdC5jb25uZWN0KCB0aGlzLCB7XHJcblx0XHRcImNoYW5nZVwiOiBcIm9uUGFyYW1ldGVyQ2hhbmdlXCIsXHJcblx0XHRcImFkZFBhcmFtZXRlcnNCdXR0b25DbGlja1wiOiBcInNob3dBZGRQYXJhbWV0ZXJJbnB1dHNcIixcclxuXHRcdFwidXBkYXRlZFNpemVcIjogXCJvblVwZGF0ZWRTaXplXCJcclxuXHR9ICk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJCdXR0b24uY29ubmVjdCh0aGlzLCB7IFwiY2xpY2tcIjogXCJvblBhcmFtZXRlckFkZFwiIH0pO1xyXG5cdHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0LmNvbm5lY3QodGhpcywge1xyXG5cdFx0XCJjaGFuZ2VcIjogXCJvbkFkZFBhcmFtZXRlck5hbWVDaGFuZ2VcIixcclxuXHRcdFwiZW50ZXJcIjogXCJvbkFkZFBhcmFtZXRlck5hbWVFbnRlclwiLFxyXG5cdFx0XCJjaG9vc2VcIjogXCJvbkFkZFBhcmFtZXRlck5hbWVFbnRlclwiXHJcblx0fSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZUlucHV0LmNvbm5lY3QodGhpcywge1xyXG5cdFx0XCJjaGFuZ2VcIjogXCJvbkFkZFBhcmFtZXRlclZhbHVlQ2hhbmdlXCIsXHJcblx0XHRcImVudGVyXCI6IFwib25BZGRQYXJhbWV0ZXJWYWx1ZUVudGVyXCIsXHJcblx0XHRcImNob29zZVwiOiBcIm9uQWRkUGFyYW1ldGVyVmFsdWVFbnRlclwiXHJcblx0fSk7XHJcblx0dGhpcy5yZW1vdmVCdXR0b24uY29ubmVjdCh0aGlzLCB7XCJjbGlja1wiOiBcIm9uUmVtb3ZlQnV0dG9uQ2xpY2tcIn0sICk7XHJcblx0dGhpcy5jbGVhckJ1dHRvbi5jb25uZWN0KCB0aGlzLCB7XCJjbGlja1wiOiBcIm9uQ2xlYXJCdXR0b25DbGlja1wifSApO1xyXG5cclxuXHQvKiAtLS0gQVBQTFkgUFJFRiAtLSAqL1xyXG5cdGlmICh0aGlzLnByZWZlcmVuY2VzLmJ5cGFzc1JlZGlyZWN0cykge1xyXG5cdFx0dGhpcy5ieXBhc3NSZWRpcmVjdCgpO1xyXG5cdH1cclxuXHJcbn1cclxuT08uaW5oZXJpdENsYXNzKCBCYW5uZXJXaWRnZXQsIE9PLnVpLldpZGdldCApO1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZW1wbGF0ZU5hbWVcclxuICogQHBhcmFtIHtPYmplY3R9IFtkYXRhXVxyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRhdGEud2l0aG91dFJhdGluZ3NcclxuICogQHBhcmFtIHtCb29sZWFufSBkYXRhLmlzV3JhcHBlclxyXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPEJhbm5lcldpZGdldD59XHJcbiAqL1xyXG5CYW5uZXJXaWRnZXQubmV3RnJvbVRlbXBsYXRlTmFtZSA9IGZ1bmN0aW9uKHRlbXBsYXRlTmFtZSwgZGF0YSwgY29uZmlnKSB7XHJcblx0dmFyIHRlbXBsYXRlID0gbmV3IFRlbXBsYXRlKCk7XHJcblx0dGVtcGxhdGUubmFtZSA9IHRlbXBsYXRlTmFtZTtcclxuXHRpZiAoZGF0YSAmJiBkYXRhLndpdGhvdXRSYXRpbmdzKSB7XHJcblx0XHR0ZW1wbGF0ZS53aXRob3V0UmF0aW5ncyA9IHRydWU7XHJcblx0fVxyXG5cdHJldHVybiBnZXRXaXRoUmVkaXJlY3RUbyh0ZW1wbGF0ZSlcclxuXHRcdC50aGVuKGZ1bmN0aW9uKHRlbXBsYXRlKSB7XHJcblx0XHRcdHJldHVybiAkLndoZW4oXHJcblx0XHRcdFx0dGVtcGxhdGUuc2V0Q2xhc3Nlc0FuZEltcG9ydGFuY2VzKCksXHJcblx0XHRcdFx0dGVtcGxhdGUuc2V0UGFyYW1EYXRhQW5kU3VnZ2VzdGlvbnMoKVxyXG5cdFx0XHQpLnRoZW4oKCkgPT4ge1xyXG5cdFx0XHRcdC8vIEFkZCBtaXNzaW5nIHJlcXVpcmVkL3N1Z2dlc3RlZCB2YWx1ZXNcclxuXHRcdFx0XHR0ZW1wbGF0ZS5hZGRNaXNzaW5nUGFyYW1zKCk7XHJcblx0XHRcdFx0Ly8gUmV0dXJuIHRoZSBub3ctbW9kaWZpZWQgdGVtcGxhdGVcclxuXHRcdFx0XHRyZXR1cm4gdGVtcGxhdGU7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSlcclxuXHRcdC50aGVuKHRlbXBsYXRlID0+IG5ldyBCYW5uZXJXaWRnZXQodGVtcGxhdGUsIGNvbmZpZykpO1xyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS5vblVwZGF0ZWRTaXplID0gZnVuY3Rpb24oKSB7XHJcblx0Ly8gRW1pdCBhbiBcInVwZGF0ZWRTaXplXCIgZXZlbnQgc28gdGhlIHBhcmVudCB3aW5kb3cgY2FuIHVwZGF0ZSBzaXplLCBpZiBuZWVkZWRcclxuXHR0aGlzLmVtaXQoXCJ1cGRhdGVkU2l6ZVwiKTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUuc2V0Q2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuY2hhbmdlZCA9IHRydWU7XHJcblx0dGhpcy5lbWl0KFwiY2hhbmdlZFwiKTtcclxuXHRpZiAodGhpcy5tYWluVGV4dCA9PT0gXCJXaWtpUHJvamVjdCBCaW9ncmFwaHlcIiB8fCB0aGlzLnJlZGlyZWN0VGFyZ2V0TWFpblRleHQgPT09IFwiV2lraVByb2plY3QgQmlvZ3JhcGh5XCIpIHtcclxuXHRcdC8vIEVtaXQgZXZlbnQgc28gQmFubmVyTGlzdFdpZGdldCBjYW4gdXBkYXRlIHRoZSBiYW5uZXIgc2hlbGwgdGVtcGxhdGUgKGlmIHByZXNlbnQpXHJcblx0XHR0aGlzLmVtaXQoXCJiaW9ncmFwaHlCYW5uZXJDaGFuZ2VcIik7XHRcdFxyXG5cdH1cclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUub25QYXJhbWV0ZXJDaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnNldENoYW5nZWQoKTtcclxuXHR0aGlzLnVwZGF0ZUFkZFBhcmFtZXRlck5hbWVTdWdnZXN0aW9ucygpO1xyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS5vbkNsYXNzQ2hhbmdlID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5zZXRDaGFuZ2VkKCk7XHJcblx0dGhpcy5jbGFzc0NoYW5nZWQgPSB0cnVlO1xyXG5cdHZhciBjbGFzc0l0ZW0gPSB0aGlzLmNsYXNzRHJvcGRvd24uZ2V0TWVudSgpLmZpbmRTZWxlY3RlZEl0ZW0oKTtcclxuXHRpZiAoY2xhc3NJdGVtICYmIGNsYXNzSXRlbS5nZXREYXRhKCkgPT0gbnVsbCApIHtcclxuXHRcdC8vIGNsZWFyIHNlbGVjdGlvblxyXG5cdFx0dGhpcy5jbGFzc0Ryb3Bkb3duLmdldE1lbnUoKS5zZWxlY3RJdGVtKCk7XHJcblx0fVxyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS5vbkltcG9ydGFuY2VDaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnNldENoYW5nZWQoKTtcclxuXHR0aGlzLmltcG9ydGFuY2VDaGFuZ2VkID0gdHJ1ZTtcclxuXHR2YXIgaW1wb3J0YW5jZUl0ZW0gPSB0aGlzLmltcG9ydGFuY2VEcm9wZG93bi5nZXRNZW51KCkuZmluZFNlbGVjdGVkSXRlbSgpO1xyXG5cdGlmIChpbXBvcnRhbmNlSXRlbSAmJiBpbXBvcnRhbmNlSXRlbS5nZXREYXRhKCkgPT0gbnVsbCApIHtcclxuXHRcdC8vIGNsZWFyIHNlbGVjdGlvblxyXG5cdFx0dGhpcy5pbXBvcnRhbmNlRHJvcGRvd24uZ2V0TWVudSgpLnNlbGVjdEl0ZW0oKTtcclxuXHR9XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLnNob3dBZGRQYXJhbWV0ZXJJbnB1dHMgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmFkZFBhcmFtZXRlckxheW91dC50b2dnbGUodHJ1ZSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJOYW1lSW5wdXQuZm9jdXMoKTtcclxuXHR0aGlzLm9uVXBkYXRlZFNpemUoKTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUuZ2V0QWRkUGFyYW1ldGVyc0luZm8gPSBmdW5jdGlvbihuYW1lSW5wdXRWYWwsIHZhbHVlSW5wdXRWYWwpIHtcclxuXHR2YXIgbmFtZSA9IG5hbWVJbnB1dFZhbCAmJiBuYW1lSW5wdXRWYWwudHJpbSgpIHx8IHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0LmdldFZhbHVlKCkudHJpbSgpO1xyXG5cdHZhciBwYXJhbUFscmVhZHlJbmNsdWRlZCA9IG5hbWUgPT09IFwiY2xhc3NcIiB8fFxyXG5cdFx0bmFtZSA9PT0gXCJpbXBvcnRhbmNlXCIgfHxcclxuXHRcdChuYW1lID09PSBcIjFcIiAmJiB0aGlzLmlzU2hlbGxUZW1wbGF0ZSkgfHxcclxuXHRcdHRoaXMucGFyYW1ldGVyTGlzdC5nZXRQYXJhbWV0ZXJJdGVtcygpLnNvbWUocGFyYW1XaWRnZXQgPT4gcGFyYW1XaWRnZXQubmFtZSA9PT0gbmFtZSk7XHJcblx0dmFyIHZhbHVlID0gdmFsdWVJbnB1dFZhbCAmJiB2YWx1ZUlucHV0VmFsLnRyaW0oKSB8fCB0aGlzLmFkZFBhcmFtZXRlclZhbHVlSW5wdXQuZ2V0VmFsdWUoKS50cmltKCk7XHJcblx0dmFyIGF1dG92YWx1ZSA9IG5hbWUgJiYgdGhpcy5wYXJhbURhdGFbbmFtZV0gJiYgdGhpcy5wYXJhbURhdGFbbmFtZV0uYXV0b3ZhbHVlIHx8IG51bGw7XHJcblx0cmV0dXJuIHtcclxuXHRcdHZhbGlkTmFtZTogISEobmFtZSAmJiAhcGFyYW1BbHJlYWR5SW5jbHVkZWQpLFxyXG5cdFx0dmFsaWRWYWx1ZTogISEodmFsdWUgfHwgYXV0b3ZhbHVlKSxcclxuXHRcdGlzQXV0b3ZhbHVlOiAhISghdmFsdWUgJiYgYXV0b3ZhbHVlKSxcclxuXHRcdGlzQWxyZWFkeUluY2x1ZGVkOiAhIShuYW1lICYmIHBhcmFtQWxyZWFkeUluY2x1ZGVkKSxcclxuXHRcdG5hbWUsXHJcblx0XHR2YWx1ZSxcclxuXHRcdGF1dG92YWx1ZVxyXG5cdH07XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLm9uQWRkUGFyYW1ldGVyTmFtZUNoYW5nZSA9IGZ1bmN0aW9uKCkge1xyXG5cdGxldCB7IHZhbGlkTmFtZSwgdmFsaWRWYWx1ZSwgaXNBdXRvdmFsdWUsIGlzQWxyZWFkeUluY2x1ZGVkLCBuYW1lLCBhdXRvdmFsdWUgfSA9IHRoaXMuZ2V0QWRkUGFyYW1ldGVyc0luZm8oKTtcclxuXHQvLyBTZXQgdmFsdWUgaW5wdXQgcGxhY2Vob2xkZXIgYXMgdGhlIGF1dG92YWx1ZVxyXG5cdHRoaXMuYWRkUGFyYW1ldGVyVmFsdWVJbnB1dC4kaW5wdXQuYXR0ciggXCJwbGFjZWhvbGRlclwiLCAgYXV0b3ZhbHVlIHx8IFwiXCIgKTtcclxuXHQvLyBTZXQgc3VnZ2VzdGlvbnMsIGlmIHRoZSBwYXJhbWV0ZXIgaGFzIGEgbGlzdCBvZiBhbGxvd2VkIHZhbHVlc1xyXG5cdHZhciBhbGxvd2VkVmFsdWVzID0gdGhpcy5wYXJhbURhdGFbbmFtZV0gJiZcclxuXHRcdHRoaXMucGFyYW1EYXRhW25hbWVdLmFsbG93ZWRWYWx1ZXMgJiYgXHJcblx0XHR0aGlzLnBhcmFtRGF0YVtuYW1lXS5hbGxvd2VkVmFsdWVzLm1hcCh2YWwgPT4ge3JldHVybiB7ZGF0YTogdmFsLCBsYWJlbDp2YWx9OyB9KTtcclxuXHR0aGlzLmFkZFBhcmFtZXRlclZhbHVlSW5wdXQuc2V0U3VnZ2VzdGlvbnMoYWxsb3dlZFZhbHVlcyB8fCBbXSk7XHJcblx0Ly8gU2V0IGJ1dHRvbiBkaXNhYmxlZCBzdGF0ZSBiYXNlZCBvbiB2YWxpZGl0eVxyXG5cdHRoaXMuYWRkUGFyYW1ldGVyQnV0dG9uLnNldERpc2FibGVkKCF2YWxpZE5hbWUgfHwgIXZhbGlkVmFsdWUpO1xyXG5cdC8vIFNob3cgbm90aWNlIGlmIGF1dG92YWx1ZSB3aWxsIGJlIHVzZWRcclxuXHR0aGlzLmFkZFBhcmFtZXRlckxheW91dC5zZXROb3RpY2VzKCB2YWxpZE5hbWUgJiYgaXNBdXRvdmFsdWUgPyBbXCJQYXJhbWV0ZXIgdmFsdWUgd2lsbCBiZSBhdXRvZmlsbGVkXCJdIDogW10gKTtcclxuXHQvLyBTaG93IGVycm9yIGlzIHRoZSBiYW5uZXIgYWxyZWFkeSBoYXMgdGhlIHBhcmFtZXRlciBzZXRcclxuXHR0aGlzLmFkZFBhcmFtZXRlckxheW91dC5zZXRFcnJvcnMoIGlzQWxyZWFkeUluY2x1ZGVkID8gW1wiUGFyYW1ldGVyIGlzIGFscmVhZHkgcHJlc2VudFwiXSA6IFtdICk7XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLm9uQWRkUGFyYW1ldGVyTmFtZUVudGVyID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZUlucHV0LmZvY3VzKCk7XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLm9uQWRkUGFyYW1ldGVyVmFsdWVDaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuXHRsZXQgeyB2YWxpZE5hbWUsIHZhbGlkVmFsdWUsIGlzQXV0b3ZhbHVlIH0gPSB0aGlzLmdldEFkZFBhcmFtZXRlcnNJbmZvKCk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJCdXR0b24uc2V0RGlzYWJsZWQoIXZhbGlkTmFtZSB8fCAhdmFsaWRWYWx1ZSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJMYXlvdXQuc2V0Tm90aWNlcyggdmFsaWROYW1lICYmIGlzQXV0b3ZhbHVlID8gW1wiUGFyYW1ldGVyIHZhbHVlIHdpbGwgYmUgYXV0b2ZpbGxlZFwiXSA6IFtdICk7IFxyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS5vbkFkZFBhcmFtZXRlclZhbHVlRW50ZXIgPSBmdW5jdGlvbigpIHtcclxuXHQvLyBNYWtlIHN1cmUgYnV0dG9uIHN0YXRlIGhhcyBiZWVuIHVwZGF0ZWRcclxuXHR0aGlzLm9uQWRkUGFyYW1ldGVyVmFsdWVDaGFuZ2UoKTtcclxuXHQvLyBEbyBub3RoaW5nIGlmIGJ1dHRvbiBpcyBkaXNhYmxlZCAoaS5lLiBuYW1lIGFuZC9vciB2YWx1ZSBhcmUgaW52YWxpZClcclxuXHRpZiAoIHRoaXMuYWRkUGFyYW1ldGVyQnV0dG9uLmlzRGlzYWJsZWQoKSApIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0Ly8gQWRkIHBhcmFtZXRlclxyXG5cdHRoaXMub25QYXJhbWV0ZXJBZGQoKTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUub25QYXJhbWV0ZXJBZGQgPSBmdW5jdGlvbigpIHtcclxuXHRsZXQgeyB2YWxpZE5hbWUsIHZhbGlkVmFsdWUsIG5hbWUsIHZhbHVlLCBhdXRvdmFsdWUgfSAgPSB0aGlzLmdldEFkZFBhcmFtZXRlcnNJbmZvKCk7XHJcblx0aWYgKCF2YWxpZE5hbWUgfHwgIXZhbGlkVmFsdWUpIHtcclxuXHRcdC8vIEVycm9yIHNob3VsZCBhbHJlYWR5IGJlIHNob3duIHZpYSBvbkFkZFBhcmFtZXRlci4uLkNoYW5nZSBtZXRob2RzXHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdHZhciBuZXdQYXJhbWV0ZXIgPSBuZXcgUGFyYW1ldGVyV2lkZ2V0KFxyXG5cdFx0e1xyXG5cdFx0XHRcIm5hbWVcIjogbmFtZSxcclxuXHRcdFx0XCJ2YWx1ZVwiOiB2YWx1ZSB8fCBhdXRvdmFsdWVcclxuXHRcdH0sXHJcblx0XHR0aGlzLnBhcmFtRGF0YVtuYW1lXSxcclxuXHRcdHskb3ZlcmxheTogdGhpcy4kb3ZlcmxheX1cclxuXHQpO1xyXG5cdHRoaXMucGFyYW1ldGVyTGlzdC5hZGRJdGVtcyhbbmV3UGFyYW1ldGVyXSk7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJOYW1lSW5wdXQuc2V0VmFsdWUoXCJcIik7XHJcblx0dGhpcy5hZGRQYXJhbWV0ZXJWYWx1ZUlucHV0LnNldFZhbHVlKFwiXCIpO1xyXG5cdHRoaXMuYWRkUGFyYW1ldGVyTmFtZUlucHV0LiRpbnB1dC5mb2N1cygpO1xyXG59O1xyXG5cclxuQmFubmVyV2lkZ2V0LnByb3RvdHlwZS51cGRhdGVBZGRQYXJhbWV0ZXJOYW1lU3VnZ2VzdGlvbnMgPSBmdW5jdGlvbigpIHtcclxuXHRsZXQgcGFyYW1zSW5Vc2UgPSB7fTtcclxuXHR0aGlzLnBhcmFtZXRlckxpc3QuZ2V0UGFyYW1ldGVySXRlbXMoKS5mb3JFYWNoKFxyXG5cdFx0cGFyYW1XaWRnZXQgPT4gcGFyYW1zSW5Vc2VbcGFyYW1XaWRnZXQubmFtZV0gPSB0cnVlXHJcblx0KTtcclxuXHR0aGlzLmFkZFBhcmFtZXRlck5hbWVJbnB1dC5zZXRTdWdnZXN0aW9ucyhcclxuXHRcdHRoaXMucGFyYW1ldGVyU3VnZ2VzdGlvbnMuZmlsdGVyKFxyXG5cdFx0XHRzdWdnZXN0aW9uID0+ICFwYXJhbXNJblVzZVtzdWdnZXN0aW9uLmRhdGFdXHJcblx0XHQpXHJcblx0KTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUub25SZW1vdmVCdXR0b25DbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuZW1pdChcInJlbW92ZVwiKTtcclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUub25DbGVhckJ1dHRvbkNsaWNrID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5wYXJhbWV0ZXJMaXN0LmNsZWFySXRlbXMoXHJcblx0XHR0aGlzLnBhcmFtZXRlckxpc3QuZ2V0UGFyYW1ldGVySXRlbXMoKVxyXG5cdCk7XHJcblx0aWYgKCB0aGlzLmhhc0NsYXNzUmF0aW5ncyApIHtcclxuXHRcdHRoaXMuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbSgpO1xyXG5cdH1cclxuXHRpZiAoIHRoaXMuaGFzSW1wb3J0YW5jZVJhdGluZ3MgKSB7XHJcblx0XHR0aGlzLmltcG9ydGFuY2VEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbSgpO1xyXG5cdH1cclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUuYnlwYXNzUmVkaXJlY3QgPSBmdW5jdGlvbigpIHtcclxuXHRpZiAoIXRoaXMucmVkaXJlY3RUYXJnZXRNYWluVGV4dCkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHQvLyBTdG9yZSB0aGUgYnlwYXNzZWQgbmFtZVxyXG5cdHRoaXMuYnlwYXNzZWROYW1lID0gdGhpcy5uYW1lO1xyXG5cdC8vIFVwZGF0ZSB0aXRsZSBsYWJlbFxyXG5cdHRoaXMubWFpbkxhYmVsUG9wdXBCdXR0b24uc2V0TGFiZWwoYHt7JHt0aGlzLnJlZGlyZWN0VGFyZ2V0TWFpblRleHR9fX0ke3RoaXMuaW5hY3RpdmVQcm9qZWN0ID8gXCIgKGluYWN0aXZlKVwiIDogXCJcIn1gKTtcclxuXHQvLyBVcGRhdGUgcHJvcGVydGllc1xyXG5cdHRoaXMubmFtZSA9IHRoaXMucmVkaXJlY3RUYXJnZXRNYWluVGV4dDtcclxuXHR0aGlzLm1haW5UZXh0ID0gdGhpcy5yZWRpcmVjdFRhcmdldE1haW5UZXh0O1xyXG5cdHRoaXMucmVkaXJlY3RUYXJnZXRNYWluVGV4dCA9IG51bGw7XHJcblx0dGhpcy5zZXRDaGFuZ2VkKCk7XHJcbn07XHJcblxyXG5CYW5uZXJXaWRnZXQucHJvdG90eXBlLm1ha2VXaWtpdGV4dCA9IGZ1bmN0aW9uKCkge1xyXG5cdGlmICghdGhpcy5jaGFuZ2VkICYmIHRoaXMud2lraXRleHQpIHtcclxuXHRcdHJldHVybiB0aGlzLndpa2l0ZXh0O1xyXG5cdH1cclxuXHR2YXIgcGlwZSA9IHRoaXMucGlwZVN0eWxlO1xyXG5cdHZhciBlcXVhbHMgPSB0aGlzLmVxdWFsc1N0eWxlO1xyXG5cdHZhciBjbGFzc0l0ZW0gPSAodGhpcy5oYXNDbGFzc1JhdGluZ3MgfHwgdGhpcy5pc1NoZWxsVGVtcGxhdGUpICYmIHRoaXMuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuZmluZFNlbGVjdGVkSXRlbSgpO1xyXG5cdHZhciBjbGFzc1ZhbCA9IGNsYXNzSXRlbSAmJiBjbGFzc0l0ZW0uZ2V0RGF0YSgpO1xyXG5cdHZhciBpbXBvcnRhbmNlSXRlbSA9IHRoaXMuaGFzSW1wb3J0YW5jZVJhdGluZ3MgJiYgdGhpcy5pbXBvcnRhbmNlRHJvcGRvd24uZ2V0TWVudSgpLmZpbmRTZWxlY3RlZEl0ZW0oKTtcclxuXHR2YXIgaW1wb3J0YW5jZVZhbCA9IGltcG9ydGFuY2VJdGVtICYmIGltcG9ydGFuY2VJdGVtLmdldERhdGEoKTtcclxuXHJcblx0cmV0dXJuIChcInt7XCIgK1xyXG5cdFx0dGhpcy5uYW1lICtcclxuXHRcdCggKHRoaXMuaGFzQ2xhc3NSYXRpbmdzIHx8IHRoaXMuaXNTaGVsbFRlbXBsYXRlKSAmJiBjbGFzc1ZhbCE9bnVsbCA/IGAke3BpcGV9Y2xhc3Mke2VxdWFsc30ke2NsYXNzVmFsfHxcIlwifWAgOiBcIlwiICkgK1xyXG5cdFx0KCB0aGlzLmhhc0ltcG9ydGFuY2VSYXRpbmdzICYmIGltcG9ydGFuY2VWYWwhPW51bGwgPyBgJHtwaXBlfWltcG9ydGFuY2Uke2VxdWFsc30ke2ltcG9ydGFuY2VWYWx8fFwiXCJ9YCA6IFwiXCIgKSArXHJcblx0XHR0aGlzLnBhcmFtZXRlckxpc3QuZ2V0UGFyYW1ldGVySXRlbXMoKVxyXG5cdFx0XHQubWFwKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIubWFrZVdpa2l0ZXh0KHBpcGUsIGVxdWFscykpXHJcblx0XHRcdC5qb2luKFwiXCIpICtcclxuXHRcdHRoaXMuZW5kQnJhY2VzU3R5bGUpXHJcblx0XHQucmVwbGFjZSgvXFxuK319JC8sIFwiXFxufX1cIik7IC8vIGF2b2lkIGVtcHR5IGxpbmUgYXQgZW5kIGxpa2UgW1tTcGVjaWFsOkRpZmYvOTI1OTgyMTQyXV1cclxufTtcclxuXHJcbkJhbm5lcldpZGdldC5wcm90b3R5cGUuc2V0UHJlZmVyZW5jZXMgPSBmdW5jdGlvbihwcmVmcykge1xyXG5cdHRoaXMucHJlZmVyZW5jZXMgPSBwcmVmcztcclxuXHRpZiAodGhpcy5wcmVmZXJlbmNlcy5ieXBhc3NSZWRpcmVjdHMpIHtcclxuXHRcdHRoaXMuYnlwYXNzUmVkaXJlY3QoKTtcclxuXHR9XHJcblx0dGhpcy5wYXJhbWV0ZXJMaXN0LnNldFByZWZlcmVuY2VzKHByZWZzKTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IEJhbm5lcldpZGdldDtcclxuLy8gPC9ub3dpa2k+IiwiLy8gPG5vd2lraT5cclxuXHJcbmZ1bmN0aW9uIERyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0KCBjb25maWcgKSB7XHJcblx0Ly8gQ29uZmlndXJhdGlvbiBpbml0aWFsaXphdGlvblxyXG5cdGNvbmZpZyA9ICQuZXh0ZW5kKHtcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjI0JSc+XCIpXHJcblx0fSwgY29uZmlnIHx8IHt9ICk7XHJcblxyXG5cdC8vIENhbGwgcGFyZW50IGNvbnN0cnVjdG9yXHJcblx0RHJvcGRvd25QYXJhbWV0ZXJXaWRnZXQuc3VwZXIuY2FsbCggdGhpcywgY29uZmlnICk7XHJcblxyXG5cdHRoaXMuJG92ZXJsYXkgPSBjb25maWcuJG92ZXJsYXk7XHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLWRyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0XCIpO1xyXG4gICAgXHJcblx0Ly8gQXV0b2ZpbGxlZCBpY29uXHJcblx0dGhpcy5hdXRvZmlsbGVkID0gISFjb25maWcuYXV0b2ZpbGxlZDtcclxuXHR0aGlzLmF1dG9maWxsZWRJY29uID0gbmV3IE9PLnVpLkljb25XaWRnZXQoIHtcclxuXHRcdGljb246IFwicm9ib3RcIixcclxuXHRcdHRpdGxlOiBcIkF1dG9maWxsZWQgYnkgUmF0ZXJcIixcclxuXHRcdGZsYWdzOiBcInByb2dyZXNzaXZlXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxzcGFuIHN0eWxlPSdtYXJnaW46IDAgLTVweCAwIDVweDttaW4td2lkdGg6IDE2cHg7d2lkdGg6IDE2cHg7bGVmdDp1bnNldDsnPlwiKVxyXG5cdH0gKS50b2dnbGUodGhpcy5hdXRvZmlsbGVkKTtcclxuXHR0aGlzLiRlbGVtZW50LmZpbmQoXCIub28tdWktaW5kaWNhdG9yRWxlbWVudC1pbmRpY2F0b3JcIikuYmVmb3JlKFxyXG5cdFx0dGhpcy5hdXRvZmlsbGVkSWNvbi4kZWxlbWVudFxyXG5cdCk7XHJcblxyXG5cdC8vIEV2ZW50c1xyXG5cdHRoaXMubWVudS5jb25uZWN0KHRoaXMsIHtcclxuXHRcdFwiY2hvb3NlXCI6IFwib25Ecm9wZG93bk1lbnVDaG9vc2VcIixcclxuXHRcdFwic2VsZWN0XCI6IFwib25Ecm9wZG93bk1lbnVTZWxlY3RcIlxyXG5cdH0pO1xyXG59XHJcbk9PLmluaGVyaXRDbGFzcyggRHJvcGRvd25QYXJhbWV0ZXJXaWRnZXQsIE9PLnVpLkRyb3Bkb3duV2lkZ2V0ICk7XHJcblxyXG5Ecm9wZG93blBhcmFtZXRlcldpZGdldC5wcm90b3R5cGUuc2V0QXV0b2ZpbGxlZCA9IGZ1bmN0aW9uKHNldEF1dG9maWxsKSB7XHJcblx0dGhpcy5hdXRvZmlsbGVkSWNvbi50b2dnbGUoISFzZXRBdXRvZmlsbCk7XHJcblx0dGhpcy4kZWxlbWVudC5maW5kKFwiLm9vLXVpLWRyb3Bkb3duV2lkZ2V0LWhhbmRsZVwiKS5jc3Moe1xyXG5cdFx0XCJib3JkZXJcIjogc2V0QXV0b2ZpbGwgPyBcIjFweCBkYXNoZWQgIzM2Y1wiIDogXCJcIlxyXG5cdH0pO1xyXG5cdHRoaXMuYXV0b2ZpbGxlZCA9ICEhc2V0QXV0b2ZpbGw7XHJcbn07XHJcblxyXG5Ecm9wZG93blBhcmFtZXRlcldpZGdldC5wcm90b3R5cGUub25Ecm9wZG93bk1lbnVDaG9vc2UgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnNldEF1dG9maWxsZWQoZmFsc2UpO1xyXG5cdHRoaXMuZW1pdChcImNoYW5nZVwiKTtcclxufTtcclxuXHJcbkRyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5vbkRyb3Bkb3duTWVudVNlbGVjdCA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuZW1pdChcImNoYW5nZVwiKTtcclxufTtcclxuXHJcbkRyb3Bkb3duUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdGNvbnN0IHNlbGVjdGVkSXRlbSA9IHRoaXMubWVudS5maW5kU2VsZWN0ZWRJdGVtKCk7XHJcblx0cmV0dXJuIHNlbGVjdGVkSXRlbSAmJiBzZWxlY3RlZEl0ZW0uZ2V0RGF0YSgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgRHJvcGRvd25QYXJhbWV0ZXJXaWRnZXQ7XHJcbi8vIDwvbm93aWtpPiIsIi8vIDxub3dpa2k+XHJcblxyXG4vKipcclxuICogQSBIb3Jpem9udGFsTGF5b3V0IHRoYXQgaXMgYWxzbyBhIHdpZGdldCwgYW5kIGNhbiB0aHVzIGJlIHBsYWNlZCB3aXRoaW5cclxuICogZmllbGQgbGF5b3V0cy5cclxuICogXHJcbiAqIEBjbGFzc1xyXG4gKiBAcGFyYW0geyp9IGNvbmZpZyBjb25maWd1cmF0aW9uIGZvciBPTy51aS5Ib3Jpem9udGFsTGF5b3V0XHJcbiAqL1xyXG5mdW5jdGlvbiBIb3Jpem9udGFsTGF5b3V0V2lkZ2V0KCBjb25maWcgKSB7XHJcblx0Ly8gQ29uZmlndXJhdGlvbiBpbml0aWFsaXphdGlvblxyXG5cdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdEhvcml6b250YWxMYXlvdXRXaWRnZXQuc3VwZXIuY2FsbCggdGhpcywge30gKTtcclxuICAgIFxyXG5cdHRoaXMubGF5b3V0ID0gbmV3IE9PLnVpLkhvcml6b250YWxMYXlvdXQoIHtcclxuXHRcdC4uLmNvbmZpZyxcclxuXHRcdCRlbGVtZW50OiB0aGlzLiRlbGVtZW50XHJcblx0fSk7XHJcblxyXG59XHJcbk9PLmluaGVyaXRDbGFzcyggSG9yaXpvbnRhbExheW91dFdpZGdldCwgT08udWkuV2lkZ2V0ICk7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBIb3Jpem9udGFsTGF5b3V0V2lkZ2V0O1xyXG4vLyA8L25vd2lraT4iLCIvLyA8bm93aWtpPlxyXG5cclxuLyoqXHJcbiAqIEBjZmcge09PLnVpLkVsZW1lbnRbXX0gaXRlbXMgSXRlbXMgdG8gYmUgYWRkZWRcclxuICogQGNmZyB7TnVtYmVyfSBkaXNwbGF5TGltaXQgVGhlIG1vc3QgdG8gc2hvdyBhdCBvbmNlLiBJZiB0aGUgbnVtYmVyIG9mIGl0ZW1zXHJcbiAqICBpcyBtb3JlIHRoYW4gdGhpcywgdGhlbiBvbmx5IHRoZSBmaXJzdCAoZGlzcGxheUxpbWl0IC0gMSkgaXRlbXMgYXJlIHNob3duLlxyXG4gKi9cclxudmFyIFBhcmFtZXRlckxpc3RXaWRnZXQgPSBmdW5jdGlvbiBQYXJhbWV0ZXJMaXN0V2lkZ2V0KCBjb25maWcgKSB7XHJcblx0Y29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG5cclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdFBhcmFtZXRlckxpc3RXaWRnZXQucGFyZW50LmNhbGwoIHRoaXMsIGNvbmZpZyApO1xyXG5cdE9PLnVpLm1peGluLkdyb3VwRWxlbWVudC5jYWxsKCB0aGlzLCB7XHJcblx0XHQkZ3JvdXA6IHRoaXMuJGVsZW1lbnRcclxuXHR9ICk7XHJcblx0dGhpcy5hZGRJdGVtcyggY29uZmlnLml0ZW1zICk7XHJcblxyXG5cdHRoaXMuJGVsZW1lbnQuYWRkQ2xhc3MoXCJyYXRlci1wYXJhbWV0ZXJMaXN0V2lkZ2V0XCIpO1xyXG4gICAgXHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IGNvbmZpZy5wcmVmZXJlbmNlcztcclxuICAgXHJcblx0Ly8gSGlkZSBzb21lIHBhcmFtZXRlcnMgKGluaXRpYWxseSksIGlmIG1vcmUgdGhhbiBzZXQgZGlzcGxheSBsaW1pdCAtLSB3aGljaCBpcyB0aGUgXHJcblx0Ly8gb25lIG1vcmUgdGhhbiBjb2xsYXBzZVBhcmFtc0xvd2VyTGltaXQsIHRvIHByZXZlbnQgb25seSBvbmUgcGFyYW0gYmVpbmcgaGlkZGVuXHJcblx0Ly8gKG1vc3RseTogbWF5IG9jY2FzaW9uYWxseSBvY2N1ciBpZiBwYXJhbXMgd2VyZSBhdXRvLWZpbGxlZCkuXHJcblx0bGV0IGRpc3BsYXlMaW1pdCA9IHRoaXMucHJlZmVyZW5jZXMuY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0ICsgMTtcclxuXHRpZiAoZGlzcGxheUxpbWl0ICYmIHRoaXMuaXRlbXMubGVuZ3RoID4gZGlzcGxheUxpbWl0ICkge1xyXG5cdFx0dmFyIGhpZGVGcm9tTnVtYmVyID0gZGlzcGxheUxpbWl0IC0gMTsgLy8gT25lLWluZGV4ZWRcclxuXHRcdHZhciBoaWRlRnJvbUluZGV4ID0gaGlkZUZyb21OdW1iZXIgLSAxOyAvLyBaZXJvLWluZGV4ZWRcclxuXHRcdHZhciBoaWRkZW5Db3VudCA9IDA7XHJcblx0XHRmb3IgKGxldCBpID0gaGlkZUZyb21JbmRleDsgaSA8IHRoaXMuaXRlbXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0aWYgKCF0aGlzLml0ZW1zW2ldLmF1dG9maWxsZWQpIHsgLy8gRG9uJ3QgaGlkZSBhdXRvLWZpbGxlZCBwYXJhbXNcclxuXHRcdFx0XHR0aGlzLml0ZW1zW2ldLnRvZ2dsZShmYWxzZSk7XHJcblx0XHRcdFx0aGlkZGVuQ291bnQrKztcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0aWYgKGhpZGRlbkNvdW50PjApIHtcclxuXHRcdFx0Ly8gQWRkIGJ1dHRvbiB0byBzaG93IHRoZSBoaWRkZW4gcGFyYW1zXHJcblx0XHRcdHRoaXMuc2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uID0gbmV3IE9PLnVpLkJ1dHRvbldpZGdldCh7XHJcblx0XHRcdFx0bGFiZWw6IFwiU2hvdyBcIiArIGhpZGRlbkNvdW50ICsgXCIgbW9yZSBcIiArIChoaWRkZW5Db3VudD09PTEgPyBcInBhcmFtZXRlclwiIDogXCJwYXJhbWV0ZXJzXCIpLFxyXG5cdFx0XHRcdGZyYW1lZDogZmFsc2UsXHJcblx0XHRcdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nbWFyZ2luLWJvdHRvbTowJz5cIilcclxuXHRcdFx0fSk7XHJcblx0XHRcdHRoaXMuYWRkSXRlbXMoW3RoaXMuc2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uXSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBBZGQgdGhlIGJ1dHRvbiB0aGF0IGFsbG93cyB1c2VyIHRvIGFkZCBtb3JlIHBhcmFtZXRlcnNcclxuXHR0aGlzLmFkZFBhcmFtZXRlcnNCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KHtcclxuXHRcdGxhYmVsOiBcIkFkZCBwYXJhbWV0ZXJcIixcclxuXHRcdGljb246IFwiYWRkXCIsXHJcblx0XHRmcmFtZWQ6IGZhbHNlLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nbWFyZ2luLWJvdHRvbTowJz5cIilcclxuXHR9KTtcclxuXHR0aGlzLmFkZEl0ZW1zKFt0aGlzLmFkZFBhcmFtZXRlcnNCdXR0b25dKTtcclxuXHJcblx0LyogLS0tIEV2ZW50cyAtLS0gKi9cclxuXHJcblx0Ly8gSGFuZGxlIGRlbGV0ZSBldmVudHMgZnJvbSBQYXJhbWV0ZXJXaWRnZXRzXHJcblx0dGhpcy5hZ2dyZWdhdGUoIHsgZGVsZXRlOiBcInBhcmFtZXRlckRlbGV0ZVwiXHR9ICk7XHJcblx0dGhpcy5jb25uZWN0KCB0aGlzLCB7IHBhcmFtZXRlckRlbGV0ZTogXCJvblBhcmFtZXRlckRlbGV0ZVwiIH0gKTtcclxuICAgIFxyXG5cdC8vIEhhbmRsZSBjaGFuZ2UgZXZlbnRzIGZyb20gUGFyYW1ldGVyV2lkZ2V0c1xyXG5cdHRoaXMuYWdncmVnYXRlKCB7IGNoYW5nZTogXCJwYXJhbWV0ZXJDaGFuZ2VcIlx0fSApO1xyXG5cdHRoaXMuY29ubmVjdCggdGhpcywgeyBwYXJhbWV0ZXJDaGFuZ2U6IFwib25QYXJhbWV0ZXJDaGFuZ2VcIiB9ICk7XHJcblxyXG5cdC8vIEhhbmRsZSB1cGRhdGVkU2l6ZSBldmVudHMgZnJvbSBQYXJhbWV0ZXJXaWRnZXRzXHJcblx0dGhpcy5hZ2dyZWdhdGUoIHtcInVwZGF0ZWRTaXplXCI6IFwicGFyYW1ldGVyVXBkYXRlZFNpemVcIn0gKTtcclxuXHR0aGlzLmNvbm5lY3QoIHRoaXMsIHtcInBhcmFtZXRlclVwZGF0ZWRTaXplXCI6IFwib25VcGRhdGVkU2l6ZVwifSApO1xyXG4gICAgXHJcblx0Ly8gSGFuZGxlIGJ1dHRvbiBjbGlja3NcclxuXHRpZiAodGhpcy5zaG93TW9yZVBhcmFtZXRlcnNCdXR0b24gKSB7XHJcblx0XHR0aGlzLnNob3dNb3JlUGFyYW1ldGVyc0J1dHRvbi5jb25uZWN0KCB0aGlzLCB7IFwiY2xpY2tcIjogXCJvblNob3dNb3JlUGFyYW1ldGVyc0J1dHRvbkNsaWNrXCIgfSApO1xyXG5cdH1cclxuXHR0aGlzLmFkZFBhcmFtZXRlcnNCdXR0b24uY29ubmVjdCggdGhpcywgeyBcImNsaWNrXCI6IFwib25BZGRQYXJhbWV0ZXJzQnV0dG9uQ2xpY2tcIiB9ICk7XHJcbn07XHJcblxyXG5PTy5pbmhlcml0Q2xhc3MoIFBhcmFtZXRlckxpc3RXaWRnZXQsIE9PLnVpLldpZGdldCApO1xyXG5PTy5taXhpbkNsYXNzKCBQYXJhbWV0ZXJMaXN0V2lkZ2V0LCBPTy51aS5taXhpbi5Hcm91cEVsZW1lbnQgKTtcclxuLypcclxubWV0aG9kcyBmcm9tIG1peGluOlxyXG4gLSBhZGRJdGVtcyggaXRlbXMsIFtpbmRleF0gKSA6IE9PLnVpLkVsZW1lbnQgIChDSEFJTkFCTEUpXHJcbiAtIGNsZWFySXRlbXMoICkgOiBPTy51aS5FbGVtZW50ICAoQ0hBSU5BQkxFKVxyXG4gLSBmaW5kSXRlbUZyb21EYXRhKCBkYXRhICkgOiBPTy51aS5FbGVtZW50fG51bGxcclxuIC0gZmluZEl0ZW1zRnJvbURhdGEoIGRhdGEgKSA6IE9PLnVpLkVsZW1lbnRbXVxyXG4gLSByZW1vdmVJdGVtcyggaXRlbXMgKSA6IE9PLnVpLkVsZW1lbnQgIChDSEFJTkFCTEUpXHJcbiovXHJcblxyXG5QYXJhbWV0ZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5vblVwZGF0ZWRTaXplID0gZnVuY3Rpb24oKSB7XHJcblx0Ly8gRW1pdCBhbiBcInVwZGF0ZWRTaXplXCIgZXZlbnQgc28gdGhlIHBhcmVudCB3aW5kb3cgY2FuIHVwZGF0ZSBzaXplLCBpZiBuZWVkZWRcclxuXHR0aGlzLmVtaXQoXCJ1cGRhdGVkU2l6ZVwiKTtcclxufTtcclxuXHJcblBhcmFtZXRlckxpc3RXaWRnZXQucHJvdG90eXBlLmFkZEl0ZW1zID0gZnVuY3Rpb24gKCBpdGVtcywgaW5kZXggKSB7XHJcblx0aWYgKCBpdGVtcy5sZW5ndGggPT09IDAgKSB7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblxyXG5cdC8vIENhbGwgbWl4aW4gbWV0aG9kIHRvIGRvIHRoZSBhZGRpbmdcclxuXHRPTy51aS5taXhpbi5Hcm91cEVsZW1lbnQucHJvdG90eXBlLmFkZEl0ZW1zLmNhbGwoIHRoaXMsIGl0ZW1zLCBpbmRleCApO1xyXG5cclxuXHQvLyBlbWl0IHVwZGF0ZWRTaXplIGV2ZW50IFxyXG5cdHRoaXMub25VcGRhdGVkU2l6ZSgpO1xyXG5cclxuXHRyZXR1cm4gdGhpcztcclxufTtcdFxyXG5cclxuUGFyYW1ldGVyTGlzdFdpZGdldC5wcm90b3R5cGUub25QYXJhbWV0ZXJEZWxldGUgPSBmdW5jdGlvbihwYXJhbWV0ZXIpIHtcclxuXHR0aGlzLnJlbW92ZUl0ZW1zKFtwYXJhbWV0ZXJdKTtcclxuXHR0aGlzLmVtaXQoXCJjaGFuZ2VcIik7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5vblBhcmFtZXRlckNoYW5nZSA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuZW1pdChcImNoYW5nZVwiKTtcclxufTtcclxuXHJcblBhcmFtZXRlckxpc3RXaWRnZXQucHJvdG90eXBlLmdldFBhcmFtZXRlckl0ZW1zID0gZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHRoaXMuaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbS5jb25zdHJ1Y3Rvci5uYW1lID09PSBcIlBhcmFtZXRlcldpZGdldFwiKTtcclxufTtcclxuXHJcblBhcmFtZXRlckxpc3RXaWRnZXQucHJvdG90eXBlLm9uU2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uQ2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnJlbW92ZUl0ZW1zKFt0aGlzLnNob3dNb3JlUGFyYW1ldGVyc0J1dHRvbl0pO1xyXG5cdHRoaXMuaXRlbXMuZm9yRWFjaChwYXJhbWV0ZXJXaWRnZXQgPT4gcGFyYW1ldGVyV2lkZ2V0LnRvZ2dsZSh0cnVlKSk7XHJcblx0dGhpcy5vblVwZGF0ZWRTaXplKCk7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5vbkFkZFBhcmFtZXRlcnNCdXR0b25DbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMucmVtb3ZlSXRlbXMoW3RoaXMuYWRkUGFyYW1ldGVyc0J1dHRvbl0pO1xyXG5cdHRoaXMuZW1pdChcImFkZFBhcmFtZXRlcnNCdXR0b25DbGlja1wiKTtcclxufTtcclxuXHJcblBhcmFtZXRlckxpc3RXaWRnZXQucHJvdG90eXBlLm1ha2VXaWtpdGV4dCA9IGZ1bmN0aW9uKHBpcGVTdHlsZSwgZXF1YWxzU3R5bGUpIHtcclxuXHRyZXR1cm4gdGhpcy5nZXRQYXJhbWV0ZXJJdGVtcygpXHJcblx0XHQubWFwKHBhcmFtZXRlciA9PiBwYXJhbWV0ZXIubWFrZVdpa2l0ZXh0KHBpcGVTdHlsZSwgZXF1YWxzU3R5bGUpKVxyXG5cdFx0LmpvaW4oXCJcIik7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJMaXN0V2lkZ2V0LnByb3RvdHlwZS5zZXRQcmVmZXJlbmNlcyA9IGZ1bmN0aW9uKHByZWZzKSB7XHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IHByZWZzO1xyXG5cdHZhciBwYXJhbXMgPSB0aGlzLmdldFBhcmFtZXRlckl0ZW1zKCk7XHJcblx0Ly8gVW5oaWRlIHNvbWUgcGFyYW1ldGVycyBvZiB0aGUgY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0IGhhcyBpbmNyZWFzZWQuXHJcblx0Ly8gKE5vdCBoaWRpbmcgYW55IGlmIGl0IGRlY3JlYXNlZCwgc2luY2UgaXQncyBhICpsb3dlciogbGltaXQgb2Ygd2hhdCBuZWVkcyB0byBiZSBzaG93bi4pXHJcblx0aWYgKCBwYXJhbXMubGVuZ3RoIDw9IHRoaXMucHJlZmVyZW5jZXMuY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0ICkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHR2YXIgaGlkZGVuUGFyYW1zID0gcGFyYW1zLmZpbHRlcihwYXJhbSA9PiAhcGFyYW0uaXNWaXNpYmxlKCkpO1xyXG5cdHZhciB2aXNpYmxlUGFyYW1zQ291bnQgPSBwYXJhbXMubGVuZ3RoIC0gaGlkZGVuUGFyYW1zLmxlbmd0aDtcclxuXHRpZiAoXHJcblx0XHRoaWRkZW5QYXJhbXMgPT09IDAgfHxcclxuICAgICAgICB2aXNpYmxlUGFyYW1zQ291bnQgPj0gdGhpcy5wcmVmZXJlbmNlcy5jb2xsYXBzZVBhcmFtc0xvd2VyTGltaXRcclxuXHQpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0dmFyIG51bVRvVW5oaWRlID0gTWF0aC5taW4oXHJcblx0XHR0aGlzLnByZWZlcmVuY2VzLmNvbGxhcHNlUGFyYW1zTG93ZXJMaW1pdCAtIHZpc2libGVQYXJhbXNDb3VudCxcclxuXHRcdGhpZGRlblBhcmFtcy5sZW5ndGhcclxuXHQpO1xyXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgbnVtVG9VbmhpZGU7IGkrKykge1xyXG5cdFx0aGlkZGVuUGFyYW1zW2ldLnRvZ2dsZSh0cnVlKTtcclxuXHR9XHJcblx0dmFyIHN0aWxsSGlkZGVuQ291bnQgPSBoaWRkZW5QYXJhbXMubGVuZ3RoIC0gbnVtVG9VbmhpZGU7XHJcblx0aWYgKHN0aWxsSGlkZGVuQ291bnQgPT09IDApIHtcclxuXHRcdHRoaXMucmVtb3ZlSXRlbXMoW3RoaXMuc2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uXSk7XHJcblx0fSBlbHNlIHtcclxuXHRcdHRoaXMuc2hvd01vcmVQYXJhbWV0ZXJzQnV0dG9uLnNldExhYmVsKFxyXG5cdFx0XHRcIlNob3cgXCIgKyBzdGlsbEhpZGRlbkNvdW50ICsgXCIgbW9yZSBcIiArIChzdGlsbEhpZGRlbkNvdW50PT09MSA/IFwicGFyYW10ZXJcIiA6IFwicGFyYW10ZXJzXCIpXHJcblx0XHQpO1xyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFBhcmFtZXRlckxpc3RXaWRnZXQ7XHJcbi8vIDwvbm93aWtpPiIsImltcG9ydCB7IG5vcm1hbGlzZVllc05vLCBmaWx0ZXJBbmRNYXAgfSBmcm9tIFwiLi4vLi4vdXRpbFwiO1xyXG5pbXBvcnQgSG9yaXpvbnRhbExheW91dFdpZGdldCBmcm9tIFwiLi9Ib3Jpem9udGFsTGF5b3V0V2lkZ2V0XCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG5mdW5jdGlvbiBQYXJhbWV0ZXJXaWRnZXQoIHBhcmFtZXRlciwgcGFyYW1EYXRhLCBjb25maWcgKSB7XHJcblx0Ly8gQ29uZmlndXJhdGlvbiBpbml0aWFsaXphdGlvblxyXG5cdGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdFBhcmFtZXRlcldpZGdldC5zdXBlci5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxuXHR0aGlzLiRvdmVybGF5ID0gY29uZmlnLiRvdmVybGF5O1xyXG4gICAgXHJcblx0dGhpcy5uYW1lID0gcGFyYW1ldGVyLm5hbWU7XHJcblx0dGhpcy52YWx1ZSA9IHBhcmFtZXRlci52YWx1ZTtcclxuXHR0aGlzLmF1dG9maWxsZWQgPSBwYXJhbWV0ZXIuYXV0b2ZpbGxlZDtcclxuXHR0aGlzLmlzSW52YWxpZCA9IHBhcmFtZXRlci52YWx1ZSA9PSBudWxsO1xyXG5cdHRoaXMucGFyYW1EYXRhID0gcGFyYW1EYXRhIHx8IHt9O1xyXG5cdHRoaXMuYWxsb3dlZFZhbHVlcyA9IHRoaXMucGFyYW1EYXRhLmFsbG93ZWRWYWx1ZXMgfHwgW107XHJcblx0dGhpcy5pc1JlcXVpcmVkID0gdGhpcy5wYXJhbURhdGEucmVxdWlyZWQ7XHJcblx0dGhpcy5pc1N1Z2dlc3RlZCA9IHRoaXMucGFyYW1EYXRhLnN1Z2dlc3RlZDtcclxuXHJcblx0Ly8gTWFrZSBhIGNoZWNrYm94IGlmIG9ubHkgMSBvciAyIGFsbG93ZWQgdmFsdWVzXHJcblx0c3dpdGNoKHRoaXMuYWxsb3dlZFZhbHVlcy5sZW5ndGgpIHtcdC8qIGVzbGludC1kaXNhYmxlIG5vLWZhbGx0aHJvdWdoICovXHJcblx0Y2FzZSAxOlxyXG5cdFx0dGhpcy5hbGxvd2VkVmFsdWVzWzFdID0gbnVsbDtcclxuXHRcdC8qIGZhbGwtdGhyb3VnaCAqL1xyXG5cdGNhc2UgMjpcclxuXHRcdHZhciBpc0ZpcnN0QWxsb3dlZFZhbCA9IChcclxuXHRcdFx0dGhpcy5hbGxvd2VkVmFsdWVzLmluZGV4T2YoIHBhcmFtZXRlci52YWx1ZSApID09PSAwIHx8XHJcblx0XHRcdFx0dGhpcy5hbGxvd2VkVmFsdWVzLm1hcChub3JtYWxpc2VZZXNObykuaW5kZXhPZiggbm9ybWFsaXNlWWVzTm8ocGFyYW1ldGVyLnZhbHVlKSApID09PSAwXHJcblx0XHQpO1xyXG5cdFx0dmFyIGlzU2Vjb25kQWxsb3dlZFZhbCA9IChcclxuXHRcdFx0dGhpcy5hbGxvd2VkVmFsdWVzLmluZGV4T2YoIHBhcmFtZXRlci52YWx1ZSB8fCBudWxsICkgPT09IDEgfHxcclxuXHRcdFx0XHR0aGlzLmFsbG93ZWRWYWx1ZXMubWFwKG5vcm1hbGlzZVllc05vKS5pbmRleE9mKCBwYXJhbWV0ZXIudmFsdWUgPyBub3JtYWxpc2VZZXNObyhwYXJhbWV0ZXIudmFsdWUpIDogbnVsbCkgPT09IDFcclxuXHRcdCk7XHJcblx0XHR2YXIgaXNJbmRldGVybWluYXRlID0gIWlzRmlyc3RBbGxvd2VkVmFsICYmICFpc1NlY29uZEFsbG93ZWRWYWw7XHJcblx0XHR0aGlzLmNoZWNrYm94ID0gbmV3IE9PLnVpLkNoZWNrYm94SW5wdXRXaWRnZXQoIHtcclxuXHRcdFx0c2VsZWN0ZWQ6IGlzSW5kZXRlcm1pbmF0ZSA/IHVuZGVmaW5lZCA6IGlzRmlyc3RBbGxvd2VkVmFsLFxyXG5cdFx0XHRpbmRldGVybWluYXRlOiBpc0luZGV0ZXJtaW5hdGUgPyB0cnVlIDogdW5kZWZpbmVkLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxsYWJlbCBzdHlsZT0nbWFyZ2luOjAgMCAwIDVweCc+XCIpXHJcblx0XHR9ICk7XHJcblx0XHRicmVhaztcclxuXHRkZWZhdWx0OlxyXG5cdFx0XHQvLyBObyBjaGVja2JveFxyXG5cdH0gLyogZXNsaW50LWVuYWJsZSBuby1mYWxsdGhyb3VnaCAqL1xyXG5cclxuXHQvKiAtLS0gRURJVCBQQVJBTUVURVIgTEFZT1VUIC0tLSAqL1xyXG5cclxuXHR0aGlzLmlucHV0ID0gbmV3IE9PLnVpLkNvbWJvQm94SW5wdXRXaWRnZXQoIHtcclxuXHRcdHZhbHVlOiB0aGlzLnZhbHVlLFxyXG5cdFx0Ly8gbGFiZWw6IHBhcmFtZXRlci5uYW1lICsgXCIgPVwiLFxyXG5cdFx0Ly8gbGFiZWxQb3NpdGlvbjogXCJiZWZvcmVcIixcclxuXHRcdG9wdGlvbnM6IGZpbHRlckFuZE1hcChcclxuXHRcdFx0dGhpcy5hbGxvd2VkVmFsdWVzLFxyXG5cdFx0XHR2YWwgPT4gdmFsIT09bnVsbCxcclxuXHRcdFx0dmFsID0+ICh7ZGF0YTogdmFsLCBsYWJlbDp2YWx9KVxyXG5cdFx0KSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPGRpdiBzdHlsZT0nbWFyZ2luLWJvdHRvbTowOyc+XCIpLFxyXG5cdFx0JG92ZXJsYXk6IHRoaXMuJG92ZXJsYXlcclxuXHR9ICk7XHJcblx0Ly8gUmVkdWNlIHRoZSBleGNlc3NpdmUgd2hpdGVzcGFjZS9oZWlnaHRcclxuXHR0aGlzLmlucHV0LiRlbGVtZW50LmZpbmQoXCJpbnB1dFwiKS5jc3Moe1xyXG5cdFx0XCJwYWRkaW5nLXRvcFwiOiAwLFxyXG5cdFx0XCJwYWRkaW5nLWJvdHRvbVwiOiBcIjJweFwiLFxyXG5cdFx0XCJoZWlnaHRcIjogXCIyNHB4XCJcclxuXHR9KTtcclxuXHQvLyBGaXggbGFiZWwgcG9zaXRpb25pbmcgd2l0aGluIHRoZSByZWR1Y2VkIGhlaWdodFxyXG5cdHRoaXMuaW5wdXQuJGVsZW1lbnQuZmluZChcInNwYW4ub28tdWktbGFiZWxFbGVtZW50LWxhYmVsXCIpLmNzcyh7XCJsaW5lLWhlaWdodFwiOiBcIm5vcm1hbFwifSk7XHJcblx0Ly8gQWxzbyByZWR1Y2UgaGVpZ2h0IG9mIGRyb3Bkb3duIGJ1dHRvbiAoaWYgb3B0aW9ucyBhcmUgcHJlc2VudClcclxuXHR0aGlzLmlucHV0LiRlbGVtZW50LmZpbmQoXCJhLm9vLXVpLWJ1dHRvbkVsZW1lbnQtYnV0dG9uXCIpLmNzcyh7XHJcblx0XHRcInBhZGRpbmctdG9wXCI6IDAsXHJcblx0XHRcImhlaWdodFwiOiBcIjI0cHhcIixcclxuXHRcdFwibWluLWhlaWdodFwiOiBcIjBcIlxyXG5cdH0pO1xyXG5cclxuXHR0aGlzLmNvbmZpcm1CdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KHtcclxuXHRcdGljb246IFwiY2hlY2tcIixcclxuXHRcdGxhYmVsOiBcIkRvbmVcIixcclxuXHRcdGZyYW1lZDogZmFsc2UsXHJcblx0XHRmbGFnczogXCJwcm9ncmVzc2l2ZVwiLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nbWFyZ2luLXJpZ2h0OjAnPlwiKVxyXG5cdH0pO1xyXG5cclxuXHR0aGlzLmNhbmNlbEJ1dHRvbiA9IG5ldyBPTy51aS5CdXR0b25XaWRnZXQoe1xyXG5cdFx0aWNvbjogXCJ1bmRvXCIsXHJcblx0XHRsYWJlbDogXCJDYW5jZWxcIixcclxuXHRcdGZyYW1lZDogZmFsc2UsXHJcblx0fSk7XHJcblxyXG5cdHRoaXMuZGVsZXRlQnV0dG9uID0gbmV3IE9PLnVpLkJ1dHRvbldpZGdldCh7XHJcblx0XHRpY29uOiB0aGlzLmlzUmVxdWlyZWQgPyBcInJlc3RvcmVcIiA6IFwidHJhc2hcIixcclxuXHRcdGxhYmVsOiB0aGlzLmlzUmVxdWlyZWQgPyBcIlJlcXVpcmVkIHBhcmFtZXRlclwiIDogXCJEZWxldGVcIixcclxuXHRcdGZyYW1lZDogZmFsc2UsXHJcblx0XHRmbGFnczogXCJkZXN0cnVjdGl2ZVwiLFxyXG5cdFx0ZGlzYWJsZWQ6IHRoaXMuaXNSZXF1aXJlZFxyXG5cdH0pO1xyXG5cclxuXHR0aGlzLmVkaXRCdXR0b25Db250cm9scyA9IG5ldyBPTy51aS5CdXR0b25Hcm91cFdpZGdldCh7XHJcblx0XHRpdGVtczogW1xyXG5cdFx0XHR0aGlzLmNvbmZpcm1CdXR0b24sXHJcblx0XHRcdHRoaXMuY2FuY2VsQnV0dG9uLFxyXG5cdFx0XHR0aGlzLmRlbGV0ZUJ1dHRvblxyXG5cdFx0XSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J2ZvbnQtc2l6ZTo5MiUnPlwiKVxyXG5cdH0pO1xyXG5cdHRoaXMuZWRpdEJ1dHRvbkNvbnRyb2xzLiRlbGVtZW50LmZpbmQoXCJhIHNwYW46Zmlyc3QtY2hpbGRcIikuY3NzKHtcclxuXHRcdFwibWluLXdpZHRoXCI6IFwidW5zZXRcIixcclxuXHRcdFwid2lkdGhcIjogXCIxNnB4XCIsXHJcblx0XHRcIm1hcmdpbi1yaWdodFwiOiAwXHJcblx0fSk7XHJcblxyXG5cdHRoaXMuZWRpdExheW91dENvbnRyb2xzID0gbmV3IEhvcml6b250YWxMYXlvdXRXaWRnZXQoe1xyXG5cdFx0aXRlbXM6IFtcclxuXHRcdFx0dGhpcy5pbnB1dCxcclxuXHRcdFx0dGhpcy5lZGl0QnV0dG9uQ29udHJvbHNcclxuXHRcdF0sXHJcblx0XHQvLyRlbGVtZW50OiAkKFwiPGRpdiBzdHlsZT0nd2lkdGg6IDQ4JTttYXJnaW46MDsnPlwiKVxyXG5cdH0pO1xyXG5cclxuXHR0aGlzLmVkaXRMYXlvdXQgPSBuZXcgT08udWkuRmllbGRMYXlvdXQoIHRoaXMuZWRpdExheW91dENvbnRyb2xzLCB7XHJcblx0XHRsYWJlbDogdGhpcy5uYW1lICsgXCIgPVwiLFxyXG5cdFx0YWxpZ246IFwidG9wXCIsXHJcblx0XHRoZWxwOiB0aGlzLnBhcmFtRGF0YS5kZXNjcmlwdGlvbiAmJiB0aGlzLnBhcmFtRGF0YS5kZXNjcmlwdGlvbi5lbiB8fCBmYWxzZSxcclxuXHRcdGhlbHBJbmxpbmU6IHRydWVcclxuXHR9KS50b2dnbGUoKTtcclxuXHR0aGlzLmVkaXRMYXlvdXQuJGVsZW1lbnQuZmluZChcImxhYmVsLm9vLXVpLWlubGluZS1oZWxwXCIpLmNzcyh7XCJtYXJnaW5cIjogXCItMTBweCAwIDVweCAxMHB4XCJ9KTtcclxuXHJcblx0LyogLS0tIFJFQUQgKENPTExBUFNFRCkgRElTUExBWSBPRiBQQVJBTUVURVIgLS0tICovXHJcblxyXG5cdHRoaXMuaW52YWxpZEljb24gPSBuZXcgT08udWkuSWNvbldpZGdldCgge1xyXG5cdFx0aWNvbjogXCJibG9ja1wiLFxyXG5cdFx0dGl0bGU6IFwiSW52YWxpZCBwYXJhbWV0ZXI6IG5vIHZhbHVlIHNwZWNpZmllZCFcIixcclxuXHRcdGZsYWdzOiBcImRlc3RydWN0aXZlXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxzcGFuIHN0eWxlPSdtYXJnaW46IDAgNXB4IDAgLTVweDsgbWluLXdpZHRoOiAxNnB4OyB3aWR0aDogMTZweDsnPlwiKVxyXG5cdH0gKS50b2dnbGUodGhpcy5pc0ludmFsaWQpO1xyXG5cdHRoaXMuZnVsbExhYmVsID0gbmV3IE9PLnVpLkxhYmVsV2lkZ2V0KHtcclxuXHRcdGxhYmVsOnRoaXMubmFtZSArXHJcblx0XHRcdCh0aGlzLnZhbHVlXHJcblx0XHRcdFx0PyBcIiA9IFwiICsgdGhpcy52YWx1ZVxyXG5cdFx0XHRcdDogXCIgXCJcclxuXHRcdFx0KSxcdFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8bGFiZWwgc3R5bGU9J21hcmdpbjogMDsnPlwiKVxyXG5cdH0pO1xyXG5cdHRoaXMuYXV0b2ZpbGxlZEljb24gPSBuZXcgT08udWkuSWNvbldpZGdldCgge1xyXG5cdFx0aWNvbjogXCJyb2JvdFwiLFxyXG5cdFx0dGl0bGU6IFwiQXV0b2ZpbGxlZCBieSBSYXRlclwiLFxyXG5cdFx0ZmxhZ3M6IFwicHJvZ3Jlc3NpdmVcIixcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J21hcmdpbjogMCAtNXB4IDAgNXB4O21pbi13aWR0aDogMTZweDt3aWR0aDogMTZweDsnPlwiKVxyXG5cdH0gKS50b2dnbGUodGhpcy5hdXRvZmlsbGVkKTtcclxuXHR0aGlzLmVkaXRCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KHtcclxuXHRcdGljb246IFwiZWRpdFwiLFxyXG5cdFx0ZnJhbWVkOiBmYWxzZSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J21hcmdpbi1ib3R0b206IDA7Jz5cIilcclxuXHR9KTtcclxuXHR0aGlzLmVkaXRCdXR0b24uJGVsZW1lbnQuZmluZChcImFcIikuY3NzKHtcclxuXHRcdFwiYm9yZGVyLXJhZGl1c1wiOiBcIjAgMTBweCAxMHB4IDBcIixcclxuXHRcdFwibWFyZ2luLWxlZnRcIjogXCI1cHhcIlxyXG5cdH0pO1xyXG5cdHRoaXMuZWRpdEJ1dHRvbi4kZWxlbWVudC5maW5kKFwiYSBzcGFuXCIpLmZpcnN0KCkuY3NzKHtcclxuXHRcdFwibWluLXdpZHRoXCI6IFwidW5zZXRcIixcclxuXHRcdFwid2lkdGhcIjogXCIxNnB4XCJcclxuXHR9KTtcclxuXHJcblx0dGhpcy5yZWFkTGF5b3V0ID0gbmV3IE9PLnVpLkhvcml6b250YWxMYXlvdXQoe1xyXG5cdFx0aXRlbXM6IFtcclxuXHRcdFx0dGhpcy5pbnZhbGlkSWNvbixcclxuXHRcdFx0dGhpcy5mdWxsTGFiZWwsXHJcblx0XHRcdHRoaXMuYXV0b2ZpbGxlZEljb24sXHJcblx0XHRcdHRoaXMuZWRpdEJ1dHRvblxyXG5cdFx0XSxcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J21hcmdpbjowO3dpZHRoOnVuc2V0Oyc+XCIpXHJcblx0fSk7XHJcblx0aWYgKHRoaXMuY2hlY2tib3gpIHtcclxuXHRcdHRoaXMucmVhZExheW91dC5hZGRJdGVtcyhbdGhpcy5jaGVja2JveF0sIDIpO1xyXG5cdH1cclxuXHJcblx0LyogLS0tIENPTlRBSU5FUiBGT1IgQk9USCBMQVlPVVRTIC0tLSAqL1xyXG5cdHRoaXMuJGVsZW1lbnQgPSAkKFwiPGRpdj5cIikuYWRkQ2xhc3MoXCJyYXRlci1wYXJhbWV0ZXJXaWRnZXRcIilcclxuXHRcdC5jc3Moe1xyXG5cdFx0XHRcIndpZHRoXCI6IFwidW5zZXRcIixcclxuXHRcdFx0XCJkaXNwbGF5XCI6IFwiaW5saW5lLWJsb2NrXCIsXHJcblx0XHRcdFwiYm9yZGVyXCI6IHRoaXMuYXV0b2ZpbGxlZCA/IFwiMXB4IGRhc2hlZCAjMzZjXCIgOiBcIjFweCBzb2xpZCAjZGRkXCIsXHJcblx0XHRcdFwiYm9yZGVyLXJhZGl1c1wiOiBcIjEwcHhcIixcclxuXHRcdFx0XCJwYWRkaW5nLWxlZnRcIjogXCIxMHB4XCIsXHJcblx0XHRcdFwibWFyZ2luXCI6IFwiMCA4cHggOHB4IDBcIixcclxuXHRcdFx0XCJiYWNrZ3JvdW5kXCI6IHRoaXMuaXNJbnZhbGlkID8gXCIjZmRkZFwiIDogXCIjZmZmZVwiXHJcblx0XHR9KVxyXG5cdFx0LmFwcGVuZCh0aGlzLnJlYWRMYXlvdXQuJGVsZW1lbnQsIHRoaXMuZWRpdExheW91dC4kZWxlbWVudCk7XHJcbiAgICBcclxuXHR0aGlzLmVkaXRCdXR0b24uY29ubmVjdCggdGhpcywgeyBcImNsaWNrXCI6IFwib25FZGl0Q2xpY2tcIiB9ICk7XHJcblx0dGhpcy5jb25maXJtQnV0dG9uLmNvbm5lY3QoIHRoaXMsIHsgXCJjbGlja1wiOiBcIm9uQ29uZmlybUNsaWNrXCIgfSApO1xyXG5cdHRoaXMuY2FuY2VsQnV0dG9uLmNvbm5lY3QoIHRoaXMsIHsgXCJjbGlja1wiOiBcIm9uQ2FuY2VsQ2xpY2tcIiB9ICk7XHJcblx0dGhpcy5kZWxldGVCdXR0b24uY29ubmVjdCggdGhpcywgeyBcImNsaWNrXCI6IFwib25EZWxldGVDbGlja1wiIH0gKTtcclxuXHRpZiAodGhpcy5jaGVja2JveCkge1xyXG5cdFx0dGhpcy5jaGVja2JveC5jb25uZWN0KHRoaXMsIHtcImNoYW5nZVwiOiBcIm9uQ2hlY2tib3hDaGFuZ2VcIn0gKTtcclxuXHR9XHJcbn1cclxuT08uaW5oZXJpdENsYXNzKCBQYXJhbWV0ZXJXaWRnZXQsIE9PLnVpLldpZGdldCApO1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5vblVwZGF0ZWRTaXplID0gZnVuY3Rpb24oKSB7XHJcblx0Ly8gRW1pdCBhbiBcInVwZGF0ZWRTaXplXCIgZXZlbnQgc28gdGhlIHBhcmVudCB3aW5kb3cgY2FuIHVwZGF0ZSBzaXplLCBpZiBuZWVkZWRcclxuXHR0aGlzLmVtaXQoXCJ1cGRhdGVkU2l6ZVwiKTtcclxufTtcclxuXHJcblBhcmFtZXRlcldpZGdldC5wcm90b3R5cGUub25FZGl0Q2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLnJlYWRMYXlvdXQudG9nZ2xlKGZhbHNlKTtcclxuXHR0aGlzLmVkaXRMYXlvdXQudG9nZ2xlKHRydWUpO1xyXG5cdHRoaXMuJGVsZW1lbnQuY3NzKHtcImJhY2tncm91bmRcIjogXCIjZmZmZVwifSk7XHJcblx0dGhpcy5pbnB1dC5mb2N1cygpO1xyXG5cdHRoaXMub25VcGRhdGVkU2l6ZSgpO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5vbkNvbmZpcm1DbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdHRoaXMuc2V0VmFsdWUoXHJcblx0XHR0aGlzLmlucHV0LmdldFZhbHVlKClcclxuXHQpO1xyXG5cdHRoaXMucmVhZExheW91dC50b2dnbGUodHJ1ZSk7XHJcblx0dGhpcy5lZGl0TGF5b3V0LnRvZ2dsZShmYWxzZSk7XHJcblx0dGhpcy5vblVwZGF0ZWRTaXplKCk7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJXaWRnZXQucHJvdG90eXBlLm9uQ2FuY2VsQ2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmlucHV0LnNldFZhbHVlKHRoaXMudmFsdWUpO1xyXG5cdHRoaXMucmVhZExheW91dC50b2dnbGUodHJ1ZSk7XHJcblx0dGhpcy5lZGl0TGF5b3V0LnRvZ2dsZShmYWxzZSk7XHJcblx0dGhpcy5vblVwZGF0ZWRTaXplKCk7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJXaWRnZXQucHJvdG90eXBlLm9uRGVsZXRlQ2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmRlbGV0ZSgpO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5vbkNoZWNrYm94Q2hhbmdlID0gZnVuY3Rpb24oaXNTZWxlY3RlZCwgaXNJbmRldGVybWluYXRlKSB7XHJcblx0aWYgKGlzSW5kZXRlcm1pbmF0ZSkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHRpZiAoaXNTZWxlY3RlZCkge1xyXG5cdFx0dGhpcy5zZXRWYWx1ZSh0aGlzLmFsbG93ZWRWYWx1ZXNbMF0pO1xyXG5cdH0gZWxzZSB7XHJcblx0XHR0aGlzLnNldFZhbHVlKHRoaXMuYWxsb3dlZFZhbHVlc1sxXSk7XHJcblx0fVxyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmVtaXQoXCJkZWxldGVcIik7XHJcbn07XHJcblxyXG5QYXJhbWV0ZXJXaWRnZXQucHJvdG90eXBlLnNldFZhbHVlID0gZnVuY3Rpb24odmFsKSB7XHJcblx0Ly8gVHVybiBvZmYgYXV0b2ZpbGwgc3R5bGluZ3MvaWNvblxyXG5cdHRoaXMuYXV0b2ZpbGxlZCA9IGZhbHNlO1xyXG5cdHRoaXMuYXV0b2ZpbGxlZEljb24udG9nZ2xlKGZhbHNlKTtcclxuXHR0aGlzLiRlbGVtZW50LmNzcyh7XCJib3JkZXJcIjogXCIxcHggc29saWQgI2RkZFwifSk7XHJcblxyXG5cdC8vIFVwZGF0ZSB0aGUgc3RvcmVkIHZhbHVlXHJcblx0dGhpcy52YWx1ZSA9IHZhbDtcclxuXHJcblx0Ly8gVXBkYXRlIHRoZSBpbnB1dCB2YWx1ZSBmb3IgZWRpdCBtb2RlXHJcblx0dGhpcy5pbnB1dC5zZXRWYWx1ZSh0aGlzLnZhbHVlKTtcclxuXHJcblx0Ly8gVXBkYXRlIHZhbGlkaXR5XHJcblx0dGhpcy5pc0ludmFsaWQgPSB0aGlzLnZhbHVlID09IG51bGw7XHJcblx0dGhpcy5pbnZhbGlkSWNvbi50b2dnbGUodGhpcy5pc0ludmFsaWQpO1xyXG5cdHRoaXMuJGVsZW1lbnQuY3NzKHtcImJhY2tncm91bmRcIjogdGhpcy5pc0ludmFsaWQgPyBcIiNmZGRkXCIgOiBcIiNmZmZlXCJ9KTtcclxuXHJcblx0Ly8gVXBkYXRlZCB0aGUgbGFiZWwgZm9yIHJlYWQgbW9kZVxyXG5cdHRoaXMuZnVsbExhYmVsLnNldExhYmVsKFxyXG5cdFx0dGhpcy5uYW1lICtcclxuXHRcdCh0aGlzLnZhbHVlXHJcblx0XHRcdD8gXCIgPSBcIiArIHRoaXMudmFsdWVcclxuXHRcdFx0OiBcIlwiXHJcblx0XHQpXHJcblx0KTtcclxuXHJcblx0Ly8gVXBkYXRlIHRoZSBjaGVja2JveCAoaWYgdGhlcmUgaXMgb25lKVxyXG5cdGlmICh0aGlzLmNoZWNrYm94KSB7XHJcblx0XHR2YXIgaXNGaXJzdEFsbG93ZWRWYWwgPSAoXHJcblx0XHRcdHRoaXMuYWxsb3dlZFZhbHVlcy5pbmRleE9mKCB2YWwgKSA9PT0gMCB8fFxyXG5cdFx0XHR0aGlzLmFsbG93ZWRWYWx1ZXMubWFwKG5vcm1hbGlzZVllc05vKS5pbmRleE9mKCBub3JtYWxpc2VZZXNObyh2YWwpICkgPT09IDBcclxuXHRcdCk7XHJcblx0XHR2YXIgaXNTZWNvbmRBbGxvd2VkVmFsID0gKFxyXG5cdFx0XHR0aGlzLmFsbG93ZWRWYWx1ZXMuaW5kZXhPZiggdmFsIHx8IG51bGwgKSA9PT0gMSB8fFxyXG5cdFx0XHR0aGlzLmFsbG93ZWRWYWx1ZXMubWFwKG5vcm1hbGlzZVllc05vKS5pbmRleE9mKCB2YWwgPyBub3JtYWxpc2VZZXNObyh2YWwpIDogbnVsbCkgPT09IDFcclxuXHRcdCk7XHJcblx0XHR2YXIgaXNJbmRldGVybWluYXRlID0gIWlzRmlyc3RBbGxvd2VkVmFsICYmICFpc1NlY29uZEFsbG93ZWRWYWw7XHJcblx0XHR0aGlzLmNoZWNrYm94LnNldEluZGV0ZXJtaW5hdGUoaXNJbmRldGVybWluYXRlLCB0cnVlKTtcclxuXHRcdGlmICghaXNJbmRldGVybWluYXRlKSB7XHJcblx0XHRcdHZhciBpc1NlbGVjdGVkID0gaXNGaXJzdEFsbG93ZWRWYWw7XHJcblx0XHRcdHRoaXMuY2hlY2tib3guc2V0U2VsZWN0ZWQoaXNTZWxlY3RlZCwgdHJ1ZSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBFbWl0IGEgY2hhbmdlIGV2ZW50XHJcblx0dGhpcy5lbWl0KFwiY2hhbmdlXCIpO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5zZXRBdXRvZmlsbGVkID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5hdXRvZmlsbGVkID0gdHJ1ZTtcclxuXHR0aGlzLmF1dG9maWxsZWRJY29uLnRvZ2dsZSh0cnVlKTtcclxuXHR0aGlzLiRlbGVtZW50LmNzcyh7XCJib3JkZXJcIjogXCIxcHggZGFzaGVkICMzNmNcIn0pO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5tYWtlV2lraXRleHQgPSBmdW5jdGlvbihwaXBlU3R5bGUsIGVxdWFsc1N0eWxlKSB7XHJcblx0aWYgKHRoaXMuaXNJbnZhbGlkKSB7XHJcblx0XHRyZXR1cm4gXCJcIjtcclxuXHR9XHJcblx0cmV0dXJuIHBpcGVTdHlsZSArIHRoaXMubmFtZSArIGVxdWFsc1N0eWxlICsgKHRoaXMudmFsdWV8fFwiXCIpO1xyXG59O1xyXG5cclxuUGFyYW1ldGVyV2lkZ2V0LnByb3RvdHlwZS5mb2N1c0lucHV0ID0gZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHRoaXMuaW5wdXQuZm9jdXMoKTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFBhcmFtZXRlcldpZGdldDtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IGNvbmZpZyBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG5mdW5jdGlvbiBQcmVmc0Zvcm1XaWRnZXQoIGNvbmZpZyApIHtcclxuXHQvLyBDb25maWd1cmF0aW9uIGluaXRpYWxpemF0aW9uXHJcblx0Y29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG5cdC8vIENhbGwgcGFyZW50IGNvbnN0cnVjdG9yXHJcblx0UHJlZnNGb3JtV2lkZ2V0LnN1cGVyLmNhbGwoIHRoaXMsIGNvbmZpZyApO1xyXG5cclxuXHR0aGlzLiRlbGVtZW50LmFkZENsYXNzKFwicmF0ZXItcHJlZnNGb3JtV2lkZ2V0XCIpO1xyXG5cclxuXHR0aGlzLmxheW91dCA9ICBuZXcgT08udWkuRmllbGRzZXRMYXlvdXQoIHtcclxuXHRcdGxhYmVsOiBcIlByZWZlcmVuY2VzXCIsXHJcblx0XHQkZWxlbWVudDogdGhpcy4kZWxlbWVudFxyXG5cdH0gKTtcclxuXHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IHtcclxuXHRcdFwiYXV0b3N0YXJ0XCI6IHtcclxuXHRcdFx0aW5wdXQ6IG5ldyBPTy51aS5Ub2dnbGVTd2l0Y2hXaWRnZXQoKSxcclxuXHRcdFx0bGFiZWw6IFwiQXV0b3N0YXJ0IFJhdGVyXCJcclxuXHRcdH0sXHJcblx0XHRcImF1dG9zdGFydFJlZGlyZWN0c1wiOiB7XHJcblx0XHRcdGlucHV0OiBuZXcgT08udWkuVG9nZ2xlU3dpdGNoV2lkZ2V0KCksXHJcblx0XHRcdGxhYmVsOiBcIkF1dG9zdGFydCBvbiByZWRpcmVjdHNcIlxyXG5cdFx0fSxcclxuXHRcdFwiYXV0b3N0YXJ0TmFtZXNwYWNlc1wiOiB7XHJcblx0XHRcdGlucHV0OiBuZXcgbXcud2lkZ2V0cy5OYW1lc3BhY2VzTXVsdGlzZWxlY3RXaWRnZXQoKSxcclxuXHRcdFx0bGFiZWw6IFwiQXV0b3N0YXJ0IGluIHRoZXNlIG5hbWVzcGFjZXNcIlxyXG5cdFx0fSxcclxuXHRcdFwiYnlwYXNzUmVkaXJlY3RzXCI6IHtcclxuXHRcdFx0aW5wdXQ6IG5ldyBPTy51aS5Ub2dnbGVTd2l0Y2hXaWRnZXQoKSxcclxuXHRcdFx0bGFiZWw6IFwiQnlwYXNzIHJlZGlyZWN0cyB0byBiYW5uZXJzXCJcclxuXHRcdH0sXHJcblx0XHRcImF1dG9maWxsQ2xhc3NGcm9tT3RoZXJzXCI6ICB7XHJcblx0XHRcdGlucHV0OiBuZXcgT08udWkuVG9nZ2xlU3dpdGNoV2lkZ2V0KCksXHJcblx0XHRcdGxhYmVsOiBcIkF1dG9maWxsIGNsYXNzIGZyb20gb3RoZXIgYmFubmVyc1wiXHJcblx0XHR9LFxyXG5cdFx0XCJhdXRvZmlsbENsYXNzRnJvbU9yZXNcIjoge1xyXG5cdFx0XHRpbnB1dDogbmV3IE9PLnVpLlRvZ2dsZVN3aXRjaFdpZGdldCgpLFxyXG5cdFx0XHRsYWJlbDogXCJBdXRvZmlsbCBjbGFzcyBiYXNlZCBvbiBPUkVTIHByZWRpY3Rpb25cIlxyXG5cdFx0fSxcclxuXHRcdFwiYXV0b2ZpbGxJbXBvcnRhbmNlXCI6IHtcclxuXHRcdFx0aW5wdXQ6IG5ldyBPTy51aS5Ub2dnbGVTd2l0Y2hXaWRnZXQoKSxcclxuXHRcdFx0bGFiZWw6IFwiQXV0b2ZpbGwgbG93IGltcG9ydGFuY2VcIlxyXG5cdFx0fSxcclxuXHRcdFwiY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0XCI6IHtcclxuXHRcdFx0aW5wdXQ6IG5ldyBPTy51aS5OdW1iZXJJbnB1dFdpZGdldCggeyBcIm1pblwiOiAxIH0gKSxcclxuXHRcdFx0bGFiZWw6IFwiTWluaW11bSBudW1iZXIgb2YgcGFyYW1ldGVycyB0byBzaG93IHVuY29sbGFwc2VkXCJcclxuXHRcdH0sXHJcblx0XHRcIndhdGNobGlzdFwiOiB7XHJcblx0XHRcdGlucHV0OiBuZXcgT08udWkuQnV0dG9uU2VsZWN0V2lkZ2V0KCB7XHJcblx0XHRcdFx0aXRlbXM6IFtcclxuXHRcdFx0XHRcdG5ldyBPTy51aS5CdXR0b25PcHRpb25XaWRnZXQoIHtcclxuXHRcdFx0XHRcdFx0ZGF0YTogXCJwcmVmZXJlbmNlc1wiLFxyXG5cdFx0XHRcdFx0XHRsYWJlbDogXCJEZWZhdWx0XCIsXHJcblx0XHRcdFx0XHRcdHRpdGxlOiBcIlVzZXMgdGhlIHNhbWUgc2V0dGluZyBhcyBpZiB5b3UgbWFudWFsbHkgZWRpdGVkIHRoZSBwYWdlLCBhcyBwZXIgU3BlY2lhbDpQcmVmZXJlbmNlc1wiXHJcblx0XHRcdFx0XHR9ICksXHJcblx0XHRcdFx0XHRuZXcgT08udWkuQnV0dG9uT3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRcdGRhdGE6IFwid2F0Y2hcIixcclxuXHRcdFx0XHRcdFx0bGFiZWw6IFwiQWx3YXlzXCIsXHJcblx0XHRcdFx0XHRcdHRpdGxlOiBcIkFsd2F5cyBhZGQgcGFnZXMgUmF0ZXIgZWRpdHMgdG8geW91ciB3YXRjaGxpc3RcIlxyXG5cdFx0XHRcdFx0fSApLFxyXG5cdFx0XHRcdFx0bmV3IE9PLnVpLkJ1dHRvbk9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0XHRkYXRhOiBcIm5vY2hhbmdlXCIsXHJcblx0XHRcdFx0XHRcdGxhYmVsOiBcIk5ldmVyXCIsXHJcblx0XHRcdFx0XHRcdHRpdGxlOiBcIk5ldmVyIGFkZCBwYWdlcyBSYXRlciBlZGl0IHRvIHlvdXIgd2F0Y2hsaXN0XCJcclxuXHRcdFx0XHRcdH0gKSxcclxuXHRcdFx0XHRdXHJcblx0XHRcdH0pLnNlbGVjdEl0ZW1CeURhdGEoXCJwcmVmZXJlbmNlc1wiKSxcclxuXHRcdFx0bGFiZWw6IFwiQWRkIGVkaXRlZCBwYWdlcyB0byB3YXRjaGxpc3RcIlxyXG5cdFx0fSxcclxuXHRcdFwicmVzZXRDYWNoZVwiOiB7XHJcblx0XHRcdGlucHV0OiBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0bGFiZWw6IFwiUmVzZXQgY2FjaGVcIixcclxuXHRcdFx0XHR0aXRsZTogXCJSZW1vdmUgY2FjaGVkIGRhdGEsIGluY2x1ZGluZyBsaXN0IG9mIFdpa2lQcm9qZWN0cyBhbmQgdGVtcGxhdGUgcGFyYW1ldGVyc1wiLFxyXG5cdFx0XHRcdGZsYWdzOiBbXCJkZXN0cnVjdGl2ZVwiXVxyXG5cdFx0XHR9IClcclxuXHRcdH1cclxuXHR9O1xyXG5cclxuXHRmb3IgKGxldCBwcmVmTmFtZSBpbiB0aGlzLnByZWZlcmVuY2VzICkge1xyXG5cdFx0dGhpcy5sYXlvdXQuYWRkSXRlbXMoW1xyXG5cdFx0XHRuZXcgT08udWkuRmllbGRMYXlvdXQoIHRoaXMucHJlZmVyZW5jZXNbcHJlZk5hbWVdLmlucHV0LCB7XHJcblx0XHRcdFx0bGFiZWw6IHRoaXMucHJlZmVyZW5jZXNbcHJlZk5hbWVdLmxhYmVsLFxyXG5cdFx0XHRcdGFsaWduOiBcInJpZ2h0XCJcclxuXHRcdFx0fSApXHJcblx0XHRdKTtcclxuXHR9XHJcblxyXG5cdHRoaXMucHJlZmVyZW5jZXMucmVzZXRDYWNoZS5pbnB1dC5jb25uZWN0KHRoaXMsIHtcImNsaWNrXCI6IFwib25SZXNldENhY2hlQ2xpY2tcIn0pO1xyXG59XHJcbk9PLmluaGVyaXRDbGFzcyggUHJlZnNGb3JtV2lkZ2V0LCBPTy51aS5XaWRnZXQgKTtcclxuXHJcblByZWZzRm9ybVdpZGdldC5wcm90b3R5cGUuc2V0UHJlZlZhbHVlcyA9IGZ1bmN0aW9uKHByZWZzKSB7XHJcblx0Zm9yIChsZXQgcHJlZk5hbWUgaW4gcHJlZnMgKSB7XHJcblx0XHRsZXQgdmFsdWUgPSBwcmVmc1twcmVmTmFtZV07XHJcblx0XHRsZXQgaW5wdXQgPSB0aGlzLnByZWZlcmVuY2VzW3ByZWZOYW1lXSAmJiB0aGlzLnByZWZlcmVuY2VzW3ByZWZOYW1lXS5pbnB1dDtcclxuXHRcdHN3aXRjaCAoaW5wdXQgJiYgaW5wdXQuY29uc3RydWN0b3IubmFtZSkge1xyXG5cdFx0Y2FzZSBcIk9vVWlCdXR0b25TZWxlY3RXaWRnZXRcIjpcclxuXHRcdFx0aW5wdXQuc2VsZWN0SXRlbUJ5RGF0YSh2YWx1ZSk7XHJcblx0XHRcdGJyZWFrO1xyXG5cdFx0Y2FzZSBcIk9vVWlOdW1iZXJJbnB1dFdpZGdldFwiOlxyXG5cdFx0Y2FzZSBcIk9vVWlUb2dnbGVTd2l0Y2hXaWRnZXRcIjpcclxuXHRcdFx0aW5wdXQuc2V0VmFsdWUodmFsdWUpO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdGNhc2UgXCJNd1dpZGdldHNOYW1lc3BhY2VzTXVsdGlzZWxlY3RXaWRnZXRcIjpcclxuXHRcdFx0aW5wdXQuY2xlYXJJdGVtcygpO1xyXG5cdFx0XHR2YWx1ZS5mb3JFYWNoKG5zID0+XHJcblx0XHRcdFx0aW5wdXQuYWRkVGFnKFxyXG5cdFx0XHRcdFx0bnMudG9TdHJpbmcoKSxcclxuXHRcdFx0XHRcdG5zID09PSAwXHJcblx0XHRcdFx0XHRcdD8gXCIoTWFpbilcIlxyXG5cdFx0XHRcdFx0XHQ6IGNvbmZpZy5tdy53Z0Zvcm1hdHRlZE5hbWVzcGFjZXNbbnNdXHJcblx0XHRcdFx0KVxyXG5cdFx0XHQpO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdH1cclxuXHR9XHJcbn07XHJcblxyXG5QcmVmc0Zvcm1XaWRnZXQucHJvdG90eXBlLmdldFByZWZzID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIHByZWZzID0ge307XHJcblx0Zm9yIChsZXQgcHJlZk5hbWUgaW4gdGhpcy5wcmVmZXJlbmNlcyApIHtcclxuXHRcdGxldCBpbnB1dCA9IHRoaXMucHJlZmVyZW5jZXNbcHJlZk5hbWVdLmlucHV0O1xyXG5cdFx0bGV0IHZhbHVlO1xyXG5cdFx0c3dpdGNoIChpbnB1dC5jb25zdHJ1Y3Rvci5uYW1lKSB7XHJcblx0XHRjYXNlIFwiT29VaUJ1dHRvblNlbGVjdFdpZGdldFwiOlxyXG5cdFx0XHR2YWx1ZSA9IGlucHV0LmZpbmRTZWxlY3RlZEl0ZW0oKS5nZXREYXRhKCk7XHJcblx0XHRcdGJyZWFrO1xyXG5cdFx0Y2FzZSBcIk9vVWlUb2dnbGVTd2l0Y2hXaWRnZXRcIjpcclxuXHRcdFx0dmFsdWUgPSBpbnB1dC5nZXRWYWx1ZSgpO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdGNhc2UgXCJPb1VpTnVtYmVySW5wdXRXaWRnZXRcIjpcclxuXHRcdFx0dmFsdWUgPSBOdW1iZXIoaW5wdXQuZ2V0VmFsdWUoKSk7IC8vIHdpZGdldCB1c2VzIHN0cmluZ3MsIG5vdCBudW1iZXJzIVxyXG5cdFx0XHRicmVhaztcclxuXHRcdGNhc2UgXCJNd1dpZGdldHNOYW1lc3BhY2VzTXVsdGlzZWxlY3RXaWRnZXRcIjpcclxuXHRcdFx0dmFsdWUgPSBpbnB1dC5nZXRWYWx1ZSgpLm1hcChOdW1iZXIpOyAvLyB3aWRnZXQgdXNlcyBzdHJpbmdzLCBub3QgbnVtYmVycyFcclxuXHRcdFx0YnJlYWs7XHJcblx0XHR9XHJcblx0XHRwcmVmc1twcmVmTmFtZV0gPSB2YWx1ZTtcclxuXHR9XHJcblx0cmV0dXJuIHByZWZzO1xyXG59O1xyXG5cclxuUHJlZnNGb3JtV2lkZ2V0LnByb3RvdHlwZS5vblJlc2V0Q2FjaGVDbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdE9PLnVpLmNvbmZpcm0oXCJBZnRlciByZXNldGluZyBjYWNoZSwgUmF0ZXIgd2lsbCBjbG9zZSBhbmQgcmVzdGFydC4gQW55IGNoYW5nZXMgbWFkZSB3aWxsIGJlIGRpc2NhcmRlZC5cIilcclxuXHRcdC50aGVuKGNvbmZpcm1lZCA9PiB7XHJcblx0XHRcdGlmIChjb25maXJtZWQpIHsgXHJcblx0XHRcdFx0dGhpcy5lbWl0KFwicmVzZXRDYWNoZVwiKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBQcmVmc0Zvcm1XaWRnZXQ7XHJcbi8vIDwvbm93aWtpPiIsIi8vIDxub3dpa2k+XHJcblxyXG52YXIgU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldCA9IGZ1bmN0aW9uIFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQoIGNvbmZpZyApIHtcclxuXHRPTy51aS5UZXh0SW5wdXRXaWRnZXQuY2FsbCggdGhpcywgY29uZmlnICk7XHJcblx0T08udWkubWl4aW4uTG9va3VwRWxlbWVudC5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxuXHR0aGlzLnN1Z2dlc3Rpb25zID0gQXJyYXkuaXNBcnJheShjb25maWcuc3VnZ2VzdGlvbnMpID8gY29uZmlnLnN1Z2dlc3Rpb25zIDogW107XHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLXN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXRcIik7XHJcbn07XHJcbk9PLmluaGVyaXRDbGFzcyggU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldCwgT08udWkuVGV4dElucHV0V2lkZ2V0ICk7XHJcbk9PLm1peGluQ2xhc3MoIFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQsIE9PLnVpLm1peGluLkxvb2t1cEVsZW1lbnQgKTtcclxuXHJcbi8vIFNldCBzdWdnZXN0aW9uLiBwYXJhbTogT2JqZWN0W10gd2l0aCBvYmplY3RzIG9mIHRoZSBmb3JtIHsgZGF0YTogLi4uICwgbGFiZWw6IC4uLiB9XHJcblN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQucHJvdG90eXBlLnNldFN1Z2dlc3Rpb25zID0gZnVuY3Rpb24oc3VnZ2VzdGlvbnMpIHtcclxuXHRpZiAoIUFycmF5LmlzQXJyYXkoc3VnZ2VzdGlvbnMpKSB7XHJcblx0XHRpZiAoc3VnZ2VzdGlvbnMgIT0gbnVsbCkge1xyXG5cdFx0XHRjb25zb2xlLndhcm4oXCJbUmF0ZXJdIFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQucHJvdG90eXBlLnNldFN1Z2dlc3Rpb25zIGNhbGxlZCB3aXRoIGEgbm9uLWFycmF5IHZhbHVlOlwiLCBzdWdnZXN0aW9ucyk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdHRoaXMuc3VnZ2VzdGlvbnMgPSBzdWdnZXN0aW9ucztcclxufTtcclxuXHJcbi8vIFJldHVybnMgZGF0YSwgYXMgYSByZXNvbHV0aW9uIHRvIGEgcHJvbWlzZSwgdG8gYmUgcGFzc2VkIHRvICNnZXRMb29rdXBNZW51T3B0aW9uc0Zyb21EYXRhXHJcblN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQucHJvdG90eXBlLmdldExvb2t1cFJlcXVlc3QgPSBmdW5jdGlvbiAoKSB7XHJcblx0dmFyIGRlZmVycmVkID0gJC5EZWZlcnJlZCgpLnJlc29sdmUobmV3IFJlZ0V4cChcIlxcXFxiXCIgKyBtdy51dGlsLmVzY2FwZVJlZ0V4cCh0aGlzLmdldFZhbHVlKCkpLCBcImlcIikpO1xyXG5cdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCB7IGFib3J0OiBmdW5jdGlvbiAoKSB7fSB9ICk7XHJcbn07XHJcblxyXG4vLyA/Pz9cclxuU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldC5wcm90b3R5cGUuZ2V0TG9va3VwQ2FjaGVEYXRhRnJvbVJlc3BvbnNlID0gZnVuY3Rpb24gKCByZXNwb25zZSApIHtcclxuXHRyZXR1cm4gcmVzcG9uc2UgfHwgW107XHJcbn07XHJcblxyXG4vLyBJcyBwYXNzZWQgZGF0YSBmcm9tICNnZXRMb29rdXBSZXF1ZXN0LCByZXR1cm5zIGFuIGFycmF5IG9mIG1lbnUgaXRlbSB3aWRnZXRzIFxyXG5TdWdnZXN0aW9uTG9va3VwVGV4dElucHV0V2lkZ2V0LnByb3RvdHlwZS5nZXRMb29rdXBNZW51T3B0aW9uc0Zyb21EYXRhID0gZnVuY3Rpb24gKCBwYXR0ZXJuICkge1xyXG5cdHZhciBsYWJlbE1hdGNoZXNJbnB1dFZhbCA9IGZ1bmN0aW9uKHN1Z2dlc3Rpb25JdGVtKSB7XHJcblx0XHRyZXR1cm4gcGF0dGVybi50ZXN0KHN1Z2dlc3Rpb25JdGVtLmxhYmVsKSB8fCAoICFzdWdnZXN0aW9uSXRlbS5sYWJlbCAmJiBwYXR0ZXJuLnRlc3Qoc3VnZ2VzdGlvbkl0ZW0uZGF0YSkgKTtcclxuXHR9O1xyXG5cdHZhciBtYWtlTWVudU9wdGlvbldpZGdldCA9IGZ1bmN0aW9uKG9wdGlvbkl0ZW0pIHtcclxuXHRcdHJldHVybiBuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRkYXRhOiBvcHRpb25JdGVtLmRhdGEsXHJcblx0XHRcdGxhYmVsOiBvcHRpb25JdGVtLmxhYmVsIHx8IG9wdGlvbkl0ZW0uZGF0YVxyXG5cdFx0fSApO1xyXG5cdH07XHJcblx0cmV0dXJuIHRoaXMuc3VnZ2VzdGlvbnMuZmlsdGVyKGxhYmVsTWF0Y2hlc0lucHV0VmFsKS5tYXAobWFrZU1lbnVPcHRpb25XaWRnZXQpO1xyXG59O1xyXG5cclxuLy8gRXh0ZW5kIG9uTG9va3VwTWVudUNob29zZSBtZXRob2QgdG8gZW1pdCBhbiBjaG9vc2UgZXZlbnRcclxuU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldC5wcm90b3R5cGUub25Mb29rdXBNZW51Q2hvb3NlID0gZnVuY3Rpb24gKCBpdGVtICkge1xyXG5cdC8vIEdldCBkYXRhXHJcblx0Y29uc3QgaXRlbURhdGEgPSBpdGVtLmdldERhdGEoKTtcclxuXHQvLyBTaW1wbGlmeSBpdGVtIGRhdGEgaWYgaXQgaXMgYW4gb2JqZWN0IHdpdGggYSBuYW1lIHByb3BlcnR5XHJcblx0aWYgKGl0ZW1EYXRhICYmIGl0ZW1EYXRhLm5hbWUpIHtcclxuXHRcdGl0ZW0uc2V0RGF0YShpdGVtRGF0YS5uYW1lKTtcclxuXHR9XHJcblx0Ly8gRmlyc3QgYmx1ciB0aGUgaW5wdXQsIHRvIHByZXZlbnQgdGhlIG1lbnUgcG9wcGluZyBiYWNrIHVwXHJcblx0dGhpcy4kaW5wdXQuYmx1cigpO1xyXG5cdE9PLnVpLm1peGluLkxvb2t1cEVsZW1lbnQucHJvdG90eXBlLm9uTG9va3VwTWVudUNob29zZS5jYWxsKHRoaXMsIGl0ZW0pO1xyXG5cdHRoaXMuZW1pdChcImNob29zZVwiLCBpdGVtRGF0YSApO1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgU3VnZ2VzdGlvbkxvb2t1cFRleHRJbnB1dFdpZGdldDtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IGFwcENvbmZpZyBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XHJcbmltcG9ydCBTdWdnZXN0aW9uTG9va3VwVGV4dElucHV0V2lkZ2V0IGZyb20gXCIuL1N1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXRcIjtcclxuaW1wb3J0IHtnZXRCYW5uZXJOYW1lc30gZnJvbSBcIi4uLy4uL2dldEJhbm5lcnNcIjtcclxuLy8gPG5vd2lraT5cclxuXHJcbmZ1bmN0aW9uIFRvcEJhcldpZGdldCggY29uZmlnICkge1xyXG5cdC8vIENvbmZpZ3VyYXRpb24gaW5pdGlhbGl6YXRpb25cclxuXHRjb25maWcgPSAkLmV4dGVuZChcclxuXHRcdHtcclxuXHRcdFx0ZXhwYW5kZWQ6IGZhbHNlLFxyXG5cdFx0XHRmcmFtZWQ6IGZhbHNlLFxyXG5cdFx0XHRwYWRkZWQ6IGZhbHNlXHJcblx0XHR9LFxyXG5cdFx0Y29uZmlnIHx8IHt9XHJcblx0KTtcclxuXHQvLyBDYWxsIHBhcmVudCBjb25zdHJ1Y3RvclxyXG5cdFRvcEJhcldpZGdldC5zdXBlci5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxuXHR0aGlzLiRvdmVybGF5ID0gY29uZmlnLiRvdmVybGF5O1xyXG4gICAgXHJcblx0Ly8gU2VhcmNoIGJveFxyXG5cdHRoaXMuc2VhcmNoQm94ID0gbmV3IFN1Z2dlc3Rpb25Mb29rdXBUZXh0SW5wdXRXaWRnZXQoIHtcclxuXHRcdHBsYWNlaG9sZGVyOiBcIkFkZCBhIFdpa2lQcm9qZWN0Li4uXCIsXHJcblx0XHQkZWxlbWVudDogJChcIjxkaXYgc3R5bGU9J2Rpc3BsYXk6aW5saW5lLWJsb2NrOyBtYXJnaW46MCAtMXB4OyB3aWR0aDpjYWxjKDEwMCUgLSA1NXB4KTsnPlwiKSxcclxuXHRcdCRvdmVybGF5OiB0aGlzLiRvdmVybGF5LFxyXG5cdH0gKTtcclxuXHRnZXRCYW5uZXJOYW1lcygpXHJcblx0XHQudGhlbihiYW5uZXJzID0+IFtcclxuXHRcdFx0Li4uYmFubmVycy53aXRoUmF0aW5ncy5tYXAoYmFubmVyTmFtZSA9PiAoe1xyXG5cdFx0XHRcdGxhYmVsOiBiYW5uZXJOYW1lLnJlcGxhY2UoXCJXaWtpUHJvamVjdCBcIiwgXCJcIiksXHJcblx0XHRcdFx0ZGF0YToge1xyXG5cdFx0XHRcdFx0bmFtZTogYmFubmVyTmFtZVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSkpLFxyXG5cdFx0XHQuLi5iYW5uZXJzLndpdGhvdXRSYXRpbmdzLm1hcChiYW5uZXJOYW1lID0+ICh7XHJcblx0XHRcdFx0bGFiZWw6IGJhbm5lck5hbWUucmVwbGFjZShcIldpa2lQcm9qZWN0IFwiLCBcIlwiKSxcclxuXHRcdFx0XHRkYXRhOiB7XHJcblx0XHRcdFx0XHRuYW1lOiBiYW5uZXJOYW1lLFxyXG5cdFx0XHRcdFx0d2l0aG91dFJhdGluZ3M6IHRydWVcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pKSxcclxuXHRcdFx0Li4uYmFubmVycy53cmFwcGVycy5tYXAoYmFubmVyTmFtZSA9PiAoe1xyXG5cdFx0XHRcdGxhYmVsOiBiYW5uZXJOYW1lLnJlcGxhY2UoXCJXaWtpUHJvamVjdCBcIiwgXCJcIikgKyBcIiBbdGVtcGxhdGUgd3JhcHBlcl1cIixcclxuXHRcdFx0XHRkYXRhOiB7XHJcblx0XHRcdFx0XHRuYW1lOiBiYW5uZXJOYW1lLFxyXG5cdFx0XHRcdFx0d3JhcHBlcjogdHJ1ZVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSkpLFxyXG5cdFx0XHQuLi5iYW5uZXJzLm5vdFdQQk0ubWFwKGJhbm5lck5hbWUgPT4gKHtcclxuXHRcdFx0XHRsYWJlbDogYmFubmVyTmFtZS5yZXBsYWNlKFwiV2lraVByb2plY3QgXCIsIFwiXCIpLFxyXG5cdFx0XHRcdGRhdGE6IHtcclxuXHRcdFx0XHRcdG5hbWU6IGJhbm5lck5hbWVcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pKSxcclxuXHRcdFx0Li4uYmFubmVycy5pbmFjdGl2ZS5tYXAoYmFubmVyTmFtZSA9PiAoe1xyXG5cdFx0XHRcdGxhYmVsOiBiYW5uZXJOYW1lLnJlcGxhY2UoXCJXaWtpUHJvamVjdCBcIiwgXCJcIikgKyBcIiBbaW5hY3RpdmVdXCIsXHJcblx0XHRcdFx0ZGF0YToge1xyXG5cdFx0XHRcdFx0bmFtZTogYmFubmVyTmFtZSxcclxuXHRcdFx0XHRcdHdpdGhvdXRSYXRpbmdzOiB0cnVlXHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9KSksXHJcblx0XHRcdC4uLmJhbm5lcnMud2lyLm1hcChiYW5uZXJOYW1lID0+ICh7XHJcblx0XHRcdFx0bGFiZWw6IGJhbm5lck5hbWUgKyBcIiBbV29tZW4gSW4gUmVkIG1lZXR1cC9pbml0aWF0aXZlXVwiLFxyXG5cdFx0XHRcdGRhdGE6IHtcclxuXHRcdFx0XHRcdG5hbWU6IGJhbm5lck5hbWUsXHJcblx0XHRcdFx0XHR3aXRob3V0UmF0aW5nczogdHJ1ZVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSkpXHJcblx0XHRdKVxyXG5cdFx0LnRoZW4oYmFubmVyT3B0aW9ucyA9PiB0aGlzLnNlYXJjaEJveC5zZXRTdWdnZXN0aW9ucyhiYW5uZXJPcHRpb25zKSk7XHJcbiAgICBcclxuXHQvLyBBZGQgYnV0dG9uXHJcblx0dGhpcy5hZGRCYW5uZXJCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KCB7XHJcblx0XHRpY29uOiBcImFkZFwiLFxyXG5cdFx0dGl0bGU6IFwiQWRkXCIsXHJcblx0XHRmbGFnczogXCJwcm9ncmVzc2l2ZVwiLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nZmxvYXQ6cmlnaHQ7bWFyZ2luOiAwO3RyYW5zZm9ybTogdHJhbnNsYXRlWCgtMTJweCk7Jz5cIiksXHJcblx0fSApO1xyXG5cdHZhciAkc2VhcmNoQ29udGFpbmVyID0gJChcIjxkaXYgc3R5bGU9J2Rpc3BsYXk6aW5saW5lLWJsb2NrOyBmbGV4LXNocmluazoxOyBmbGV4LWdyb3c6MTAwOyBtaW4td2lkdGg6MjUwcHg7IHdpZHRoOjUwJTsnPlwiKVxyXG5cdFx0LmFwcGVuZCh0aGlzLnNlYXJjaEJveC4kZWxlbWVudCwgdGhpcy5hZGRCYW5uZXJCdXR0b24uJGVsZW1lbnQpO1xyXG5cclxuXHQvLyBTZXQgYWxsIGNsYXNzZXMvaW1wb3J0YW5jZXNcclxuXHQvLyBpbiB0aGUgc3R5bGUgb2YgYSBwb3B1cCBidXR0b24gd2l0aCBhIG1lbnUgKGlzIGFjdHVhbGx5IGEgZHJvcGRvd24gd2l0aCBhIGhpZGRlbiBsYWJlbCwgYmVjYXVzZSB0aGF0IG1ha2VzIHRoZSBjb2RpbmcgZWFzaWVyLilcclxuXHR0aGlzLnNldEFsbERyb3BEb3duID0gbmV3IE9PLnVpLkRyb3Bkb3duV2lkZ2V0KCB7XHJcblx0XHRpY29uOiBcInRhZ1wiLFxyXG5cdFx0bGFiZWw6IFwiU2V0IGFsbC4uLlwiLFxyXG5cdFx0aW52aXNpYmxlTGFiZWw6IHRydWUsXHJcblx0XHRtZW51OiB7XHJcblx0XHRcdGl0ZW1zOiBbXHJcblx0XHRcdFx0bmV3IE9PLnVpLk1lbnVTZWN0aW9uT3B0aW9uV2lkZ2V0KCB7XHJcblx0XHRcdFx0XHRsYWJlbDogXCJDbGFzc2VzXCJcclxuXHRcdFx0XHR9ICksXHJcblx0XHRcdFx0bmV3IE9PLnVpLk1lbnVPcHRpb25XaWRnZXQoIHtcclxuXHRcdFx0XHRcdGRhdGE6IHtjbGFzczogbnVsbH0sXHJcblx0XHRcdFx0XHRsYWJlbDogbmV3IE9PLnVpLkh0bWxTbmlwcGV0KFwiPHNwYW4gc3R5bGU9XFxcImNvbG9yOiM3NzdcXFwiPihubyBjbGFzcyk8L3NwYW4+XCIpXHJcblx0XHRcdFx0fSApLFxyXG5cdFx0XHRcdC4uLmFwcENvbmZpZy5iYW5uZXJEZWZhdWx0cy5jbGFzc2VzLm1hcChjbGFzc25hbWUgPT4gbmV3IE9PLnVpLk1lbnVPcHRpb25XaWRnZXQoIHtcclxuXHRcdFx0XHRcdGRhdGE6IHtjbGFzczogY2xhc3NuYW1lfSxcclxuXHRcdFx0XHRcdGxhYmVsOiBjbGFzc25hbWVcclxuXHRcdFx0XHR9IClcclxuXHRcdFx0XHQpLFxyXG5cdFx0XHRcdG5ldyBPTy51aS5NZW51U2VjdGlvbk9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0bGFiZWw6IFwiSW1wb3J0YW5jZXNcIlxyXG5cdFx0XHRcdH0gKSxcclxuXHRcdFx0XHRuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0ZGF0YToge2ltcG9ydGFuY2U6IG51bGx9LFxyXG5cdFx0XHRcdFx0bGFiZWw6IG5ldyBPTy51aS5IdG1sU25pcHBldChcIjxzcGFuIHN0eWxlPVxcXCJjb2xvcjojNzc3XFxcIj4obm8gaW1wb3J0YW5jZSk8L3NwYW4+XCIpXHJcblx0XHRcdFx0fSApLFxyXG5cdFx0XHRcdC4uLmFwcENvbmZpZy5iYW5uZXJEZWZhdWx0cy5pbXBvcnRhbmNlcy5tYXAoaW1wb3J0YW5jZSA9PiBuZXcgT08udWkuTWVudU9wdGlvbldpZGdldCgge1xyXG5cdFx0XHRcdFx0ZGF0YToge2ltcG9ydGFuY2U6IGltcG9ydGFuY2V9LFxyXG5cdFx0XHRcdFx0bGFiZWw6IGltcG9ydGFuY2VcclxuXHRcdFx0XHR9IClcclxuXHRcdFx0XHQpXHJcblx0XHRcdF1cclxuXHRcdH0sXHJcblx0XHQkZWxlbWVudDogJChcIjxzcGFuIHN0eWxlPVxcXCJ3aWR0aDphdXRvO2Rpc3BsYXk6aW5saW5lLWJsb2NrO2Zsb2F0OmxlZnQ7bWFyZ2luOjBcXFwiIHRpdGxlPSdTZXQgYWxsLi4uJz5cIiksXHJcblx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHR9ICk7XHJcblxyXG5cdC8vIFJlbW92ZSBhbGwgYmFubmVycyBidXR0b25cclxuXHR0aGlzLnJlbW92ZUFsbEJ1dHRvbiA9IG5ldyBPTy51aS5CdXR0b25XaWRnZXQoIHtcclxuXHRcdGljb246IFwidHJhc2hcIixcclxuXHRcdHRpdGxlOiBcIlJlbW92ZSBhbGxcIixcclxuXHRcdGZsYWdzOiBcImRlc3RydWN0aXZlXCJcclxuXHR9ICk7XHJcblxyXG5cdC8vIENsZWFyIGFsbCBwYXJhbWV0ZXJzIGJ1dHRvblxyXG5cdHRoaXMuY2xlYXJBbGxCdXR0b24gPSBuZXcgT08udWkuQnV0dG9uV2lkZ2V0KCB7XHJcblx0XHRpY29uOiBcImNhbmNlbFwiLFxyXG5cdFx0dGl0bGU6IFwiQ2xlYXIgYWxsXCIsXHJcblx0XHRmbGFnczogXCJkZXN0cnVjdGl2ZVwiXHJcblx0fSApO1xyXG5cclxuXHQvLyBHcm91cCB0aGUgYnV0dG9ucyB0b2dldGhlclxyXG5cdHRoaXMubWVudUJ1dHRvbnMgPSBuZXcgT08udWkuQnV0dG9uR3JvdXBXaWRnZXQoIHtcclxuXHRcdGl0ZW1zOiBbXHJcblx0XHRcdHRoaXMucmVtb3ZlQWxsQnV0dG9uLFxyXG5cdFx0XHR0aGlzLmNsZWFyQWxsQnV0dG9uXHJcblx0XHRdLFxyXG5cdFx0JGVsZW1lbnQ6ICQoXCI8c3BhbiBzdHlsZT0nZmxleDoxIDAgYXV0bzsnPlwiKSxcclxuXHR9ICk7XHJcblx0Ly8gSW5jbHVkZSB0aGUgZHJvcGRvd24gaW4gdGhlIGdyb3VwXHJcblx0dGhpcy5tZW51QnV0dG9ucy4kZWxlbWVudC5wcmVwZW5kKHRoaXMuc2V0QWxsRHJvcERvd24uJGVsZW1lbnQpO1xyXG5cclxuXHQvLyBQdXQgZXZlcnl0aGluZyBpbnRvIGEgbGF5b3V0XHJcblx0dGhpcy4kZWxlbWVudC5hZGRDbGFzcyhcInJhdGVyLXRvcEJhcldpZGdldFwiKVxyXG5cdFx0LmNzcyh7XHJcblx0XHRcdFwicG9zaXRpb25cIjogXCJmaXhlZFwiLFxyXG5cdFx0XHRcIndpZHRoXCI6IFwiMTAwJVwiLFxyXG5cdFx0XHRcImJhY2tncm91bmRcIjogXCIjY2NjXCIsXHJcblx0XHRcdFwiZGlzcGxheVwiOiBcImZsZXhcIixcclxuXHRcdFx0XCJmbGV4LXdyYXBcIjogXCJ3cmFwXCIsXHJcblx0XHRcdFwianVzdGlmeS1jb250ZW50XCI6IFwic3BhY2UtYXJvdW5kXCIsXHJcblx0XHRcdFwibWFyZ2luXCI6IFwiLTJweCAwIDAgMFwiXHJcblx0XHR9KVxyXG5cdFx0LmFwcGVuZChcclxuXHRcdFx0JHNlYXJjaENvbnRhaW5lcixcclxuXHRcdFx0dGhpcy5tZW51QnV0dG9ucy4kZWxlbWVudFxyXG5cdFx0KTtcclxuXHJcblx0LyogLS0tIEV2ZW50IGhhbmRsaW5nIC0tLSAqL1xyXG4gICAgXHJcblx0dGhpcy5zZWFyY2hCb3guY29ubmVjdCh0aGlzLCB7XHJcblx0XHRcImVudGVyXCI6IFwib25TZWFyY2hTZWxlY3RcIixcclxuXHRcdFwiY2hvb3NlXCI6IFwib25TZWFyY2hTZWxlY3RcIlxyXG5cdH0pO1xyXG5cdHRoaXMuYWRkQmFubmVyQnV0dG9uLmNvbm5lY3QodGhpcywge1wiY2xpY2tcIjogXCJvblNlYXJjaFNlbGVjdFwifSk7XHJcblx0dGhpcy5zZXRBbGxEcm9wRG93bi5nZXRNZW51KCkuY29ubmVjdCh0aGlzLCB7XCJjaG9vc2VcIjogXCJvblJhdGluZ0Nob29zZVwifSk7XHJcblx0dGhpcy5yZW1vdmVBbGxCdXR0b24uY29ubmVjdCh0aGlzLCB7XCJjbGlja1wiOiBcIm9uUmVtb3ZlQWxsQ2xpY2tcIn0pO1xyXG5cdHRoaXMuY2xlYXJBbGxCdXR0b24uY29ubmVjdCh0aGlzLCB7XCJjbGlja1wiOiBcIm9uQ2xlYXJBbGxDbGlja1wifSk7XHJcbn1cclxuT08uaW5oZXJpdENsYXNzKCBUb3BCYXJXaWRnZXQsIE9PLnVpLlBhbmVsTGF5b3V0ICk7XHJcblxyXG5Ub3BCYXJXaWRnZXQucHJvdG90eXBlLm9uU2VhcmNoU2VsZWN0ID0gZnVuY3Rpb24oZGF0YSkge1xyXG5cdHRoaXMuZW1pdChcInNlYXJjaFNlbGVjdFwiLCBkYXRhKTtcclxufTtcclxuXHJcblRvcEJhcldpZGdldC5wcm90b3R5cGUub25SYXRpbmdDaG9vc2UgPSBmdW5jdGlvbihpdGVtKSB7XHJcblx0Y29uc3QgZGF0YSA9IGl0ZW0uZ2V0RGF0YSgpO1xyXG5cdGlmIChkYXRhLmNsYXNzIHx8IGRhdGEuY2xhc3M9PT1udWxsKSB7XHJcblx0XHR0aGlzLmVtaXQoXCJzZXRDbGFzc2VzXCIsIGRhdGEuY2xhc3MpO1xyXG5cdH1cclxuXHRpZiAoZGF0YS5pbXBvcnRhbmNlIHx8IGRhdGEuaW1wb3J0YW5jZT09PW51bGwpIHtcclxuXHRcdHRoaXMuZW1pdChcInNldEltcG9ydGFuY2VzXCIsIGRhdGEuaW1wb3J0YW5jZSk7XHJcblx0fVxyXG59O1xyXG5cclxuVG9wQmFyV2lkZ2V0LnByb3RvdHlwZS5vblJlbW92ZUFsbENsaWNrID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5lbWl0KFwicmVtb3ZlQWxsXCIpO1xyXG59O1xyXG5cclxuVG9wQmFyV2lkZ2V0LnByb3RvdHlwZS5vbkNsZWFyQWxsQ2xpY2sgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmVtaXQoXCJjbGVhckFsbFwiKTtcclxufTtcclxuXHJcblRvcEJhcldpZGdldC5wcm90b3R5cGUuc2V0RGlzYWJsZWQgPSBmdW5jdGlvbihkaXNhYmxlKSB7XHJcblx0W1xyXG5cdFx0dGhpcy5zZWFyY2hCb3gsXHJcblx0XHR0aGlzLmFkZEJhbm5lckJ1dHRvbixcclxuXHRcdHRoaXMuc2V0QWxsRHJvcERvd24sXHJcblx0XHR0aGlzLnJlbW92ZUFsbEJ1dHRvbixcclxuXHRcdHRoaXMuY2xlYXJBbGxCdXR0b25cclxuXHRdLmZvckVhY2god2lkZ2V0ID0+IHdpZGdldC5zZXREaXNhYmxlZChkaXNhYmxlKSk7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBUb3BCYXJXaWRnZXQ7XHJcbi8vIDwvbm93aWtpPiIsImltcG9ydCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuLi9hcGlcIjtcclxuLy8gPG5vd2lraT5cclxuXHJcbi8qIHZhciBpbmNyZW1lbnRQcm9ncmVzc0J5SW50ZXJ2YWwgPSBmdW5jdGlvbigpIHtcclxuXHR2YXIgaW5jcmVtZW50SW50ZXJ2YWxEZWxheSA9IDEwMDtcclxuXHR2YXIgaW5jcmVtZW50SW50ZXJ2YWxBbW91bnQgPSAwLjE7XHJcblx0dmFyIGluY3JlbWVudEludGVydmFsTWF4dmFsID0gOTg7XHJcblx0cmV0dXJuIHdpbmRvdy5zZXRJbnRlcnZhbChcclxuXHRcdGluY3JlbWVudFByb2dyZXNzLFxyXG5cdFx0aW5jcmVtZW50SW50ZXJ2YWxEZWxheSxcclxuXHRcdGluY3JlbWVudEludGVydmFsQW1vdW50LFxyXG5cdFx0aW5jcmVtZW50SW50ZXJ2YWxNYXh2YWxcclxuXHQpO1xyXG59OyAqL1xyXG5cclxudmFyIExvYWREaWFsb2cgPSBmdW5jdGlvbiBMb2FkRGlhbG9nKCBjb25maWcgKSB7XHJcblx0TG9hZERpYWxvZy5zdXBlci5jYWxsKCB0aGlzLCBjb25maWcgKTtcclxufTtcclxuT08uaW5oZXJpdENsYXNzKCBMb2FkRGlhbG9nLCBPTy51aS5EaWFsb2cgKTsgXHJcblxyXG5Mb2FkRGlhbG9nLnN0YXRpYy5uYW1lID0gXCJsb2FkRGlhbG9nXCI7XHJcbkxvYWREaWFsb2cuc3RhdGljLnRpdGxlID0gXCJMb2FkaW5nIFJhdGVyLi4uXCI7XHJcblxyXG4vLyBDdXN0b21pemUgdGhlIGluaXRpYWxpemUoKSBmdW5jdGlvbjogVGhpcyBpcyB3aGVyZSB0byBhZGQgY29udGVudCB0byB0aGUgZGlhbG9nIGJvZHkgYW5kIHNldCB1cCBldmVudCBoYW5kbGVycy5cclxuTG9hZERpYWxvZy5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuXHQvLyBDYWxsIHRoZSBwYXJlbnQgbWV0aG9kLlxyXG5cdExvYWREaWFsb2cuc3VwZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbCggdGhpcyApO1xyXG5cdC8vIENyZWF0ZSBhIGxheW91dFxyXG5cdHRoaXMuY29udGVudCA9IG5ldyBPTy51aS5QYW5lbExheW91dCggeyBcclxuXHRcdHBhZGRlZDogdHJ1ZSxcclxuXHRcdGV4cGFuZGVkOiBmYWxzZSBcclxuXHR9ICk7XHJcblx0Ly8gQ3JlYXRlIGNvbnRlbnRcclxuXHR0aGlzLnByb2dyZXNzQmFyID0gbmV3IE9PLnVpLlByb2dyZXNzQmFyV2lkZ2V0KCB7XHJcblx0XHRwcm9ncmVzczogMVxyXG5cdH0gKTtcclxuXHR0aGlzLnNldHVwdGFza3MgPSBbXHJcblx0XHRuZXcgT08udWkuTGFiZWxXaWRnZXQoIHtcclxuXHRcdFx0bGFiZWw6IFwiTG9hZGluZyB5b3VyIFJhdGVyIHByZWZlcmVuY2VzLi4uXCIsXHJcblx0XHRcdCRlbGVtZW50OiAkKFwiPHAgc3R5bGU9XFxcImRpc3BsYXk6YmxvY2tcXFwiPlwiKVxyXG5cdFx0fSksXHJcblx0XHRuZXcgT08udWkuTGFiZWxXaWRnZXQoIHtcclxuXHRcdFx0bGFiZWw6IFwiTG9hZGluZyBsaXN0IG9mIHByb2plY3QgYmFubmVycy4uLlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxwIHN0eWxlPVxcXCJkaXNwbGF5OmJsb2NrXFxcIj5cIilcclxuXHRcdH0pLFxyXG5cdFx0bmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBcIkxvYWRpbmcgdGFsa3BhZ2Ugd2lraXRleHQuLi5cIixcclxuXHRcdFx0JGVsZW1lbnQ6ICQoXCI8cCBzdHlsZT1cXFwiZGlzcGxheTpibG9ja1xcXCI+XCIpXHJcblx0XHR9KSxcclxuXHRcdG5ldyBPTy51aS5MYWJlbFdpZGdldCgge1xyXG5cdFx0XHRsYWJlbDogXCJQYXJzaW5nIHRhbGtwYWdlIHRlbXBsYXRlcy4uLlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxwIHN0eWxlPVxcXCJkaXNwbGF5OmJsb2NrXFxcIj5cIilcclxuXHRcdH0pLFxyXG5cdFx0bmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBcIkdldHRpbmcgdGVtcGxhdGVzJyBwYXJhbWV0ZXIgZGF0YS4uLlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxwIHN0eWxlPVxcXCJkaXNwbGF5OmJsb2NrXFxcIj5cIilcclxuXHRcdH0pLFxyXG5cdFx0bmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBcIkNoZWNraW5nIHN1YmplY3QgcGFnZS4uLlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxwIHN0eWxlPVxcXCJkaXNwbGF5OmJsb2NrXFxcIj5cIilcclxuXHRcdH0pLFxyXG5cdFx0bmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7XHJcblx0XHRcdGxhYmVsOiBcIlJldHJpZXZpbmcgcXVhbGl0eSBwcmVkaWN0aW9uLi4uXCIsXHJcblx0XHRcdCRlbGVtZW50OiAkKFwiPHAgc3R5bGU9XFxcImRpc3BsYXk6YmxvY2tcXFwiPlwiKVxyXG5cdFx0fSkudG9nZ2xlKCksXHJcblx0XTtcclxuXHR0aGlzLmNsb3NlQnV0dG9uID0gbmV3IE9PLnVpLkJ1dHRvbldpZGdldCgge1xyXG5cdFx0bGFiZWw6IFwiQ2xvc2VcIlxyXG5cdH0pLnRvZ2dsZSgpO1xyXG5cdHRoaXMuc2V0dXBQcm9taXNlcyA9IFtdO1xyXG5cclxuXHQvLyBBcHBlbmQgY29udGVudCB0byBsYXlvdXRcclxuXHR0aGlzLmNvbnRlbnQuJGVsZW1lbnQuYXBwZW5kKFxyXG5cdFx0dGhpcy5wcm9ncmVzc0Jhci4kZWxlbWVudCxcclxuXHRcdChuZXcgT08udWkuTGFiZWxXaWRnZXQoIHtcclxuXHRcdFx0bGFiZWw6IFwiSW5pdGlhbGlzaW5nOlwiLFxyXG5cdFx0XHQkZWxlbWVudDogJChcIjxzdHJvbmcgc3R5bGU9XFxcImRpc3BsYXk6YmxvY2tcXFwiPlwiKVxyXG5cdFx0fSkpLiRlbGVtZW50LFxyXG5cdFx0Li4udGhpcy5zZXR1cHRhc2tzLm1hcCh3aWRnZXQgPT4gd2lkZ2V0LiRlbGVtZW50KSxcclxuXHRcdHRoaXMuY2xvc2VCdXR0b24uJGVsZW1lbnRcclxuXHQpO1xyXG5cclxuXHQvLyBBcHBlbmQgbGF5b3V0IHRvIGRpYWxvZ1xyXG5cdHRoaXMuJGJvZHkuYXBwZW5kKCB0aGlzLmNvbnRlbnQuJGVsZW1lbnQgKTtcclxuXHJcblx0Ly8gQ29ubmVjdCBldmVudHMgdG8gaGFuZGxlcnNcclxuXHR0aGlzLmNsb3NlQnV0dG9uLmNvbm5lY3QoIHRoaXMsIHsgXCJjbGlja1wiOiBcIm9uQ2xvc2VCdXR0b25DbGlja1wiIH0gKTtcclxufTtcclxuXHJcbkxvYWREaWFsb2cucHJvdG90eXBlLm9uQ2xvc2VCdXR0b25DbGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdC8vIENsb3NlIHRoaXMgZGlhbG9nLCB3aXRob3V0IHBhc3NpbmcgYW55IGRhdGFcclxuXHR0aGlzLmNsb3NlKCk7XHJcbn07XHJcblxyXG4vLyBPdmVycmlkZSB0aGUgZ2V0Qm9keUhlaWdodCgpIG1ldGhvZCB0byBzcGVjaWZ5IGEgY3VzdG9tIGhlaWdodCAob3IgZG9uJ3QgdG8gdXNlIHRoZSBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBoZWlnaHQpLlxyXG5Mb2FkRGlhbG9nLnByb3RvdHlwZS5nZXRCb2R5SGVpZ2h0ID0gZnVuY3Rpb24gKCkge1xyXG5cdHJldHVybiB0aGlzLmNvbnRlbnQuJGVsZW1lbnQub3V0ZXJIZWlnaHQoIHRydWUgKTtcclxufTtcclxuXHJcbkxvYWREaWFsb2cucHJvdG90eXBlLmluY3JlbWVudFByb2dyZXNzID0gZnVuY3Rpb24oYW1vdW50LCBtYXhpbXVtKSB7XHJcblx0dmFyIHByaW9yUHJvZ3Jlc3MgPSB0aGlzLnByb2dyZXNzQmFyLmdldFByb2dyZXNzKCk7XHJcblx0dmFyIGluY3JlbWVudGVkUHJvZ3Jlc3MgPSBNYXRoLm1pbihtYXhpbXVtIHx8IDEwMCwgcHJpb3JQcm9ncmVzcyArIGFtb3VudCk7XHJcblx0dGhpcy5wcm9ncmVzc0Jhci5zZXRQcm9ncmVzcyhpbmNyZW1lbnRlZFByb2dyZXNzKTtcclxufTtcclxuXHJcbkxvYWREaWFsb2cucHJvdG90eXBlLmFkZFRhc2tQcm9taXNlSGFuZGxlcnMgPSBmdW5jdGlvbih0YXNrUHJvbWlzZXMpIHtcclxuXHR2YXIgb25UYXNrRG9uZSA9IGluZGV4ID0+IHtcclxuXHRcdC8vIEFkZCBcIkRvbmUhXCIgdG8gbGFiZWxcclxuXHRcdHZhciB3aWRnZXQgPSB0aGlzLnNldHVwdGFza3NbaW5kZXhdO1xyXG5cdFx0d2lkZ2V0LnNldExhYmVsKHdpZGdldC5nZXRMYWJlbCgpICsgXCIgRG9uZSFcIik7XHJcblx0XHQvLyBJbmNyZW1lbnQgc3RhdHVzIGJhci4gU2hvdyBhIHNtb290aCB0cmFuc2l0aW9uIGJ5XHJcblx0XHQvLyB1c2luZyBzbWFsbCBzdGVwcyBvdmVyIGEgc2hvcnQgZHVyYXRpb24uXHJcblx0XHR2YXIgdG90YWxJbmNyZW1lbnQgPSAxMDAgLyB0aGlzLnNldHVwdGFza3MubGVuZ3RoOyAvLyBwZXJjZW50XHJcblx0XHR2YXIgdG90YWxUaW1lID0gNDAwOyAvLyBtaWxsaXNlY29uZHNcclxuXHRcdHZhciB0b3RhbFN0ZXBzID0gMTA7XHJcblx0XHR2YXIgaW5jcmVtZW50UGVyU3RlcCA9IHRvdGFsSW5jcmVtZW50IC8gdG90YWxTdGVwcztcclxuXHJcblx0XHRmb3IgKCB2YXIgc3RlcD0wOyBzdGVwIDwgdG90YWxTdGVwczsgc3RlcCsrKSB7XHJcblx0XHRcdHdpbmRvdy5zZXRUaW1lb3V0KFxyXG5cdFx0XHRcdHRoaXMuaW5jcmVtZW50UHJvZ3Jlc3MuYmluZCh0aGlzKSxcclxuXHRcdFx0XHR0b3RhbFRpbWUgKiBzdGVwIC8gdG90YWxTdGVwcyxcclxuXHRcdFx0XHRpbmNyZW1lbnRQZXJTdGVwXHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblx0fTtcclxuXHR2YXIgb25UYXNrRXJyb3IgPSAoaW5kZXgsIGNvZGUsIGluZm8pID0+IHtcclxuXHRcdHZhciB3aWRnZXQgPSB0aGlzLnNldHVwdGFza3NbaW5kZXhdO1xyXG5cdFx0d2lkZ2V0LnNldExhYmVsKFxyXG5cdFx0XHR3aWRnZXQuZ2V0TGFiZWwoKSArIFwiIEZhaWxlZC4gXCIgKyBtYWtlRXJyb3JNc2coY29kZSwgaW5mbylcclxuXHRcdCk7XHJcblx0XHR0aGlzLmNsb3NlQnV0dG9uLnRvZ2dsZSh0cnVlKTtcclxuXHRcdHRoaXMudXBkYXRlU2l6ZSgpO1xyXG5cdH07XHJcblx0dGFza1Byb21pc2VzLmZvckVhY2goZnVuY3Rpb24ocHJvbWlzZSwgaW5kZXgpIHtcclxuXHRcdHByb21pc2UudGhlbihcclxuXHRcdFx0KCkgPT4gb25UYXNrRG9uZShpbmRleCksXHJcblx0XHRcdChjb2RlLCBpbmZvKSA9PiBvblRhc2tFcnJvcihpbmRleCwgY29kZSwgaW5mbylcclxuXHRcdCk7XHJcblx0fSk7XHJcbn07XHJcblxyXG4vLyBVc2UgZ2V0U2V0dXBQcm9jZXNzKCkgdG8gc2V0IHVwIHRoZSB3aW5kb3cgd2l0aCBkYXRhIHBhc3NlZCB0byBpdCBhdCB0aGUgdGltZSBcclxuLy8gb2Ygb3BlbmluZ1xyXG5Mb2FkRGlhbG9nLnByb3RvdHlwZS5nZXRTZXR1cFByb2Nlc3MgPSBmdW5jdGlvbiAoIGRhdGEgKSB7XHJcblx0ZGF0YSA9IGRhdGEgfHwge307XHJcblx0cmV0dXJuIExvYWREaWFsb2cuc3VwZXIucHJvdG90eXBlLmdldFNldHVwUHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhIClcclxuXHRcdC5uZXh0KCAoKSA9PiB7XHJcblx0XHRcdHZhciBzaG93T3Jlc1Rhc2sgPSAhIWRhdGEub3JlcztcclxuXHRcdFx0dGhpcy5zZXR1cHRhc2tzWzZdLnRvZ2dsZShzaG93T3Jlc1Rhc2spO1xyXG5cdFx0XHR2YXIgdGFza1Byb21pc2VzID0gZGF0YS5vcmVzID8gZGF0YS5wcm9taXNlcyA6IGRhdGEucHJvbWlzZXMuc2xpY2UoMCwgLTEpO1xyXG5cdFx0XHRkYXRhLmlzT3BlbmVkLnRoZW4oKCkgPT4gdGhpcy5hZGRUYXNrUHJvbWlzZUhhbmRsZXJzKHRhc2tQcm9taXNlcykpO1xyXG5cdFx0fSwgdGhpcyApO1xyXG59O1xyXG5cclxuLy8gUHJldmVudCB3aW5kb3cgZnJvbSBjbG9zaW5nIHRvbyBxdWlja2x5LCB1c2luZyBnZXRIb2xkUHJvY2VzcygpXHJcbkxvYWREaWFsb2cucHJvdG90eXBlLmdldEhvbGRQcm9jZXNzID0gZnVuY3Rpb24gKCBkYXRhICkge1xyXG5cdGRhdGEgPSBkYXRhIHx8IHt9O1xyXG5cdGlmIChkYXRhLnN1Y2Nlc3MpIHtcclxuXHRcdC8vIFdhaXQgYSBiaXQgYmVmb3JlIHByb2Nlc3NpbmcgdGhlIGNsb3NlLCB3aGljaCBoYXBwZW5zIGF1dG9tYXRpY2FsbHlcclxuXHRcdHJldHVybiBMb2FkRGlhbG9nLnN1cGVyLnByb3RvdHlwZS5nZXRIb2xkUHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhIClcclxuXHRcdFx0Lm5leHQoODAwKTtcclxuXHR9XHJcblx0Ly8gTm8gbmVlZCB0byB3YWl0IGlmIGNsb3NlZCBtYW51YWxseVxyXG5cdHJldHVybiBMb2FkRGlhbG9nLnN1cGVyLnByb3RvdHlwZS5nZXRIb2xkUHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhICk7XHJcbn07XHJcblxyXG4vLyBVc2UgdGhlIGdldFRlYXJkb3duUHJvY2VzcygpIG1ldGhvZCB0byBwZXJmb3JtIGFjdGlvbnMgd2hlbmV2ZXIgdGhlIGRpYWxvZyBpcyBjbG9zZWQuIFxyXG5Mb2FkRGlhbG9nLnByb3RvdHlwZS5nZXRUZWFyZG93blByb2Nlc3MgPSBmdW5jdGlvbiAoIGRhdGEgKSB7XHJcblx0cmV0dXJuIExvYWREaWFsb2cuc3VwZXIucHJvdG90eXBlLmdldFRlYXJkb3duUHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhIClcclxuXHRcdC5maXJzdCggKCkgPT4ge1xyXG5cdFx0Ly8gUGVyZm9ybSBjbGVhbnVwOiByZXNldCBsYWJlbHNcclxuXHRcdFx0dGhpcy5zZXR1cHRhc2tzLmZvckVhY2goIHNldHVwdGFzayA9PiB7XHJcblx0XHRcdFx0dmFyIGN1cnJlbnRMYWJlbCA9IHNldHVwdGFzay5nZXRMYWJlbCgpO1xyXG5cdFx0XHRcdHNldHVwdGFzay5zZXRMYWJlbChcclxuXHRcdFx0XHRcdGN1cnJlbnRMYWJlbC5zbGljZSgwLCBjdXJyZW50TGFiZWwuaW5kZXhPZihcIi4uLlwiKSszKVxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH0gKTtcclxuXHRcdH0sIHRoaXMgKTtcclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IExvYWREaWFsb2c7XHJcbi8vIDwvbm93aWtpPiIsImltcG9ydCBCYW5uZXJXaWRnZXQgZnJvbSBcIi4vQ29tcG9uZW50cy9CYW5uZXJXaWRnZXRcIjtcclxuaW1wb3J0IEJhbm5lckxpc3RXaWRnZXQgZnJvbSBcIi4vQ29tcG9uZW50cy9CYW5uZXJMaXN0V2lkZ2V0XCI7XHJcbmltcG9ydCBhcHBDb25maWcgZnJvbSBcIi4uL2NvbmZpZ1wiO1xyXG5pbXBvcnQgQVBJLCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuLi9hcGlcIjtcclxuaW1wb3J0IFByZWZzRm9ybVdpZGdldCBmcm9tIFwiLi9Db21wb25lbnRzL1ByZWZzRm9ybVdpZGdldFwiO1xyXG5pbXBvcnQgeyBzZXRQcmVmcyBhcyBBcGlTZXRQcmVmcyB9IGZyb20gXCIuLi9wcmVmc1wiO1xyXG5pbXBvcnQgeyBwYXJzZVRlbXBsYXRlcyB9IGZyb20gXCIuLi9UZW1wbGF0ZVwiO1xyXG5pbXBvcnQgVG9wQmFyV2lkZ2V0IGZyb20gXCIuL0NvbXBvbmVudHMvVG9wQmFyV2lkZ2V0XCI7XHJcbmltcG9ydCB7IGZpbHRlckFuZE1hcCwgdW5pcXVlQXJyYXkgfSBmcm9tIFwiLi4vdXRpbFwiO1xyXG5pbXBvcnQgKiBhcyBjYWNoZSBmcm9tIFwiLi4vY2FjaGVcIjtcclxuLy8gPG5vd2lraT5cclxuXHJcbmZ1bmN0aW9uIE1haW5XaW5kb3coIGNvbmZpZyApIHtcclxuXHRNYWluV2luZG93LnN1cGVyLmNhbGwoIHRoaXMsIGNvbmZpZyApO1xyXG59XHJcbk9PLmluaGVyaXRDbGFzcyggTWFpbldpbmRvdywgT08udWkuUHJvY2Vzc0RpYWxvZyApO1xyXG5cclxuTWFpbldpbmRvdy5zdGF0aWMubmFtZSA9IFwibWFpblwiO1xyXG5NYWluV2luZG93LnN0YXRpYy50aXRsZSA9ICQoXCI8c3Bhbj5cIikuY3NzKHtcImZvbnQtd2VpZ2h0XCI6XCJub3JtYWxcIn0pLmFwcGVuZChcclxuXHQkKFwiPGE+XCIpLmNzcyh7XCJmb250LXdlaWdodFwiOiBcImJvbGRcIn0pLmF0dHIoe1wiaHJlZlwiOiBtdy51dGlsLmdldFVybChcIldQOlJBVEVSXCIpLCBcInRhcmdldFwiOiBcIl9ibGFua1wifSkudGV4dChcIlJhdGVyXCIpLFxyXG5cdFwiIChcIixcclxuXHQkKFwiPGE+XCIpLmF0dHIoe1wiaHJlZlwiOiBtdy51dGlsLmdldFVybChcIldUOlJBVEVSXCIpLCBcInRhcmdldFwiOiBcIl9ibGFua1wifSkudGV4dChcInRhbGtcIiksXHJcblx0XCIpIFwiLFxyXG5cdCQoXCI8c3Bhbj5cIikuY3NzKHtcImZvbnQtc2l6ZVwiOlwiOTAlXCJ9KS50ZXh0KFwidlwiK2FwcENvbmZpZy5zY3JpcHQudmVyc2lvbilcclxuKTtcclxuTWFpbldpbmRvdy5zdGF0aWMuc2l6ZSA9IFwibGFyZ2VcIjtcclxuTWFpbldpbmRvdy5zdGF0aWMuYWN0aW9ucyA9IFtcclxuXHQvLyBQcmltYXJ5ICh0b3AgcmlnaHQpOlxyXG5cdHtcclxuXHRcdGxhYmVsOiBcIlhcIiwgLy8gbm90IHVzaW5nIGFuIGljb24gc2luY2UgY29sb3IgYmVjb21lcyBpbnZlcnRlZCwgaS5lLiB3aGl0ZSBvbiBsaWdodC1ncmV5XHJcblx0XHR0aXRsZTogXCJDbG9zZSAoYW5kIGRpc2NhcmQgYW55IGNoYW5nZXMpXCIsXHJcblx0XHRmbGFnczogXCJwcmltYXJ5XCIsXHJcblx0XHRtb2RlczogW1wiZWRpdFwiLCBcImRpZmZcIiwgXCJwcmV2aWV3XCJdIC8vIGF2YWlsYWJsZSB3aGVuIGN1cnJlbnQgbW9kZSBpc24ndCBcInByZWZzXCJcclxuXHR9LFxyXG5cdC8vIFNhZmUgKHRvcCBsZWZ0KVxyXG5cdHtcclxuXHRcdGFjdGlvbjogXCJzaG93UHJlZnNcIixcclxuXHRcdGZsYWdzOiBcInNhZmVcIixcclxuXHRcdGljb246IFwic2V0dGluZ3NcIixcclxuXHRcdHRpdGxlOiBcIlByZWZlcmVuY2VzXCIsXHJcblx0XHRtb2RlczogW1wiZWRpdFwiLCBcImRpZmZcIiwgXCJwcmV2aWV3XCJdIC8vIGF2YWlsYWJsZSB3aGVuIGN1cnJlbnQgbW9kZSBpc24ndCBcInByZWZzXCJcclxuXHR9LFxyXG5cdC8vIE90aGVycyAoYm90dG9tKVxyXG5cdHtcclxuXHRcdGFjdGlvbjogXCJzYXZlXCIsXHJcblx0XHRhY2Nlc3NLZXk6IFwic1wiLFxyXG5cdFx0bGFiZWw6IG5ldyBPTy51aS5IdG1sU25pcHBldChcIjxzcGFuIHN0eWxlPSdwYWRkaW5nOjAgMWVtOyc+U2F2ZTwvc3Bhbj5cIiksXHJcblx0XHRmbGFnczogW1wicHJpbWFyeVwiLCBcInByb2dyZXNzaXZlXCJdLFxyXG5cdFx0bW9kZXM6IFtcImVkaXRcIiwgXCJkaWZmXCIsIFwicHJldmlld1wiXSAvLyBhdmFpbGFibGUgd2hlbiBjdXJyZW50IG1vZGUgaXNuJ3QgXCJwcmVmc1wiXHJcblx0fSxcclxuXHR7XHJcblx0XHRhY3Rpb246IFwicHJldmlld1wiLFxyXG5cdFx0YWNjZXNzS2V5OiBcInBcIixcclxuXHRcdGxhYmVsOiBcIlNob3cgcHJldmlld1wiLFxyXG5cdFx0bW9kZXM6IFtcImVkaXRcIiwgXCJkaWZmXCJdIC8vIGF2YWlsYWJsZSB3aGVuIGN1cnJlbnQgbW9kZSBpc24ndCBcInByZXZpZXdcIiBvciBcInByZWZzXCJcclxuXHR9LFxyXG5cdHtcclxuXHRcdGFjdGlvbjogXCJjaGFuZ2VzXCIsXHJcblx0XHRhY2Nlc3NLZXk6IFwidlwiLFxyXG5cdFx0bGFiZWw6IFwiU2hvdyBjaGFuZ2VzXCIsXHJcblx0XHRtb2RlczogW1wiZWRpdFwiLCBcInByZXZpZXdcIl0gLy8gYXZhaWxhYmxlIHdoZW4gY3VycmVudCBtb2RlIGlzbid0IFwiZGlmZlwiIG9yIFwicHJlZnNcIlxyXG5cdH0sXHJcblx0e1xyXG5cdFx0YWN0aW9uOiBcImJhY2tcIixcclxuXHRcdGxhYmVsOiBcIkJhY2tcIixcclxuXHRcdG1vZGVzOiBbXCJkaWZmXCIsIFwicHJldmlld1wiXSAvLyBhdmFpbGFibGUgd2hlbiBjdXJyZW50IG1vZGUgaXMgXCJkaWZmXCIgb3IgXCJwcmVmc1wiXHJcblx0fSxcclxuXHRcclxuXHQvLyBcInByZWZzXCIgbW9kZSBvbmx5XHJcblx0e1xyXG5cdFx0YWN0aW9uOiBcInNhdmVQcmVmc1wiLFxyXG5cdFx0bGFiZWw6IFwiVXBkYXRlXCIsXHJcblx0XHRmbGFnczogW1wicHJpbWFyeVwiLCBcInByb2dyZXNzaXZlXCJdLFxyXG5cdFx0bW9kZXM6IFwicHJlZnNcIiBcclxuXHR9LFxyXG5cdHtcclxuXHRcdGFjdGlvbjogXCJjbG9zZVByZWZzXCIsXHJcblx0XHRsYWJlbDogXCJDYW5jZWxcIixcclxuXHRcdGZsYWdzOiBcInNhZmVcIixcclxuXHRcdG1vZGVzOiBcInByZWZzXCJcclxuXHR9XHJcbl07XHJcblxyXG4vLyBDdXN0b21pemUgdGhlIGluaXRpYWxpemUoKSBmdW5jdGlvbjogVGhpcyBpcyB3aGVyZSB0byBhZGQgY29udGVudCB0byB0aGUgZGlhbG9nIGJvZHkgYW5kIHNldCB1cCBldmVudCBoYW5kbGVycy5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuXHQvLyBDYWxsIHRoZSBwYXJlbnQgbWV0aG9kLlxyXG5cdE1haW5XaW5kb3cuc3VwZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbCggdGhpcyApO1xyXG5cclxuXHQvKiAtLS0gUFJFRlMgLS0tICovXHJcblx0dGhpcy5wcmVmZXJlbmNlcyA9IGFwcENvbmZpZy5kZWZhdWx0UHJlZnM7XHJcblx0XHJcblx0LyogLS0tIFRPUCBCQVIgLS0tICovXHJcblx0dGhpcy50b3BCYXIgPSBuZXcgVG9wQmFyV2lkZ2V0KHtcclxuXHRcdCRvdmVybGF5OiB0aGlzLiRvdmVybGF5XHJcblx0fSApO1xyXG5cdHRoaXMuJGhlYWQuY3NzKHtcImhlaWdodFwiOlwiNzNweFwifSkuYXBwZW5kKHRoaXMudG9wQmFyLiRlbGVtZW50KTtcclxuXHJcblx0LyogLS0tIEZPT1RFUiAtLS0gKi9cclxuXHR0aGlzLm9yZXNMYWJlbCA9IG5ldyBPTy51aS5MYWJlbFdpZGdldCh7XHJcblx0XHQkZWxlbWVudDogJChcIjxzcGFuIHN0eWxlPSdmbG9hdDpyaWdodDsgcGFkZGluZzogMTBweDsgbWF4LXdpZHRoOiA1MCU7IHRleHQtYWxpZ246IGNlbnRlcjsnPlwiKSxcclxuXHRcdGxhYmVsOiAkKFwiPHNwYW4+XCIpLmFwcGVuZChcclxuXHRcdFx0JChcIjxhPlwiKVxyXG5cdFx0XHRcdC5hdHRyKHtcImhyZWZcIjptdy51dGlsLmdldFVybChcIm13Ok9SRVNcIiksIFwidGFyZ2V0XCI6XCJfYmxhbmtcIn0pXHJcblx0XHRcdFx0LmFwcGVuZChcclxuXHRcdFx0XHRcdCQoXCI8aW1nPlwiKVxyXG5cdFx0XHRcdFx0XHQuY3NzKHtcInZlcnRpY2FsLWFsaWduXCI6IFwidGV4dC1ib3R0b207XCJ9KVxyXG5cdFx0XHRcdFx0XHQuYXR0cih7XHJcblx0XHRcdFx0XHRcdFx0XCJzcmNcIjogXCIvL3VwbG9hZC53aWtpbWVkaWEub3JnL3dpa2lwZWRpYS9jb21tb25zL3RodW1iLzUvNTEvT2JqZWN0aXZlX1JldmlzaW9uX0V2YWx1YXRpb25fU2VydmljZV9sb2dvLnN2Zy80MHB4LU9iamVjdGl2ZV9SZXZpc2lvbl9FdmFsdWF0aW9uX1NlcnZpY2VfbG9nby5zdmcucG5nXCIsXHJcblx0XHRcdFx0XHRcdFx0XCJ0aXRsZVwiOiBcIk1hY2hpbmUgcHJlZGljdGVkIHF1YWxpdHkgZnJvbSBPUkVTXCIsXHJcblx0XHRcdFx0XHRcdFx0XCJhbHRcIjogXCJPUkVTIGxvZ29cIixcclxuXHRcdFx0XHRcdFx0XHRcIndpZHRoXCI6IFwiMjBweFwiLFxyXG5cdFx0XHRcdFx0XHRcdFwiaGVpZ2h0XCI6IFwiMjBweFwiXHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KSxcclxuXHRcdFx0XCIgXCIsXHJcblx0XHRcdCQoXCI8c3BhbiBjbGFzcz0nb3Jlc1ByZWRpY3Rpb24nPlwiKVxyXG5cdFx0KVxyXG5cdH0pLnRvZ2dsZShmYWxzZSk7XHJcblx0dGhpcy5wYWdldHlwZUxhYmVsID0gbmV3IE9PLnVpLkxhYmVsV2lkZ2V0KHtcclxuXHRcdCRlbGVtZW50OiAkKFwiPHNwYW4gc3R5bGU9J2Zsb2F0OnJpZ2h0OyBwYWRkaW5nOiAxMHB4OyBtYXgtd2lkdGg6IDMzLjMzJTsgdGV4dC1hbGlnbjogY2VudGVyOyc+XCIpXHJcblx0fSkudG9nZ2xlKGZhbHNlKTtcclxuXHR0aGlzLiRmb290LnByZXBlbmQodGhpcy5vcmVzTGFiZWwuJGVsZW1lbnQsIHRoaXMucGFnZXR5cGVMYWJlbC4kZWxlbWVudCk7XHJcblxyXG5cdC8qIC0tLSBDT05URU5UIEFSRUEgLS0tICovXHJcblxyXG5cdC8vIEJhbm5lcnMgYWRkZWQgZHluYW1pY2FsbHkgdXBvbiBvcGVuaW5nLCBzbyBqdXN0IG5lZWQgYSBsYXlvdXQgd2l0aCBhbiBlbXB0eSBsaXN0XHJcblx0dGhpcy5iYW5uZXJMaXN0ID0gbmV3IEJhbm5lckxpc3RXaWRnZXQoe1xyXG5cdFx0cHJlZmVyZW5jZXM6IHRoaXMucHJlZmVyZW5jZXNcclxuXHR9KTtcclxuXHR0aGlzLmVkaXRMYXlvdXQgPSBuZXcgT08udWkuUGFuZWxMYXlvdXQoIHtcclxuXHRcdHBhZGRlZDogZmFsc2UsXHJcblx0XHRleHBhbmRlZDogZmFsc2UsXHJcblx0XHQkY29udGVudDogdGhpcy5iYW5uZXJMaXN0LiRlbGVtZW50XHJcblx0fSApO1xyXG5cclxuXHQvLyBQcmVmZXJlbmNlcywgZmlsbGVkIGluIHdpdGggY3VycmVudCBwcmVmcyB1cG9uIGxvYWRpbmcuXHJcblx0Ly8gVE9ETzogTWFrZSB0aGlzIGludG8gYSBjb21wb25lbnQsIGFkZCBmaWVsZHMgYW5kIGlucHV0c1xyXG5cdHRoaXMucHJlZnNGb3JtID0gbmV3IFByZWZzRm9ybVdpZGdldCgpO1xyXG5cdHRoaXMucHJlZnNMYXlvdXQgPSBuZXcgT08udWkuUGFuZWxMYXlvdXQoIHtcclxuXHRcdHBhZGRlZDogdHJ1ZSxcclxuXHRcdGV4cGFuZGVkOiBmYWxzZSxcclxuXHRcdCRjb250ZW50OiB0aGlzLnByZWZzRm9ybS4kZWxlbWVudFxyXG5cdH0gKTtcclxuXHJcblx0Ly8gUHJldmlldywgU2hvdyBjaGFuZ2VzXHJcblx0dGhpcy5wYXJzZWRDb250ZW50Q29udGFpbmVyID0gbmV3IE9PLnVpLkZpZWxkc2V0TGF5b3V0KCB7XHJcblx0XHRsYWJlbDogXCJQcmV2aWV3XCJcclxuXHR9ICk7XHJcblx0dGhpcy5wYXJzZWRDb250ZW50V2lkZ2V0ID0gbmV3IE9PLnVpLkxhYmVsV2lkZ2V0KCB7bGFiZWw6IFwiXCIsXHQkZWxlbWVudDokKFwiPGRpdj5cIilcdH0pO1xyXG5cdHRoaXMucGFyc2VkQ29udGVudENvbnRhaW5lci5hZGRJdGVtcyhbXHJcblx0XHRuZXcgT08udWkuRmllbGRMYXlvdXQoXHJcblx0XHRcdHRoaXMucGFyc2VkQ29udGVudFdpZGdldCxcdFx0XHRcclxuXHRcdFx0eyBhbGlnbjogXCJ0b3BcIiB9XHJcblx0XHQpXHJcblx0XSk7XHJcblx0dGhpcy5wYXJzZWRDb250ZW50TGF5b3V0ID0gbmV3IE9PLnVpLlBhbmVsTGF5b3V0KCB7XHJcblx0XHRwYWRkZWQ6IHRydWUsXHJcblx0XHRleHBhbmRlZDogZmFsc2UsXHJcblx0XHQkY29udGVudDogdGhpcy5wYXJzZWRDb250ZW50Q29udGFpbmVyLiRlbGVtZW50XHJcblx0fSApO1xyXG5cclxuXHR0aGlzLmNvbnRlbnRBcmVhID0gbmV3IE9PLnVpLlN0YWNrTGF5b3V0KCB7XHJcblx0XHRpdGVtczogW1xyXG5cdFx0XHR0aGlzLmVkaXRMYXlvdXQsXHJcblx0XHRcdHRoaXMucHJlZnNMYXlvdXQsXHJcblx0XHRcdHRoaXMucGFyc2VkQ29udGVudExheW91dFxyXG5cdFx0XSxcclxuXHRcdHBhZGRlZDogZmFsc2UsXHJcblx0XHRleHBhbmRlZDogZmFsc2VcclxuXHR9ICk7XHJcblxyXG5cdHRoaXMuJGJvZHkuY3NzKHtcInRvcFwiOlwiNzNweFwifSkuYXBwZW5kKHRoaXMuY29udGVudEFyZWEuJGVsZW1lbnQpO1xyXG5cclxuXHQvKiAtLS0gRVZFTlQgSEFORExJTkcgLS0tICovXHJcblxyXG5cdHRoaXMudG9wQmFyLmNvbm5lY3QodGhpcywge1xyXG5cdFx0XCJzZWFyY2hTZWxlY3RcIjogXCJvblNlYXJjaFNlbGVjdFwiLFxyXG5cdFx0XCJzZXRDbGFzc2VzXCI6IFwib25TZXRDbGFzc2VzXCIsXHJcblx0XHRcInNldEltcG9ydGFuY2VzXCI6IFwib25TZXRJbXBvcnRhbmNlc1wiLFxyXG5cdFx0XCJyZW1vdmVBbGxcIjogXCJvblJlbW92ZUFsbFwiLFxyXG5cdFx0XCJjbGVhckFsbFwiOiBcIm9uQ2xlYXJBbGxcIlxyXG5cdH0pO1xyXG5cdHRoaXMuYmFubmVyTGlzdC5jb25uZWN0KHRoaXMsIHtcInVwZGF0ZWRTaXplXCI6IFwib25CYW5uZXJMaXN0VXBkYXRlU2l6ZVwifSk7XHJcblxyXG5cdC8vIEhhbmRsZSBjZXJ0YWluIGtleWJvYXJkIGV2ZW50cy4gUmVxdWlyZXMgc29tZXRoaW5nIGluIHRoZSBSYXRlciB3aW5kb3cgdG8gYmUgZm9jdXNlZCxcclxuXHQvLyBzbyBhZGQgYSB0YWJpbmRleCB0byB0aGUgYm9keSBhbmQgaXQncyBwYXJlbnQgY29udGFpbmVyLlxyXG5cdHRoaXMuJGJvZHkuYXR0cihcInRhYmluZGV4XCIsIFwiOTk5XCIpXHJcblx0XHQucGFyZW50KCkuYXR0cihcInRhYmluZGV4XCIsIFwiOTk5XCIpLmtleWRvd24oZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cdFx0XHRsZXQgc2Nyb2xsQW1vdW50O1xyXG5cdFx0XHRzd2l0Y2goZXZlbnQud2hpY2gpIHtcclxuXHRcdFx0Y2FzZSAzMzogLy8gcGFnZSB1cFxyXG5cdFx0XHRcdHNjcm9sbEFtb3VudCA9IHRoaXMuJGJvZHkuc2Nyb2xsVG9wKCkgLSB0aGlzLiRib2R5LmhlaWdodCgpKjAuOTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0Y2FzZSAzNDogLy8gcGFnZSBkb3duXHJcblx0XHRcdFx0c2Nyb2xsQW1vdW50ID0gdGhpcy4kYm9keS5zY3JvbGxUb3AoKSArIHRoaXMuJGJvZHkuaGVpZ2h0KCkqMC45O1xyXG5cdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRkZWZhdWx0OlxyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHR0aGlzLiRib2R5LnNjcm9sbFRvcChzY3JvbGxBbW91bnQpO1xyXG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0fS5iaW5kKHRoaXMpKTtcclxuXHJcblx0dGhpcy5wcmVmc0Zvcm0uY29ubmVjdCh0aGlzLCB7XCJyZXNldENhY2hlXCI6IFwib25SZXNldENhY2hlXCJ9KTtcclxuXHRcclxufTtcclxuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLm9uQmFubmVyTGlzdFVwZGF0ZVNpemUgPSBmdW5jdGlvbigpIHtcclxuXHQvLyBHZXQgdGhlIGN1cnJlbnQgc2Nyb2xsIGFtb3VudFxyXG5cdGNvbnN0IHNjcm9sbEFtb3VudCA9IHRoaXMuJGJvZHkuc2Nyb2xsVG9wKCk7XHJcblx0Ly8gVXBkYXRlIHNpemUgKHdoaWNoIHJlc2V0cyB0aGUgc2Nyb2xsIHRvIDApXHJcblx0dGhpcy51cGRhdGVTaXplKCk7XHJcblx0Ly8gU2Nyb2xsIHRvIHdoZXJlIGl0IHdhcyBiZWZvcmVcclxuXHR0aGlzLiRib2R5LnNjcm9sbFRvcChzY3JvbGxBbW91bnQpO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUubWFrZURyYWdnYWJsZSA9IGZ1bmN0aW9uKCkge1xyXG5cdGxldCAkZnJhbWVFbCA9IHRoaXMuJGVsZW1lbnQuZmluZChcIi5vby11aS13aW5kb3ctZnJhbWVcIik7XHJcblx0bGV0ICRoYW5kbGVFbCA9IHRoaXMuJGVsZW1lbnQuZmluZChcIi5vby11aS1wcm9jZXNzRGlhbG9nLWxvY2F0aW9uXCIpLmNzcyh7XCJjdXJzb3JcIjpcIm1vdmVcIn0pO1xyXG5cdC8vIFBvc2l0aW9uIGZvciBjc3MgdHJhbnNsYXRlIHRyYW5zZm9ybWF0aW9ucywgcmVsYXRpdmUgdG8gaW5pdGlhbCBwb3NpdGlvblxyXG5cdC8vICh3aGljaCBpcyBjZW50ZXJlZCBvbiB2aWV3cG9ydCB3aGVuIHNjcm9sbGVkIHRvIHRvcClcclxuXHRsZXQgcG9zaXRpb24gPSB7IHg6IDAsIHk6IDAgfTtcclxuXHRjb25zdCBjb25zdHJhaW4gPSBmdW5jdGlvbih2YWwsIG1pblZhbCwgbWF4VmFsKSB7XHJcblx0XHRpZiAodmFsIDwgbWluVmFsKSByZXR1cm4gbWluVmFsO1xyXG5cdFx0aWYgKHZhbCA+IG1heFZhbCkgcmV0dXJuIG1heFZhbDtcclxuXHRcdHJldHVybiB2YWw7XHJcblx0fTtcclxuXHRjb25zdCBjb25zdHJhaW5YID0gKHZhbCkgPT4ge1xyXG5cdFx0Ly8gRG9uJ3QgdG9vIGZhciBob3Jpem9udGFsbHkgKGxlYXZlIGF0IGxlYXN0IDEwMHB4IHZpc2libGUpXHJcblx0XHRsZXQgbGltaXQgPSB3aW5kb3cuaW5uZXJXaWR0aC8yICsgJGZyYW1lRWwub3V0ZXJXaWR0aCgpLzIgLSAxMDA7XHJcblx0XHRyZXR1cm4gY29uc3RyYWluKHZhbCwgLTEqbGltaXQsIGxpbWl0KTtcclxuXHR9O1xyXG5cdGNvbnN0IGNvbnN0cmFpblkgPSAodmFsKSA9PiB7XHJcblx0XHQvLyBDYW4ndCB0YWtlIHRpdGxlIGJhciBvZmYgdGhlIHZpZXdwb3J0LCBzaW5jZSBpdCdzIHRoZSBkcmFnIGhhbmRsZVxyXG5cdFx0bGV0IG1pbkxpbWl0ID0gLTEqKHdpbmRvdy5pbm5lckhlaWdodCAtICRmcmFtZUVsLm91dGVySGVpZ2h0KCkpLzI7XHJcblx0XHQvLyBEb24ndCBnbyB0b28gZmFyIGRvd24gdGhlIHBhZ2U6ICh3aG9sZSBwYWdlIGhlaWdodCkgLSAoaW5pdGlhbCBwb3NpdGlvbilcclxuXHRcdGxldCBtYXhMaW1pdCA9IChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnR8fGRvY3VtZW50KS5zY3JvbGxIZWlnaHQgLSB3aW5kb3cuaW5uZXJIZWlnaHQvMjtcclxuXHRcdHJldHVybiBjb25zdHJhaW4odmFsLCBtaW5MaW1pdCwgbWF4TGltaXQpO1xyXG5cdH07XHJcblxyXG5cdGxldCBwb2ludGVyZG93biA9IGZhbHNlO1xyXG5cdGxldCBkcmFnRnJvbSA9IHt9O1xyXG5cclxuXHRsZXQgb25EcmFnU3RhcnQgPSBldmVudCA9PiB7XHJcblx0XHRwb2ludGVyZG93biA9IHRydWU7XHJcblx0XHRkcmFnRnJvbS54ID0gZXZlbnQuY2xpZW50WDtcclxuXHRcdGRyYWdGcm9tLnkgPSBldmVudC5jbGllbnRZO1xyXG5cdH07XHJcblx0bGV0IG9uRHJhZ01vdmUgPSBldmVudCA9PiB7XHJcblx0XHRpZiAoIXBvaW50ZXJkb3duIHx8IGRyYWdGcm9tLnggPT0gbnVsbCB8fCBkcmFnRnJvbS55ID09PSBudWxsKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGR4ID0gZXZlbnQuY2xpZW50WCAtIGRyYWdGcm9tLng7XHJcblx0XHRjb25zdCBkeSA9IGV2ZW50LmNsaWVudFkgLSBkcmFnRnJvbS55O1xyXG5cdFx0ZHJhZ0Zyb20ueCA9IGV2ZW50LmNsaWVudFg7XHJcblx0XHRkcmFnRnJvbS55ID0gZXZlbnQuY2xpZW50WTtcclxuXHRcdHBvc2l0aW9uLnggPSBjb25zdHJhaW5YKHBvc2l0aW9uLnggKyBkeCk7XHJcblx0XHRwb3NpdGlvbi55ID0gY29uc3RyYWluWShwb3NpdGlvbi55ICsgZHkpO1xyXG5cdFx0JGZyYW1lRWwuY3NzKFwidHJhbnNmb3JtXCIsIGB0cmFuc2xhdGUoJHtwb3NpdGlvbi54fXB4LCAke3Bvc2l0aW9uLnl9cHgpYCk7XHJcblx0fTtcclxuXHRsZXQgb25EcmFnRW5kID0gKCkgPT4ge1xyXG5cdFx0cG9pbnRlcmRvd24gPSBmYWxzZTtcclxuXHRcdGRlbGV0ZSBkcmFnRnJvbS54O1xyXG5cdFx0ZGVsZXRlIGRyYWdGcm9tLnk7XHJcblx0XHQvLyBNYWtlIHN1cmUgZmluYWwgcG9zaXRpb25zIGFyZSB3aG9sZSBudW1iZXJzXHJcblx0XHRwb3NpdGlvbi54ID0gTWF0aC5yb3VuZChwb3NpdGlvbi54KTtcclxuXHRcdHBvc2l0aW9uLnkgPSBNYXRoLnJvdW5kKHBvc2l0aW9uLnkpO1xyXG5cdFx0JGZyYW1lRWwuY3NzKFwidHJhbnNmb3JtXCIsIGB0cmFuc2xhdGUoJHtwb3NpdGlvbi54fXB4LCAke3Bvc2l0aW9uLnl9cHgpYCk7XHJcblx0fTtcclxuXHJcblx0Ly8gVXNlIHBvaW50ZXIgZXZlbnRzIGlmIGF2YWlsYWJsZTsgb3RoZXJ3aXNlIHVzZSBtb3VzZSBldmVudHNcclxuXHRjb25zdCBwb2ludGVyID0gKFwiUG9pbnRlckV2ZW50XCIgaW4gd2luZG93KSA/IFwicG9pbnRlclwiIDogXCJtb3VzZVwiO1xyXG5cdCRoYW5kbGVFbC5vbihwb2ludGVyK1wiZW50ZXIucmF0ZXJNYWluV2luXCIsICgpID0+ICRmcmFtZUVsLmNzcyhcIndpbGwtY2hhbmdlXCIsIFwidHJhbnNmb3JtXCIpICk7IC8vIFRlbGwgYnJvd3NlciB0byBvcHRpbWlzZSB0cmFuc2Zvcm1cclxuXHQkaGFuZGxlRWwub24ocG9pbnRlcitcImxlYXZlLnJhdGVyTWFpbldpblwiLCAoKSA9PiB7IGlmICghcG9pbnRlcmRvd24pICRmcmFtZUVsLmNzcyhcIndpbGwtY2hhbmdlXCIsIFwiXCIpOyB9ICk7IC8vIFJlbW92ZSBvcHRpbWlzYXRpb24gaWYgbm90IGRyYWdnaW5nXHJcblx0JGhhbmRsZUVsLm9uKHBvaW50ZXIrXCJkb3duLnJhdGVyTWFpbldpblwiLCBvbkRyYWdTdGFydCk7XHJcblx0JChcImJvZHlcIikub24ocG9pbnRlcitcIm1vdmUucmF0ZXJNYWluV2luXCIsIG9uRHJhZ01vdmUpO1xyXG5cdCQoXCJib2R5XCIpLm9uKHBvaW50ZXIrXCJ1cC5yYXRlck1haW5XaW5cIiwgb25EcmFnRW5kKTtcclxufTtcclxuXHJcbi8vIE92ZXJyaWRlIHRoZSBnZXRCb2R5SGVpZ2h0KCkgbWV0aG9kIHRvIHNwZWNpZnkgYSBjdXN0b20gaGVpZ2h0XHJcbk1haW5XaW5kb3cucHJvdG90eXBlLmdldEJvZHlIZWlnaHQgPSBmdW5jdGlvbiAoKSB7XHJcblx0dmFyIGN1cnJlbnRsYXlvdXQgPSB0aGlzLmNvbnRlbnRBcmVhLmdldEN1cnJlbnRJdGVtKCk7XHJcblx0dmFyIGxheW91dEhlaWdodCA9IGN1cnJlbnRsYXlvdXQgJiYgY3VycmVudGxheW91dC4kZWxlbWVudC5vdXRlckhlaWdodCh0cnVlKTtcclxuXHR2YXIgY29udGVudEhlaWdodCA9IGN1cnJlbnRsYXlvdXQgJiYgY3VycmVudGxheW91dC4kZWxlbWVudC5jaGlsZHJlbihcIjpmaXJzdC1jaGlsZFwiKS5vdXRlckhlaWdodCh0cnVlKTtcclxuXHRyZXR1cm4gTWF0aC5tYXgoMjAwLCBsYXlvdXRIZWlnaHQsIGNvbnRlbnRIZWlnaHQpO1xyXG59O1xyXG5cclxuLy8gVXNlIGdldFNldHVwUHJvY2VzcygpIHRvIHNldCB1cCB0aGUgd2luZG93IHdpdGggZGF0YSBwYXNzZWQgdG8gaXQgYXQgdGhlIHRpbWUgXHJcbi8vIG9mIG9wZW5pbmdcclxuTWFpbldpbmRvdy5wcm90b3R5cGUuZ2V0U2V0dXBQcm9jZXNzID0gZnVuY3Rpb24gKCBkYXRhICkge1xyXG5cdGRhdGEgPSBkYXRhIHx8IHt9O1xyXG5cdHJldHVybiBNYWluV2luZG93LnN1cGVyLnByb3RvdHlwZS5nZXRTZXR1cFByb2Nlc3MuY2FsbCggdGhpcywgZGF0YSApXHJcblx0XHQubmV4dCggKCkgPT4ge1xyXG5cdFx0XHR0aGlzLm1ha2VEcmFnZ2FibGUoKTtcclxuXHRcdFx0Ly8gU2V0IHVwIHByZWZlcmVuY2VzXHJcblx0XHRcdHRoaXMuc2V0UHJlZmVyZW5jZXMoZGF0YS5wcmVmZXJlbmNlcyk7XHJcblx0XHRcdHRoaXMucHJlZnNGb3JtLnNldFByZWZWYWx1ZXMoZGF0YS5wcmVmZXJlbmNlcyk7XHJcblx0XHRcdC8vIFNldCBzdWJqZWN0IHBhZ2UgaW5mb1xyXG5cdFx0XHR0aGlzLnN1YmplY3RQYWdlID0gZGF0YS5zdWJqZWN0UGFnZTtcclxuXHRcdFx0dGhpcy5wYWdlSW5mbyA9IHtcclxuXHRcdFx0XHRyZWRpcmVjdDogZGF0YS5yZWRpcmVjdFRhcmdldCxcclxuXHRcdFx0XHRpc0Rpc2FtYmlnOiBkYXRhLmRpc2FtYmlnLFxyXG5cdFx0XHRcdGhhc1N0dWJ0YWc6IGRhdGEuc3R1YnRhZyxcclxuXHRcdFx0XHRpc0FydGljbGU6IGRhdGEuaXNBcnRpY2xlXHJcblx0XHRcdH07XHJcblx0XHRcdC8vIFNldCB1cCBlZGl0IG1vZGUgYmFubmVyc1xyXG5cdFx0XHR0aGlzLmFjdGlvbnMuc2V0TW9kZShcImVkaXRcIik7XHJcblx0XHRcdHRoaXMuYmFubmVyTGlzdC5vcmVzQ2xhc3MgPSAoZGF0YS5pc0FydGljbGUgJiYgZGF0YS5pc0xpc3QpXHJcblx0XHRcdFx0PyBcIkxpc3RcIlxyXG5cdFx0XHRcdDogZGF0YS5vcmVzICYmIGRhdGEub3Jlcy5wcmVkaWN0aW9uO1xyXG5cdFx0XHR0aGlzLmJhbm5lckxpc3QucGFnZUluZm8gPSB0aGlzLnBhZ2VJbmZvO1xyXG5cdFx0XHR0aGlzLmJhbm5lckxpc3QuYWRkSXRlbXMoXHJcblx0XHRcdFx0ZGF0YS5iYW5uZXJzLm1hcCggYmFubmVyVGVtcGxhdGUgPT4gbmV3IEJhbm5lcldpZGdldChcclxuXHRcdFx0XHRcdGJhbm5lclRlbXBsYXRlLFxyXG5cdFx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0XHRwcmVmZXJlbmNlczogdGhpcy5wcmVmZXJlbmNlcyxcclxuXHRcdFx0XHRcdFx0JG92ZXJsYXk6IHRoaXMuJG92ZXJsYXksXHJcblx0XHRcdFx0XHRcdGlzQXJ0aWNsZTogdGhpcy5wYWdlSW5mby5pc0FydGljbGVcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHQpIClcclxuXHRcdFx0KTtcclxuXHRcdFx0bGV0IHNoZWxsVGVtcGxhdGVCYW5uZXIgPSB0aGlzLmJhbm5lckxpc3QuaXRlbXMuZmluZChiYW5uZXIgPT4gYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSk7XHJcblx0XHRcdGlmIChzaGVsbFRlbXBsYXRlQmFubmVyICYmIHNoZWxsVGVtcGxhdGVCYW5uZXIuc2hlbGxQYXJhbTFWYWx1ZSkge1xyXG5cdFx0XHRcdHNoZWxsVGVtcGxhdGVCYW5uZXIubm9uU3RhbmRhcmRUZW1wbGF0ZXMgPSB0aGlzLmJhbm5lckxpc3QuaXRlbXMucmVkdWNlKFxyXG5cdFx0XHRcdFx0KGJhbm5lcnNMaXN0LCBjdXJCYW5uZXIpID0+IGJhbm5lcnNMaXN0LnJlcGxhY2UoY3VyQmFubmVyLndpa2l0ZXh0LCBcIlwiKSxcclxuXHRcdFx0XHRcdHNoZWxsVGVtcGxhdGVCYW5uZXIuc2hlbGxQYXJhbTFWYWx1ZVxyXG5cdFx0XHRcdCkudHJpbSgpLnJlcGxhY2UoL1xcbisvZywgXCJcXG5cIik7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy5iYW5uZXJMaXN0LmFkZFNoZWxsVGVtcGxhdGVJZk5lZWVkZWQoKVxyXG5cdFx0XHRcdC5zeW5jU2hlbGxUZW1wbGF0ZVdpdGhCaW9ncmFwaHlCYW5uZXIoKTtcclxuXHRcdFx0Ly8gU2hvdyBwYWdlIHR5cGUsIG9yIE9SRVMgcHJlZGljdGlvbiwgaWYgYXZhaWxhYmxlXHJcblx0XHRcdGlmICh0aGlzLnBhZ2VJbmZvLnJlZGlyZWN0KSB7XHJcblx0XHRcdFx0dGhpcy5wYWdldHlwZUxhYmVsLnNldExhYmVsKFwiUmVkaXJlY3QgcGFnZVwiKS50b2dnbGUodHJ1ZSk7XHJcblx0XHRcdH0gZWxzZSBpZiAodGhpcy5wYWdlSW5mby5pc0Rpc2FtYmlnKSB7XHJcblx0XHRcdFx0dGhpcy5wYWdldHlwZUxhYmVsLnNldExhYmVsKFwiRGlzYW1iaWd1YXRpb24gcGFnZVwiKS50b2dnbGUodHJ1ZSk7XHJcblx0XHRcdH0gZWxzZSBpZiAodGhpcy5wYWdlSW5mby5pc0FydGljbGUgJiYgZGF0YS5pc0dBKSB7XHJcblx0XHRcdFx0dGhpcy5wYWdldHlwZUxhYmVsLnNldExhYmVsKFwiR29vZCBhcnRpY2xlXCIpLnRvZ2dsZSh0cnVlKTtcclxuXHRcdFx0fSBlbHNlIGlmICh0aGlzLnBhZ2VJbmZvLmlzQXJ0aWNsZSAmJiBkYXRhLmlzRkEpIHtcclxuXHRcdFx0XHR0aGlzLnBhZ2V0eXBlTGFiZWwuc2V0TGFiZWwoXCJGZWF0dXJlZCBhcnRpY2xlXCIpLnRvZ2dsZSh0cnVlKTtcclxuXHRcdFx0fSBlbHNlIGlmICh0aGlzLnBhZ2VJbmZvLmlzQXJ0aWNsZSAmJiBkYXRhLmlzRkwpIHtcclxuXHRcdFx0XHR0aGlzLnBhZ2V0eXBlTGFiZWwuc2V0TGFiZWwoXCJGZWF0dXJlZCBsaXN0XCIpLnRvZ2dsZSh0cnVlKTtcclxuXHRcdFx0fSBlbHNlIGlmICh0aGlzLnBhZ2VJbmZvLmlzQXJ0aWNsZSAmJiBkYXRhLmlzTGlzdCkge1xyXG5cdFx0XHRcdHRoaXMucGFnZXR5cGVMYWJlbC5zZXRMYWJlbChcIkxpc3QgYXJ0aWNsZVwiKS50b2dnbGUodHJ1ZSk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZGF0YS5vcmVzKSB7XHJcblx0XHRcdFx0dGhpcy5vcmVzQ2xhc3MgPSBkYXRhLm9yZXMucHJlZGljdGlvbjtcclxuXHRcdFx0XHR0aGlzLm9yZXNMYWJlbC50b2dnbGUodHJ1ZSkuJGVsZW1lbnQuZmluZChcIi5vcmVzUHJlZGljdGlvblwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcIlByZWRpY3Rpb246IFwiLFxyXG5cdFx0XHRcdFx0JChcIjxzdHJvbmc+XCIpLnRleHQoZGF0YS5vcmVzLnByZWRpY3Rpb24pLFxyXG5cdFx0XHRcdFx0XCImbmJzcDsoXCIgKyBkYXRhLm9yZXMucHJvYmFiaWxpdHkgKyBcIilcIlxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH0gZWxzZSBpZiAodGhpcy5wYWdlSW5mby5pc0FydGljbGUpIHtcclxuXHRcdFx0XHR0aGlzLnBhZ2V0eXBlTGFiZWwuc2V0TGFiZWwoXCJBcnRpY2xlIHBhZ2VcIikudG9nZ2xlKHRydWUpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMucGFnZXR5cGVMYWJlbC5zZXRMYWJlbCggdGhpcy5zdWJqZWN0UGFnZS5nZXROYW1lc3BhY2VQcmVmaXgoKS5zbGljZSgwLC0xKSArIFwiIHBhZ2VcIiApLnRvZ2dsZSh0cnVlKTtcclxuXHRcdFx0fVxyXG5cdFx0XHQvLyBTZXQgcHJvcHMgZm9yIHVzZSBpbiBtYWtpbmcgd2lraXRleHQgYW5kIGVkaXQgc3VtbWFyaWVzXHJcblx0XHRcdHRoaXMudGFsa1dpa2l0ZXh0ID0gZGF0YS50YWxrV2lraXRleHQ7XHJcblx0XHRcdHRoaXMuZXhpc3RpbmdCYW5uZXJOYW1lcyA9IGRhdGEuYmFubmVycy5tYXAoIGJhbm5lclRlbXBsYXRlID0+IGJhbm5lclRlbXBsYXRlLm5hbWUgKTtcclxuXHRcdFx0dGhpcy50YWxrcGFnZSA9IGRhdGEudGFsa3BhZ2U7XHJcblx0XHRcdC8vIEZvcmNlIGEgc2l6ZSB1cGRhdGUgdG8gZW5zdXJlIGV2ZXl0aGluZyBmaXRzIG9rYXlcclxuXHRcdFx0dGhpcy51cGRhdGVTaXplKCk7XHJcblx0XHR9LCB0aGlzICk7XHJcbn07XHJcblxyXG4vLyBTZXQgdXAgdGhlIHdpbmRvdyBpdCBpcyByZWFkeTogYXR0YWNoZWQgdG8gdGhlIERPTSwgYW5kIG9wZW5pbmcgYW5pbWF0aW9uIGNvbXBsZXRlZFxyXG5NYWluV2luZG93LnByb3RvdHlwZS5nZXRSZWFkeVByb2Nlc3MgPSBmdW5jdGlvbiAoIGRhdGEgKSB7XHJcblx0ZGF0YSA9IGRhdGEgfHwge307XHJcblx0cmV0dXJuIE1haW5XaW5kb3cuc3VwZXIucHJvdG90eXBlLmdldFJlYWR5UHJvY2Vzcy5jYWxsKCB0aGlzLCBkYXRhIClcclxuXHRcdC5uZXh0KCAoKSA9PiB0aGlzLnRvcEJhci5zZWFyY2hCb3guZm9jdXMoKSApO1xyXG59O1xyXG5cclxuLy8gVXNlIHRoZSBnZXRBY3Rpb25Qcm9jZXNzKCkgbWV0aG9kIHRvIGRvIHRoaW5ncyB3aGVuIGFjdGlvbnMgYXJlIGNsaWNrZWRcclxuTWFpbldpbmRvdy5wcm90b3R5cGUuZ2V0QWN0aW9uUHJvY2VzcyA9IGZ1bmN0aW9uICggYWN0aW9uICkge1xyXG5cdGlmICggYWN0aW9uID09PSBcInNob3dQcmVmc1wiICkge1xyXG5cdFx0dGhpcy5hY3Rpb25zLnNldE1vZGUoXCJwcmVmc1wiKTtcclxuXHRcdHRoaXMuY29udGVudEFyZWEuc2V0SXRlbSggdGhpcy5wcmVmc0xheW91dCApO1xyXG5cdFx0dGhpcy50b3BCYXIuc2V0RGlzYWJsZWQodHJ1ZSk7XHJcblx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHJcblx0fSBlbHNlIGlmICggYWN0aW9uID09PSBcInNhdmVQcmVmc1wiICkge1xyXG5cdFx0dmFyIHVwZGF0ZWRQcmVmcyA9IHRoaXMucHJlZnNGb3JtLmdldFByZWZzKCk7XHJcblx0XHRyZXR1cm4gbmV3IE9PLnVpLlByb2Nlc3MoKS5uZXh0KFxyXG5cdFx0XHRBcGlTZXRQcmVmcyh1cGRhdGVkUHJlZnMpLnRoZW4oXHJcblx0XHRcdFx0Ly8gU3VjY2Vzc1xyXG5cdFx0XHRcdCgpID0+IHtcclxuXHRcdFx0XHRcdHRoaXMuc2V0UHJlZmVyZW5jZXModXBkYXRlZFByZWZzKTtcclxuXHRcdFx0XHRcdHRoaXMuYWN0aW9ucy5zZXRNb2RlKFwiZWRpdFwiKTtcclxuXHRcdFx0XHRcdHRoaXMuY29udGVudEFyZWEuc2V0SXRlbSggdGhpcy5lZGl0TGF5b3V0ICk7XHJcblx0XHRcdFx0XHR0aGlzLnRvcEJhci5zZXREaXNhYmxlZChmYWxzZSk7XHJcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdC8vIEZhaWx1cmVcclxuXHRcdFx0XHQoY29kZSwgZXJyKSA9PiAkLkRlZmVycmVkKCkucmVqZWN0KFxyXG5cdFx0XHRcdFx0bmV3IE9PLnVpLkVycm9yKFxyXG5cdFx0XHRcdFx0XHQkKFwiPGRpdj5cIikuYXBwZW5kKFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nIHN0eWxlPSdkaXNwbGF5OmJsb2NrOyc+XCIpLnRleHQoXCJDb3VsZCBub3Qgc2F2ZSBwcmVmZXJlbmNlcy5cIiksXHJcblx0XHRcdFx0XHRcdFx0JChcIjxzcGFuIHN0eWxlPSdjb2xvcjojNzc3Jz5cIikudGV4dCggbWFrZUVycm9yTXNnKGNvZGUsIGVycikgKVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KVxyXG5cdFx0XHQpXHJcblx0XHQpO1xyXG5cclxuXHR9IGVsc2UgaWYgKCBhY3Rpb24gPT09IFwiY2xlYXJDYWNoZVwiICkge1xyXG5cdFx0cmV0dXJuIG5ldyBPTy51aS5Qcm9jZXNzKCkubmV4dCgoKSA9PiB7XHJcblx0XHRcdGNhY2hlLmNsZWFyQWxsSXRlbXMoKTtcclxuXHRcdFx0dGhpcy5jbG9zZSh7cmVzdGFydDogdHJ1ZX0pO1xyXG5cdFx0fSk7XHJcblxyXG5cclxuXHR9IGVsc2UgaWYgKCBhY3Rpb24gPT09IFwiY2xvc2VQcmVmc1wiICkge1xyXG5cdFx0dGhpcy5hY3Rpb25zLnNldE1vZGUoXCJlZGl0XCIpO1xyXG5cdFx0dGhpcy5jb250ZW50QXJlYS5zZXRJdGVtKCB0aGlzLmVkaXRMYXlvdXQgKTtcclxuXHRcdHRoaXMudG9wQmFyLnNldERpc2FibGVkKGZhbHNlKTtcclxuXHRcdHRoaXMucHJlZnNGb3JtLnNldFByZWZWYWx1ZXModGhpcy5wcmVmZXJlbmNlcyk7XHJcblx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHJcblx0fSBlbHNlIGlmICggYWN0aW9uID09PSBcInNhdmVcIiApIHtcclxuXHRcdHJldHVybiBuZXcgT08udWkuUHJvY2VzcygpLm5leHQoXHJcblx0XHRcdEFQSS5lZGl0V2l0aFJldHJ5KFxyXG5cdFx0XHRcdHRoaXMudGFsa3BhZ2UuZ2V0UHJlZml4ZWRUZXh0KCksXHJcblx0XHRcdFx0e3J2c2VjdGlvbjogMH0sXHJcblx0XHRcdFx0cmV2aXNpb24gPT4gKHtcclxuXHRcdFx0XHRcdHNlY3Rpb246IDAsXHJcblx0XHRcdFx0XHR0ZXh0OiB0aGlzLnRyYW5zZm9ybVRhbGtXaWtpdGV4dChyZXZpc2lvbi5jb250ZW50KSxcclxuXHRcdFx0XHRcdHN1bW1hcnk6IHRoaXMubWFrZUVkaXRTdW1tYXJ5KCksXHJcblx0XHRcdFx0XHR3YXRjaGxpc3Q6IHRoaXMucHJlZmVyZW5jZXMud2F0Y2hsaXN0XHJcblx0XHRcdFx0fSlcclxuXHRcdFx0KS5jYXRjaCgoY29kZSwgZXJyKSA9PiAkLkRlZmVycmVkKCkucmVqZWN0KFxyXG5cdFx0XHRcdG5ldyBPTy51aS5FcnJvcihcclxuXHRcdFx0XHRcdCQoXCI8ZGl2PlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nIHN0eWxlPSdkaXNwbGF5OmJsb2NrOyc+XCIpLnRleHQoXCJDb3VsZCBub3Qgc2F2ZSB5b3VyIGNoYW5nZXMuXCIpLFxyXG5cdFx0XHRcdFx0XHQkKFwiPHNwYW4gc3R5bGU9J2NvbG9yOiM3NzcnPlwiKS50ZXh0KCBtYWtlRXJyb3JNc2coY29kZSwgZXJyKSApXHJcblx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KVxyXG5cdFx0XHQpIClcclxuXHRcdCkubmV4dCggKCkgPT4gdGhpcy5jbG9zZSh7XHJcblx0XHRcdHN1Y2Nlc3M6IHRydWUsXHJcblx0XHRcdHVwZ3JhZGVkU3R1YjogdGhpcy5wYWdlSW5mby5oYXNTdHVidGFnICYmIHRoaXMuaXNSYXRlZEFuZE5vdFN0dWIoKVxyXG5cdFx0fSkgKTtcclxuXHJcblx0fSBlbHNlIGlmICggYWN0aW9uID09PSBcInByZXZpZXdcIiApIHtcclxuXHRcdHJldHVybiBuZXcgT08udWkuUHJvY2VzcygpLm5leHQoXHJcblx0XHRcdEFQSS5wb3N0KHtcclxuXHRcdFx0XHRhY3Rpb246IFwicGFyc2VcIixcclxuXHRcdFx0XHRjb250ZW50bW9kZWw6IFwid2lraXRleHRcIixcclxuXHRcdFx0XHR0ZXh0OiB0aGlzLnRyYW5zZm9ybVRhbGtXaWtpdGV4dCh0aGlzLnRhbGtXaWtpdGV4dCkgKyBcIlxcbjxocj5cXG5cIiArIFwiJycnRWRpdCBzdW1tYXJ5OicnJyBcIiArIHRoaXMubWFrZUVkaXRTdW1tYXJ5KCksXHJcblx0XHRcdFx0dGl0bGU6IHRoaXMudGFsa3BhZ2UuZ2V0UHJlZml4ZWRUZXh0KCksXHJcblx0XHRcdFx0cHN0OiAxXHJcblx0XHRcdH0pLnRoZW4oIHJlc3VsdCA9PiB7XHJcblx0XHRcdFx0aWYgKCAhcmVzdWx0IHx8ICFyZXN1bHQucGFyc2UgfHwgIXJlc3VsdC5wYXJzZS50ZXh0IHx8ICFyZXN1bHQucGFyc2UudGV4dFtcIipcIl0gKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlamVjdChcIkVtcHR5IHJlc3VsdFwiKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dmFyIHByZXZpZXdIdG1sU25pcHBldCA9IG5ldyBPTy51aS5IdG1sU25pcHBldChyZXN1bHQucGFyc2UudGV4dFtcIipcIl0pO1xyXG5cclxuXHRcdFx0XHR0aGlzLnBhcnNlZENvbnRlbnRXaWRnZXQuc2V0TGFiZWwocHJldmlld0h0bWxTbmlwcGV0KTtcclxuXHRcdFx0XHR0aGlzLnBhcnNlZENvbnRlbnRDb250YWluZXIuc2V0TGFiZWwoXCJQcmV2aWV3OlwiKTtcclxuXHRcdFx0XHR0aGlzLmFjdGlvbnMuc2V0TW9kZShcInByZXZpZXdcIik7XHJcblx0XHRcdFx0dGhpcy5jb250ZW50QXJlYS5zZXRJdGVtKCB0aGlzLnBhcnNlZENvbnRlbnRMYXlvdXQgKTtcclxuXHRcdFx0XHR0aGlzLnRvcEJhci5zZXREaXNhYmxlZCh0cnVlKTtcclxuXHRcdFx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHRcdFx0fSlcclxuXHRcdFx0XHQuY2F0Y2goIChjb2RlLCBlcnIpID0+ICQuRGVmZXJyZWQoKS5yZWplY3QoXHJcblx0XHRcdFx0XHRuZXcgT08udWkuRXJyb3IoXHJcblx0XHRcdFx0XHRcdCQoXCI8ZGl2PlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdFx0JChcIjxzdHJvbmcgc3R5bGU9J2Rpc3BsYXk6YmxvY2s7Jz5cIikudGV4dChcIkNvdWxkIG5vdCBzaG93IGNoYW5nZXMuXCIpLFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8c3BhbiBzdHlsZT0nY29sb3I6Izc3Nyc+XCIpLnRleHQoIG1ha2VFcnJvck1zZyhjb2RlLCBlcnIpIClcclxuXHRcdFx0XHRcdFx0KVxyXG5cdFx0XHRcdFx0KVxyXG5cdFx0XHRcdCkgKVxyXG5cdFx0KTtcclxuXHJcblx0fSBlbHNlIGlmICggYWN0aW9uID09PSBcImNoYW5nZXNcIiApIHtcclxuXHRcdHJldHVybiBuZXcgT08udWkuUHJvY2VzcygpLm5leHQoXHJcblx0XHRcdEFQSS5wb3N0KHtcclxuXHRcdFx0XHRhY3Rpb246IFwiY29tcGFyZVwiLFxyXG5cdFx0XHRcdGZvcm1hdDogXCJqc29uXCIsXHJcblx0XHRcdFx0ZnJvbXRleHQ6IHRoaXMudGFsa1dpa2l0ZXh0LFxyXG5cdFx0XHRcdGZyb21jb250ZW50bW9kZWw6IFwid2lraXRleHRcIixcclxuXHRcdFx0XHR0b3RleHQ6IHRoaXMudHJhbnNmb3JtVGFsa1dpa2l0ZXh0KHRoaXMudGFsa1dpa2l0ZXh0KSxcclxuXHRcdFx0XHR0b2NvbnRlbnRtb2RlbDogXCJ3aWtpdGV4dFwiLFxyXG5cdFx0XHRcdHByb3A6IFwiZGlmZlwiXHJcblx0XHRcdH0pXHJcblx0XHRcdFx0LnRoZW4oIHJlc3VsdCA9PiB7XHJcblx0XHRcdFx0XHRpZiAoICFyZXN1bHQgfHwgIXJlc3VsdC5jb21wYXJlIHx8ICFyZXN1bHQuY29tcGFyZVtcIipcIl0gKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVqZWN0KFwiRW1wdHkgcmVzdWx0XCIpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0dmFyICRkaWZmID0gJChcIjx0YWJsZT5cIikuYWRkQ2xhc3MoXCJkaWZmXCIpLmNzcyhcIndpZHRoXCIsIFwiMTAwJVwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdCQoXCI8dHI+XCIpLmFwcGVuZChcclxuXHRcdFx0XHRcdFx0XHQkKFwiPHRoPlwiKS5hdHRyKHtcImNvbHNwYW5cIjpcIjJcIiwgXCJzY29wZVwiOlwiY29sXCJ9KS5jc3MoXCJ3aWR0aFwiLCBcIjUwJVwiKS50ZXh0KFwiTGF0ZXN0IHJldmlzaW9uXCIpLFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8dGg+XCIpLmF0dHIoe1wiY29sc3BhblwiOlwiMlwiLCBcInNjb3BlXCI6XCJjb2xcIn0pLmNzcyhcIndpZHRoXCIsIFwiNTAlXCIpLnRleHQoXCJOZXcgdGV4dFwiKVxyXG5cdFx0XHRcdFx0XHQpLFxyXG5cdFx0XHRcdFx0XHRyZXN1bHQuY29tcGFyZVtcIipcIl0sXHJcblx0XHRcdFx0XHRcdCQoXCI8dGZvb3Q+XCIpLmFwcGVuZChcclxuXHRcdFx0XHRcdFx0XHQkKFwiPHRyPlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdFx0XHQkKFwiPHRkIGNvbHNwYW49JzQnPlwiKS5hcHBlbmQoXHJcblx0XHRcdFx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nPlwiKS50ZXh0KFwiRWRpdCBzdW1tYXJ5OiBcIiksXHJcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMubWFrZUVkaXRTdW1tYXJ5KClcclxuXHRcdFx0XHRcdFx0XHRcdClcclxuXHRcdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XHRcdClcclxuXHRcdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRcdFx0dGhpcy5wYXJzZWRDb250ZW50V2lkZ2V0LnNldExhYmVsKCRkaWZmKTtcclxuXHRcdFx0XHRcdHRoaXMucGFyc2VkQ29udGVudENvbnRhaW5lci5zZXRMYWJlbChcIkNoYW5nZXM6XCIpO1xyXG5cdFx0XHRcdFx0dGhpcy5hY3Rpb25zLnNldE1vZGUoXCJkaWZmXCIpO1xyXG5cdFx0XHRcdFx0dGhpcy5jb250ZW50QXJlYS5zZXRJdGVtKCB0aGlzLnBhcnNlZENvbnRlbnRMYXlvdXQgKTtcclxuXHRcdFx0XHRcdHRoaXMudG9wQmFyLnNldERpc2FibGVkKHRydWUpO1xyXG5cdFx0XHRcdFx0dGhpcy51cGRhdGVTaXplKCk7XHJcblx0XHRcdFx0fSApXHJcblx0XHRcdFx0LmNhdGNoKCAoY29kZSwgZXJyKSA9PiAkLkRlZmVycmVkKCkucmVqZWN0KFxyXG5cdFx0XHRcdFx0bmV3IE9PLnVpLkVycm9yKFxyXG5cdFx0XHRcdFx0XHQkKFwiPGRpdj5cIikuYXBwZW5kKFxyXG5cdFx0XHRcdFx0XHRcdCQoXCI8c3Ryb25nIHN0eWxlPSdkaXNwbGF5OmJsb2NrOyc+XCIpLnRleHQoXCJDb3VsZCBub3Qgc2hvdyBjaGFuZ2VzLlwiKSxcclxuXHRcdFx0XHRcdFx0XHQkKFwiPHNwYW4gc3R5bGU9J2NvbG9yOiM3NzcnPlwiKS50ZXh0KCBtYWtlRXJyb3JNc2coY29kZSwgZXJyKSApXHJcblx0XHRcdFx0XHRcdClcclxuXHRcdFx0XHRcdClcclxuXHRcdFx0XHQpIClcclxuXHRcdCk7XHJcblxyXG5cdH0gZWxzZSBpZiAoIGFjdGlvbiA9PT0gXCJiYWNrXCIgKSB7XHJcblx0XHR0aGlzLmFjdGlvbnMuc2V0TW9kZShcImVkaXRcIik7XHJcblx0XHR0aGlzLmNvbnRlbnRBcmVhLnNldEl0ZW0oIHRoaXMuZWRpdExheW91dCApO1xyXG5cdFx0dGhpcy50b3BCYXIuc2V0RGlzYWJsZWQoZmFsc2UpO1xyXG5cdFx0dGhpcy51cGRhdGVTaXplKCk7XHJcblxyXG5cdH0gZWxzZSBpZiAoIWFjdGlvbiAmJiB0aGlzLmJhbm5lckxpc3QuY2hhbmdlZCkge1xyXG5cdFx0Ly8gQ29uZmlybSBjbG9zaW5nIG9mIGRpYWxvZyBpZiB0aGVyZSBoYXZlIGJlZW4gY2hhbmdlcyBcclxuXHRcdHJldHVybiBuZXcgT08udWkuUHJvY2VzcygpLm5leHQoXHJcblx0XHRcdE9PLnVpLmNvbmZpcm0oXCJDaGFuZ2VzIG1hZGUgd2lsbCBiZSBkaXNjYXJkZWQuXCIsIHt0aXRsZTpcIkNsb3NlIFJhdGVyP1wifSlcclxuXHRcdFx0XHQudGhlbihjb25maXJtZWQgPT4gY29uZmlybWVkID8gdGhpcy5jbG9zZSgpIDogbnVsbClcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gTWFpbldpbmRvdy5zdXBlci5wcm90b3R5cGUuZ2V0QWN0aW9uUHJvY2Vzcy5jYWxsKCB0aGlzLCBhY3Rpb24gKTtcclxufTtcclxuXHJcbi8vIFVzZSB0aGUgZ2V0VGVhcmRvd25Qcm9jZXNzKCkgbWV0aG9kIHRvIHBlcmZvcm0gYWN0aW9ucyB3aGVuZXZlciB0aGUgZGlhbG9nIGlzIGNsb3NlZC5cclxuLy8gYGRhdGFgIGlzIHRoZSBkYXRhIHBhc3NlZCBpbnRvIHRoZSB3aW5kb3cncyAuY2xvc2UoKSBtZXRob2QuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLmdldFRlYXJkb3duUHJvY2VzcyA9IGZ1bmN0aW9uICggZGF0YSApIHtcclxuXHRyZXR1cm4gTWFpbldpbmRvdy5zdXBlci5wcm90b3R5cGUuZ2V0VGVhcmRvd25Qcm9jZXNzLmNhbGwoIHRoaXMsIGRhdGEgKVxyXG5cdFx0LmZpcnN0KCAoKSA9PiB7XHJcblx0XHRcdHRoaXMuYmFubmVyTGlzdC5jbGVhckl0ZW1zKCk7XHJcblx0XHRcdHRoaXMudG9wQmFyLnNlYXJjaEJveC5zZXRWYWx1ZShcIlwiKTtcclxuXHRcdFx0dGhpcy5jb250ZW50QXJlYS5zZXRJdGVtKCB0aGlzLmVkaXRMYXlvdXQgKTtcclxuXHRcdFx0dGhpcy50b3BCYXIuc2V0RGlzYWJsZWQoZmFsc2UpO1xyXG5cdFx0XHR0aGlzLm9yZXNMYWJlbC50b2dnbGUoZmFsc2UpLiRlbGVtZW50LmZpbmQoXCIub3Jlc1ByZWRpY3Rpb25cIikuZW1wdHkoKTtcclxuXHRcdFx0dGhpcy5wYWdldHlwZUxhYmVsLnRvZ2dsZShmYWxzZSkuc2V0TGFiZWwoXCJcIik7XHJcblxyXG5cdFx0XHR0aGlzLiRlbGVtZW50LmZpbmQoXCIub28tdWktd2luZG93LWZyYW1lXCIpLmNzcyhcInRyYW5zZm9ybVwiLFwiXCIpO1xyXG5cdFx0XHR0aGlzLiRlbGVtZW50LmZpbmQoXCIub28tdWktcHJvY2Vzc0RpYWxvZy1sb2NhdGlvblwiKS5vZmYoXCIucmF0ZXJNYWluV2luXCIpO1xyXG5cdFx0XHQkKFwiYm9keVwiKS5vZmYoXCIucmF0ZXJNYWluV2luXCIpO1xyXG5cdFx0fSApO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUuc2V0UHJlZmVyZW5jZXMgPSBmdW5jdGlvbihwcmVmcykge1xyXG5cdHRoaXMucHJlZmVyZW5jZXMgPSAkLmV4dGVuZCh7fSwgYXBwQ29uZmlnLmRlZmF1bHRQcmVmcywgcHJlZnMpO1xyXG5cdC8vIEFwcGxpZXMgcHJlZmVyZW5jZXMgdG8gZXhpc3RpbmcgaXRlbXMgaW4gdGhlIHdpbmRvdzpcclxuXHR0aGlzLmJhbm5lckxpc3Quc2V0UHJlZmVyZW5jZXModGhpcy5wcmVmZXJlbmNlcyk7XHJcbn07XHJcblxyXG5NYWluV2luZG93LnByb3RvdHlwZS5vblJlc2V0Q2FjaGUgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmV4ZWN1dGVBY3Rpb24oXCJjbGVhckNhY2hlXCIpO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUub25TZWFyY2hTZWxlY3QgPSBmdW5jdGlvbihkYXRhKSB7XHJcblx0dGhpcy50b3BCYXIuc2VhcmNoQm94LnB1c2hQZW5kaW5nKCk7XHJcblx0dmFyIG5hbWUgPSB0aGlzLnRvcEJhci5zZWFyY2hCb3guZ2V0VmFsdWUoKS50cmltKCk7XHJcblx0aWYgKCFuYW1lKSB7XHJcblx0XHR0aGlzLnRvcEJhci5zZWFyY2hCb3gucG9wUGVuZGluZygpLmZvY3VzKCk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdHZhciBleGlzdGluZ0Jhbm5lciA9IHRoaXMuYmFubmVyTGlzdC5pdGVtcy5maW5kKGJhbm5lciA9PiB7XHJcblx0XHRyZXR1cm4gYmFubmVyLm1haW5UZXh0ID09PSBuYW1lIHx8XHRiYW5uZXIucmVkaXJlY3RUYXJnZXRNYWluVGV4dCA9PT0gbmFtZTtcclxuXHR9KTtcclxuXHJcblx0Ly8gQWJvcnQgYW5kIHNob3cgYWxlcnQgaWYgYmFubmVyIGFscmVhZHkgZXhpc3RzXHJcblx0aWYgKGV4aXN0aW5nQmFubmVyKSB7XHJcblx0XHR0aGlzLnRvcEJhci5zZWFyY2hCb3gucG9wUGVuZGluZygpO1xyXG5cdFx0cmV0dXJuIE9PLnVpLmFsZXJ0KFwiVGhlcmUgaXMgYWxyZWFkeSBhIHt7XCIgKyBuYW1lICsgXCJ9fSBiYW5uZXJcIikudGhlbih0aGlzLnNlYXJjaEJveC5mb2N1cygpKTtcclxuXHR9XHJcblxyXG5cdC8vIENvbmZpcm1hdGlvbiByZXF1aXJlZCBmb3IgYmFubmVycyBtaXNzaW5nIFdpa2lQcm9qZWN0IGZyb20gbmFtZSwgYW5kIGZvciB1bmNyZWF0ZWQgZGlzYW1iaWd1YXRpb24gdGFsayBwYWdlc1xyXG5cdHZhciBjb25maXJtVGV4dDtcclxuXHRpZiAoIS9eW1d3XSg/OlB8aWtpW1BwXXJvamVjdCkvLnRlc3QobmFtZSkpIHtcclxuXHRcdGNvbmZpcm1UZXh0ID0gbmV3IE9PLnVpLkh0bWxTbmlwcGV0KFxyXG5cdFx0XHRcInt7XCIgKyBtdy5odG1sLmVzY2FwZShuYW1lKSArIFwifX0gaXMgbm90IGEgcmVjb2duaXNlZCBXaWtpUHJvamVjdCBiYW5uZXIuPGJyLz5EbyB5b3Ugd2FudCB0byBjb250aW51ZT9cIlxyXG5cdFx0KTtcclxuXHR9IGVsc2UgaWYgKG5hbWUgPT09IFwiV2lraVByb2plY3QgRGlzYW1iaWd1YXRpb25cIiAmJiAkKFwiI2NhLXRhbGsubmV3XCIpLmxlbmd0aCAhPT0gMCAmJiB0aGlzLmJhbm5lckxpc3QuaXRlbXMubGVuZ3RoID09PSAwKSB7XHJcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1lc2NhcGVcclxuXHRcdGNvbmZpcm1UZXh0ID0gXCJOZXcgdGFsayBwYWdlcyBzaG91bGRuJ3QgYmUgY3JlYXRlZCBpZiB0aGV5IHdpbGwgb25seSBjb250YWluIHRoZSBcXHtcXHtXaWtpUHJvamVjdCBEaXNhbWJpZ3VhdGlvblxcfVxcfSBiYW5uZXIuIENvbnRpbnVlP1wiO1xyXG5cdH1cclxuXHQkLndoZW4oIGNvbmZpcm1UZXh0ID8gT08udWkuY29uZmlybShjb25maXJtVGV4dCkgOiB0cnVlKVxyXG5cdFx0LnRoZW4oIGNvbmZpcm1lZCA9PiB7XHJcblx0XHRcdGlmICghY29uZmlybWVkKSByZXR1cm47XHJcblx0XHRcdC8vIENyZWF0ZSBUZW1wbGF0ZSBvYmplY3RcclxuXHRcdFx0cmV0dXJuIEJhbm5lcldpZGdldC5uZXdGcm9tVGVtcGxhdGVOYW1lKG5hbWUsIGRhdGEsIHtcclxuXHRcdFx0XHRwcmVmZXJlbmNlczogdGhpcy5wcmVmZXJlbmNlcyxcclxuXHRcdFx0XHQkb3ZlcmxheTogdGhpcy4kb3ZlcmxheSxcclxuXHRcdFx0XHRpc0FydGljbGU6IHRoaXMucGFnZUluZm8uaXNBcnRpY2xlXHJcblx0XHRcdH0pXHJcblx0XHRcdFx0LnRoZW4oYmFubmVyID0+IHtcclxuXHRcdFx0XHRcdHRoaXMuYmFubmVyTGlzdC5hZGRJdGVtcyggW2Jhbm5lcl0gKTtcclxuXHRcdFx0XHRcdGJhbm5lci5zZXRDaGFuZ2VkKCk7XHJcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVNpemUoKTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdH0pXHJcblx0XHQudGhlbiggKCkgPT4gdGhpcy50b3BCYXIuc2VhcmNoQm94LnNldFZhbHVlKFwiXCIpLmZvY3VzKCkucG9wUGVuZGluZygpICk7XHJcbn07XHJcblxyXG5NYWluV2luZG93LnByb3RvdHlwZS5vblNldENsYXNzZXMgPSBmdW5jdGlvbihjbGFzc1ZhbCkge1xyXG5cdGNvbnN0IHNoZWxsVGVtcGxhdGUgPSB0aGlzLmJhbm5lckxpc3QuaXRlbXMuZmluZChiYW5uZXIgPT4gYmFubmVyLmlzU2hlbGxUZW1wbGF0ZSk7XHJcblx0aWYgKHNoZWxsVGVtcGxhdGUpIHtcclxuXHRcdHNoZWxsVGVtcGxhdGUuY2xhc3NEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YShjbGFzc1ZhbCk7XHJcblx0XHRzaGVsbFRlbXBsYXRlLmNsYXNzRHJvcGRvd24uc2V0QXV0b2ZpbGxlZChmYWxzZSk7XHJcblx0fVxyXG5cdHRoaXMuYmFubmVyTGlzdC5pdGVtcy5mb3JFYWNoKGJhbm5lciA9PiB7XHJcblx0XHRpZiAoYmFubmVyLmhhc0NsYXNzUmF0aW5ncyAmJiFiYW5uZXIuaXNTaGVsbFRlbXBsYXRlKSB7XHJcblx0XHRcdGJhbm5lci5jbGFzc0Ryb3Bkb3duLmdldE1lbnUoKS5zZWxlY3RJdGVtQnlEYXRhKHNoZWxsVGVtcGxhdGUgPyBudWxsIDogY2xhc3NWYWwpO1xyXG5cdFx0XHRiYW5uZXIuY2xhc3NEcm9wZG93bi5zZXRBdXRvZmlsbGVkKGZhbHNlKTtcclxuXHRcdH1cclxuXHR9KTtcclxufTtcclxuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLm9uU2V0SW1wb3J0YW5jZXMgPSBmdW5jdGlvbihpbXBvcnRhbmNlVmFsKSB7XHJcblx0dGhpcy5iYW5uZXJMaXN0Lml0ZW1zLmZvckVhY2goYmFubmVyID0+IHtcclxuXHRcdGlmIChiYW5uZXIuaGFzSW1wb3J0YW5jZVJhdGluZ3MpIHtcclxuXHRcdFx0YmFubmVyLmltcG9ydGFuY2VEcm9wZG93bi5nZXRNZW51KCkuc2VsZWN0SXRlbUJ5RGF0YShpbXBvcnRhbmNlVmFsKTtcclxuXHRcdFx0YmFubmVyLmltcG9ydGFuY2VEcm9wZG93bi5zZXRBdXRvZmlsbGVkKGZhbHNlKTtcclxuXHRcdH1cclxuXHR9KTtcclxufTtcclxuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLm9uUmVtb3ZlQWxsID0gZnVuY3Rpb24oKSB7XHJcblx0dGhpcy5iYW5uZXJMaXN0LmNsZWFySXRlbXMoKTtcclxufTtcclxuXHJcbk1haW5XaW5kb3cucHJvdG90eXBlLm9uQ2xlYXJBbGwgPSBmdW5jdGlvbigpIHtcclxuXHR0aGlzLmJhbm5lckxpc3QuaXRlbXMuZm9yRWFjaCggYmFubmVyID0+IGJhbm5lci5vbkNsZWFyQnV0dG9uQ2xpY2soKSApO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUudHJhbnNmb3JtVGFsa1dpa2l0ZXh0ID0gZnVuY3Rpb24odGFsa1dpa2l0ZXh0KSB7XHJcblx0dmFyIGJhbm5lcnNXaWtpdGV4dCA9IHRoaXMuYmFubmVyTGlzdC5tYWtlV2lraXRleHQoKTtcclxuXHRpZiAoIXRhbGtXaWtpdGV4dCkge1xyXG5cdFx0cmV0dXJuIGJhbm5lcnNXaWtpdGV4dC50cmltKCk7XHJcblx0fVxyXG5cdC8vIFJlcGFyc2UgdGVtcGxhdGVzLCBpbiBjYXNlIHRhbGtwYWdlIHdpa2l0ZXh0IGhhcyBjaGFuZ2VkXHJcblx0dmFyIHRhbGtUZW1wbGF0ZXMgPSBwYXJzZVRlbXBsYXRlcyh0YWxrV2lraXRleHQsIHRydWUpO1xyXG5cdC8vIHJlcGxhY2UgZXhpc3RpbmcgYmFubmVycyB3aWtpdGV4dCB3aXRoIGEgY29udHJvbCBjaGFyYWN0ZXJcclxuXHR0YWxrVGVtcGxhdGVzLmZvckVhY2godGVtcGxhdGUgPT4ge1xyXG5cdFx0aWYgKHRoaXMuZXhpc3RpbmdCYW5uZXJOYW1lcy5pbmNsdWRlcyh0ZW1wbGF0ZS5uYW1lKSkge1xyXG5cdFx0XHR0YWxrV2lraXRleHQgPSB0YWxrV2lraXRleHQucmVwbGFjZSh0ZW1wbGF0ZS53aWtpdGV4dCwgXCJcXHgwMVwiKTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHQvLyByZXBsYWNlIGluc2VydGlvbiBwb2ludCAoZmlyc3QgY29udHJvbCBjaGFyYWN0ZXIpIHdpdGggYSBkaWZmZXJlbnQgY29udHJvbCBjaGFyYWN0ZXJcclxuXHR0YWxrV2lraXRleHQgPSB0YWxrV2lraXRleHQucmVwbGFjZShcIlxceDAxXCIsIFwiXFx4MDJcIik7XHJcblx0Ly8gcmVtb3ZlIG90aGVyIGNvbnRyb2wgY2hhcmFjdGVyc1xyXG5cdC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb250cm9sLXJlZ2V4ICovXHJcblx0dGFsa1dpa2l0ZXh0ID0gdGFsa1dpa2l0ZXh0LnJlcGxhY2UoLyg/Olxcc3xcXG4pKlxceDAxKD86XFxzfFxcbikqL2csXCJcIik7XHJcblx0Ly8gc3BsaXQgaW50byB3aWtpdGV4dCBiZWZvcmUvYWZ0ZXIgdGhlIHJlbWFpbmluZyBjb250cm9sIGNoYXJhY3RlciAoYW5kIHRyaW0gZWFjaCBzZWN0aW9uKVxyXG5cdHZhciB0YWxrV2lraXRleHRTZWN0aW9ucyA9IHRhbGtXaWtpdGV4dC5zcGxpdChcIlxceDAyXCIpLm1hcCh0ID0+IHQudHJpbSgpKTtcclxuXHRpZiAodGFsa1dpa2l0ZXh0U2VjdGlvbnMubGVuZ3RoID09PSAyKSB7XHJcblx0XHQvLyBGb3VuZCB0aGUgaW5zZXJ0aW9uIHBvaW50IGZvciB0aGUgYmFubmVyc1xyXG5cdFx0cmV0dXJuICh0YWxrV2lraXRleHRTZWN0aW9uc1swXSArIFwiXFxuXCIgKyBiYW5uZXJzV2lraXRleHQudHJpbSgpICsgXCJcXG5cIiArIHRhbGtXaWtpdGV4dFNlY3Rpb25zWzFdKS50cmltKCk7XHJcblx0fVxyXG5cdC8vIENoZWNrIGlmIHRoZXJlJ3MgYW55dGhpbmcgYmVzaWRlIHRlbXBsYXRlc1xyXG5cdHZhciB0ZW1wU3RyID0gdGFsa1dpa2l0ZXh0O1xyXG5cdHRhbGtUZW1wbGF0ZXMuZm9yRWFjaCh0ZW1wbGF0ZSA9PiB7XHJcblx0XHR0ZW1wU3RyID0gdGVtcFN0ci5yZXBsYWNlKHRlbXBsYXRlLndpa2l0ZXh0LCBcIlwiKTtcclxuXHR9KTtcclxuXHRpZiAoL14jUkVESVJFQ1QvaS50ZXN0KHRhbGtXaWtpdGV4dCkgfHwgIXRlbXBTdHIudHJpbSgpKSB7XHJcblx0XHQvLyBJcyBhIHJlZGlyZWN0LCBvciBldmVyeXRoaW5nIGlzIGEgdGVtcGxhdGU6IGluc2VydCBhdCB0aGUgZW5kXHJcblx0XHRyZXR1cm4gdGFsa1dpa2l0ZXh0LnRyaW0oKSArIFwiXFxuXCIgKyBiYW5uZXJzV2lraXRleHQudHJpbSgpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHQvLyBUaGVyZSBpcyBub24tdGVtcGxhdGUgY29udGVudCwgc28gaW5zZXJ0IGF0IHRoZSBzdGFydFxyXG5cdFx0cmV0dXJuIGJhbm5lcnNXaWtpdGV4dC50cmltKCkgKyBcIlxcblwiICsgdGFsa1dpa2l0ZXh0LnRyaW0oKTtcclxuXHR9XHJcbn07XHJcblxyXG5NYWluV2luZG93LnByb3RvdHlwZS5pc1JhdGVkQW5kTm90U3R1YiA9IGZ1bmN0aW9uKCkge1xyXG5cdGNvbnN0IG5vblN0dWJSYXRpbmdncyA9IHRoaXMuYmFubmVyTGlzdC5pdGVtcy5maWx0ZXIoYmFubmVyID0+XHJcblx0XHRiYW5uZXIuaGFzQ2xhc3NSYXRpbmdzICYmXHJcblx0XHRiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRWYWx1ZSgpICYmXHJcblx0XHRiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRWYWx1ZSgpICE9PSBcIlN0dWJcIlxyXG5cdCk7XHJcblx0cmV0dXJuIG5vblN0dWJSYXRpbmdncy5sZW5ndGggPiAwO1xyXG59O1xyXG5cclxuTWFpbldpbmRvdy5wcm90b3R5cGUubWFrZUVkaXRTdW1tYXJ5ID0gZnVuY3Rpb24oKSB7XHJcblx0Y29uc3QgcmVtb3ZlZEJhbm5lcnMgPSBbXTtcclxuXHRjb25zdCBlZGl0ZWRCYW5uZXJzID0gW107XHJcblx0Y29uc3QgbmV3QmFubmVycyA9IFtdO1xyXG5cdGNvbnN0IHNob3J0TmFtZSA9IG5hbWUgPT4gbmFtZS5yZXBsYWNlKFwiV2lraVByb2plY3QgXCIsXCJcIikucmVwbGFjZShcIlN1YnN0OlwiLFwiXCIpO1xyXG5cclxuXHQvLyBPdmVyYWxsIGNsYXNzL2ltcG9ydGFuY2UsIGlmIGFsbCB0aGUgc2FtZVxyXG5cdGNvbnN0IGFsbENsYXNzZXMgPSB1bmlxdWVBcnJheShcclxuXHRcdGZpbHRlckFuZE1hcCh0aGlzLmJhbm5lckxpc3QuaXRlbXMsXHJcblx0XHRcdGJhbm5lciA9PiBiYW5uZXIuaGFzQ2xhc3NSYXRpbmdzIHx8IGJhbm5lci5pc1NoZWxsVGVtcGxhdGUsXHJcblx0XHRcdGJhbm5lciA9PiBiYW5uZXIuY2xhc3NEcm9wZG93bi5nZXRWYWx1ZSgpXHJcblx0XHQpXHJcblx0KTtcclxuXHRsZXQgb3ZlcmFsbENsYXNzID0gYWxsQ2xhc3Nlcy5sZW5ndGggPT09IDEgJiYgYWxsQ2xhc3Nlc1swXTtcclxuXHRjb25zdCBhbGxJbXBvcnRhbmNlcyA9IHVuaXF1ZUFycmF5KFxyXG5cdFx0ZmlsdGVyQW5kTWFwKHRoaXMuYmFubmVyTGlzdC5pdGVtcyxcclxuXHRcdFx0YmFubmVyID0+IGJhbm5lci5oYXNJbXBvcnRhbmNlUmF0aW5ncyxcclxuXHRcdFx0YmFubmVyID0+IGJhbm5lci5pbXBvcnRhbmNlRHJvcGRvd24uZ2V0VmFsdWUoKVxyXG5cdFx0KVxyXG5cdCk7XHJcblx0bGV0IG92ZXJhbGxJbXBvcnRhbmNlID0gYWxsSW1wb3J0YW5jZXMubGVuZ3RoID09PSAxICYmIGFsbEltcG9ydGFuY2VzWzBdO1xyXG5cdC8vIERvbid0IHVzZSB0aGVtIHVubGVzcyBzb21lIGhhdmUgY2hhbmdlZFxyXG5cdGxldCBzb21lQ2xhc3Nlc0NoYW5nZWQgPSBmYWxzZTtcclxuXHRsZXQgc29tZUltcG9ydGFuY2VzQ2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuXHQvLyByZW1vdmVkIGJhbm5lcnM6XHJcblx0dGhpcy5leGlzdGluZ0Jhbm5lck5hbWVzLmZvckVhY2gobmFtZSA9PiB7XHJcblx0XHRjb25zdCBiYW5uZXIgPSB0aGlzLmJhbm5lckxpc3QuaXRlbXMuZmluZCggYmFubmVyID0+IGJhbm5lci5uYW1lID09PSBuYW1lIHx8IGJhbm5lci5ieXBhc3NlZE5hbWUgPT09IG5hbWUgKTtcclxuXHRcdGlmICghYmFubmVyKSB7XHJcblx0XHRcdHJlbW92ZWRCYW5uZXJzLnB1c2goXCLiiJJcIiArIHNob3J0TmFtZShuYW1lKSk7XHJcblx0XHR9XHJcblx0fSk7XHJcblx0Ly8gZWRpdGVkICYgbmV3IGJhbm5lcnNcclxuXHR0aGlzLmJhbm5lckxpc3QuaXRlbXMuZm9yRWFjaCggYmFubmVyID0+IHtcclxuXHRcdGNvbnN0IGlzTmV3ID0gIWJhbm5lci53aWtpdGV4dDsgLy8gbm90IGFkZGVkIGZyb20gd2lraXRleHQgb24gcGFnZVxyXG5cdFx0aWYgKCFpc05ldyAmJiAhYmFubmVyLmNoYW5nZWQpIHtcclxuXHRcdFx0Ly8gTm90IGNoYW5nZWRcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0bGV0IG5ld0NsYXNzID0gYmFubmVyLmhhc0NsYXNzUmF0aW5ncyAmJiAgKGlzTmV3IHx8IGJhbm5lci5jbGFzc0NoYW5nZWQpICYmIGJhbm5lci5jbGFzc0Ryb3Bkb3duLmdldFZhbHVlKCk7XHJcblx0XHRpZiAobmV3Q2xhc3MpIHsgc29tZUNsYXNzZXNDaGFuZ2VkID0gdHJ1ZTsgfVxyXG5cdFx0aWYgKG92ZXJhbGxDbGFzcykgeyBuZXdDbGFzcyA9IG51bGw7IH1cclxuXHJcblx0XHRsZXQgbmV3SW1wb3J0YW5jZSA9IGJhbm5lci5oYXNJbXBvcnRhbmNlUmF0aW5ncyAmJiAoaXNOZXcgfHwgYmFubmVyLmltcG9ydGFuY2VDaGFuZ2VkKSAmJiBiYW5uZXIuaW1wb3J0YW5jZURyb3Bkb3duLmdldFZhbHVlKCk7XHJcblx0XHRpZiAobmV3SW1wb3J0YW5jZSkgeyBzb21lSW1wb3J0YW5jZXNDaGFuZ2VkID0gdHJ1ZTsgfVxyXG5cdFx0aWYgKG92ZXJhbGxJbXBvcnRhbmNlKSB7IG5ld0ltcG9ydGFuY2UgPSBudWxsOyB9XHJcblxyXG5cdFx0bGV0IHJhdGluZyA9IChuZXdDbGFzcyAmJiBuZXdJbXBvcnRhbmNlKVxyXG5cdFx0XHQ/IG5ld0NsYXNzICsgXCIvXCIgKyBuZXdJbXBvcnRhbmNlXHJcblx0XHRcdDogbmV3Q2xhc3MgfHwgbmV3SW1wb3J0YW5jZSB8fCBcIlwiO1xyXG5cdFx0aWYgKHJhdGluZykgeyByYXRpbmcgPSBcIiAoXCIgKyByYXRpbmcgKyBcIilcIjsgfVxyXG5cdFx0XHJcblx0XHRpZiAoaXNOZXcpIHtcclxuXHRcdFx0bmV3QmFubmVycy5wdXNoKFwiK1wiICsgc2hvcnROYW1lKGJhbm5lci5uYW1lKSArIHJhdGluZyk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRlZGl0ZWRCYW5uZXJzLnB1c2goc2hvcnROYW1lKGJhbm5lci5uYW1lKSArIHJhdGluZyk7XHJcblx0XHR9XHJcblx0fSk7XHJcblx0Ly8gb3ZlcmFsbCByYXRpbmdcclxuXHRsZXQgb3ZlcmFsbFJhdGluZyA9IChzb21lQ2xhc3Nlc0NoYW5nZWQgJiYgb3ZlcmFsbENsYXNzICYmIHNvbWVJbXBvcnRhbmNlc0NoYW5nZWQgJiYgb3ZlcmFsbEltcG9ydGFuY2UpXHJcblx0XHQ/IG92ZXJhbGxDbGFzcyArIFwiL1wiICsgb3ZlcmFsbEltcG9ydGFuY2VcclxuXHRcdDogKHNvbWVDbGFzc2VzQ2hhbmdlZCAmJiBvdmVyYWxsQ2xhc3MpIHx8IChzb21lSW1wb3J0YW5jZXNDaGFuZ2VkICYmIG92ZXJhbGxJbXBvcnRhbmNlKSB8fCBcIlwiO1xyXG5cdGlmIChvdmVyYWxsUmF0aW5nKSB7IG92ZXJhbGxSYXRpbmcgPSBcIiAoXCIgKyBvdmVyYWxsUmF0aW5nICsgXCIpXCI7IH1cclxuXHJcblx0cmV0dXJuIGBBc3Nlc3NtZW50JHtvdmVyYWxsUmF0aW5nfTogJHtbLi4uZWRpdGVkQmFubmVycywgLi4ubmV3QmFubmVycywgLi4ucmVtb3ZlZEJhbm5lcnNdLmpvaW4oXCIsIFwiKX0ke2FwcENvbmZpZy5zY3JpcHQuYWR2ZXJ0fWA7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBNYWluV2luZG93O1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgY29uZmlnIGZyb20gXCIuL2NvbmZpZ1wiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxudmFyIEFQSSA9IG5ldyBtdy5BcGkoIHtcclxuXHRhamF4OiB7XHJcblx0XHRoZWFkZXJzOiB7IFxyXG5cdFx0XHRcIkFwaS1Vc2VyLUFnZW50XCI6IFwiUmF0ZXIvXCIgKyBjb25maWcuc2NyaXB0LnZlcnNpb24gKyBcclxuXHRcdFx0XHRcIiAoIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VzZXI6RXZhZDM3L1JhdGVyIClcIlxyXG5cdFx0fVxyXG5cdH1cclxufSApO1xyXG5cclxuLyogLS0tLS0tLS0tLSBBUEkgZm9yIE9SRVMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5BUEkuZ2V0T1JFUyA9IGZ1bmN0aW9uKHJldmlzaW9uSUQpIHtcclxuXHRyZXR1cm4gJC5nZXQoXCJodHRwczovL29yZXMud2lraW1lZGlhLm9yZy92My9zY29yZXMvZW53aWtpP21vZGVscz1hcnRpY2xlcXVhbGl0eSZyZXZpZHM9XCIrcmV2aXNpb25JRCk7XHJcbn07XHJcblxyXG4vKiAtLS0tLS0tLS0tIFJhdyB3aWtpdGV4dCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcbkFQSS5nZXRSYXcgPSBmdW5jdGlvbihwYWdlKSB7XHJcblx0cmV0dXJuICQuZ2V0KFwiaHR0cHM6XCIgKyBjb25maWcubXcud2dTZXJ2ZXIgKyBtdy51dGlsLmdldFVybChwYWdlLCB7YWN0aW9uOlwicmF3XCJ9KSlcclxuXHRcdC50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcclxuXHRcdFx0aWYgKCAhZGF0YSApIHtcclxuXHRcdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlamVjdChcIm9rLWJ1dC1lbXB0eVwiKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gZGF0YTtcclxuXHRcdH0pO1xyXG59O1xyXG5cclxuLyogLS0tLS0tLS0tLSBFZGl0IHdpdGggcmV0cnkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG4vKipcclxuICogQHBhcmFtIHtTdHJpbmd9IHRpdGxlXHJcbiAqIEBwYXJhbSB7T2JqZWN0P30gcGFyYW1zIGFkZGl0aW9uYWwgcGFyYW1zIGZvciB0aGUgZ2V0IHJlcXVlc3RcclxuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0LCBzdHJpbmc+fSBwYWdlLCBzdGFydHRpbWUgdGltZXN0YW1wXHJcbiAqL1xyXG52YXIgZ2V0UGFnZSA9IGZ1bmN0aW9uKHRpdGxlLCBwYXJhbXMpIHtcclxuXHRyZXR1cm4gQVBJLmdldChcclxuXHRcdCQuZXh0ZW5kKFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0XCJhY3Rpb25cIjogXCJxdWVyeVwiLFxyXG5cdFx0XHRcdFwiZm9ybWF0XCI6IFwianNvblwiLFxyXG5cdFx0XHRcdFwiY3VydGltZXN0YW1wXCI6IDEsXHJcblx0XHRcdFx0XCJ0aXRsZXNcIjogdGl0bGUsXHJcblx0XHRcdFx0XCJwcm9wXCI6IFwicmV2aXNpb25zfGluZm9cIixcclxuXHRcdFx0XHRcInJ2cHJvcFwiOiBcImNvbnRlbnR8dGltZXN0YW1wXCIsXHJcblx0XHRcdFx0XCJydnNsb3RzXCI6IFwibWFpblwiXHRcdFx0XHRcdFxyXG5cdFx0XHR9LFxyXG5cdFx0XHRwYXJhbXNcclxuXHRcdClcclxuXHQpLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG5cdFx0dmFyIHBhZ2UgPSBPYmplY3QudmFsdWVzKHJlc3BvbnNlLnF1ZXJ5LnBhZ2VzKVswXTtcclxuXHRcdHZhciBzdGFydHRpbWUgPSByZXNwb25zZS5jdXJ0aW1lc3RhbXA7XHJcblx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlc29sdmUocGFnZSwgc3RhcnR0aW1lKTtcclxuXHR9KTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gcGFnZSBkZXRhaWxzIG9iamVjdCBmcm9tIEFQSVxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RhcnR0aW1lIHRpbWVzdGFtcFxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gY2FsbGJhY2sgdGhhdCBwcmVwYXJlcyB0aGUgZWRpdDpcclxuICogIHtPYmplY3R9IHNpbXBsaWZpZWRQYWdlID0+IHtPYmplY3R8UHJvbWlzZTxPYmplY3Q+fSBlZGl0IHBhcmFtc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBwYXJhbXMgZm9yIGVkaXQgcXVlcnlcclxuICovXHJcbnZhciBwcm9jZXNzUGFnZSA9IGZ1bmN0aW9uKHBhZ2UsIHN0YXJ0dGltZSwgdHJhbnNmb3JtKSB7XHJcblx0dmFyIGJhc2V0aW1lc3RhbXAgPSBwYWdlLnJldmlzaW9ucyAmJiBwYWdlLnJldmlzaW9uc1swXS50aW1lc3RhbXA7XHJcblx0dmFyIHNpbXBsaWZpZWRQYWdlID0ge1xyXG5cdFx0cGFnZWlkOiBwYWdlLnBhZ2VpZCxcclxuXHRcdG1pc3Npbmc6IHBhZ2UubWlzc2luZyA9PT0gXCJcIixcclxuXHRcdHJlZGlyZWN0OiBwYWdlLnJlZGlyZWN0ID09PSBcIlwiLFxyXG5cdFx0Y2F0ZWdvcmllczogcGFnZS5jYXRlZ29yaWVzLFxyXG5cdFx0bnM6IHBhZ2UubnMsXHJcblx0XHR0aXRsZTogcGFnZS50aXRsZSxcclxuXHRcdGNvbnRlbnQ6IHBhZ2UucmV2aXNpb25zICYmIHBhZ2UucmV2aXNpb25zWzBdLnNsb3RzLm1haW5bXCIqXCJdXHJcblx0fTtcclxuXHRyZXR1cm4gJC53aGVuKCB0cmFuc2Zvcm0oc2ltcGxpZmllZFBhZ2UpIClcclxuXHRcdC50aGVuKCBlZGl0UGFyYW1zID0+XHJcblx0XHRcdCQuZXh0ZW5kKCB7XHJcblx0XHRcdFx0YWN0aW9uOiBcImVkaXRcIixcclxuXHRcdFx0XHR0aXRsZTogcGFnZS50aXRsZSxcclxuXHRcdFx0XHQvLyBQcm90ZWN0IGFnYWluc3QgZXJyb3JzIGFuZCBjb25mbGljdHNcclxuXHRcdFx0XHRhc3NlcnQ6IFwidXNlclwiLFxyXG5cdFx0XHRcdGJhc2V0aW1lc3RhbXA6IGJhc2V0aW1lc3RhbXAsXHJcblx0XHRcdFx0c3RhcnR0aW1lc3RhbXA6IHN0YXJ0dGltZVxyXG5cdFx0XHR9LCBlZGl0UGFyYW1zIClcclxuXHRcdCk7XHJcbn07XHJcblxyXG4vKiogZWRpdFdpdGhSZXRyeVxyXG4gKiBcclxuICogRWRpdHMgYSBwYWdlLCByZXNvbHZpbmcgZWRpdCBjb25mbGljdHMsIGFuZCByZXRyeWluZyBlZGl0cyB0aGF0IGZhaWwuIFRoZVxyXG4gKiB0cmFuZm9ybSBmdW5jdGlvbiBtYXkgcmV0dXJuIGEgcmVqZWN0ZWQgcHJvbWlzZSBpZiB0aGUgcGFnZSBzaG91bGQgbm90IGJlXHJcbiAqIGVkaXRlZDsgdGhlIEByZXR1cm5zIHtQcm9taXNlfSB3aWxsIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgc2FtZSByZWplY3Rpb25cclxuICogdmFsdWVzLlxyXG4gKiBcclxuICogTm90ZTogVW5saWtlIFttdy5BcGkjRWRpdF0sIGEgbWlzc2luZyBwYWdlIHdpbGwgYmUgY3JlYXRlZCwgdW5sZXNzIHRoZVxyXG4gKiB0cmFuc2Zvcm0gY2FsbGJhY2sgaW5jbHVkZXMgdGhlIFwibm9jcmVhdGVcIiBwYXJhbS5cclxuICogXHJcbiAqIFttdy5BcGkjRWRpdF06IDxodHRwczovL2RvYy53aWtpbWVkaWEub3JnL21lZGlhd2lraS1jb3JlL21hc3Rlci9qcy8jIS9hcGkvbXcuQXBpLnBsdWdpbi5lZGl0PlxyXG4gKiBcclxuICogQHBhcmFtIHtTdHJpbmd9IHRpdGxlIHBhZ2UgdG8gYmUgZWRpdGVkXHJcbiAqIEBwYXJhbSB7T2JqZWN0fG51bGx9IGdldFBhcmFtcyBhZGRpdGlvbmFsIHBhcmFtcyBmb3IgdGhlIGdldCByZXF1ZXN0XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBjYWxsYmFjayB0aGF0IHByZXBhcmVzIHRoZSBlZGl0OlxyXG4gKiAge09iamVjdH0gc2ltcGxpZmllZFBhZ2UgPT4ge09iamVjdHxQcm9taXNlPE9iamVjdD59IHBhcmFtcyBmb3IgQVBJIGVkaXRpbmdcclxuICogQHJldHVybnMge1Byb21pc2U8b2JqZWN0Pn0gcHJvbWlzZSwgcmVzb2x2ZWQgb24gc3VjY2VzcywgcmVqZWN0ZWQgaWZcclxuICogIHBhZ2Ugd2FzIG5vdCBlZGl0ZWRcclxuICovXHJcbkFQSS5lZGl0V2l0aFJldHJ5ID0gZnVuY3Rpb24odGl0bGUsIGdldFBhcmFtcywgdHJhbnNmb3JtKSB7XHJcblx0cmV0dXJuIGdldFBhZ2UodGl0bGUsIGdldFBhcmFtcylcclxuXHRcdC50aGVuKFxyXG5cdFx0Ly8gU3VjY2VzOiBwcm9jZXNzIHRoZSBwYWdlXHJcblx0XHRcdChwYWdlLCBzdGFydHRpbWUpID0+IHByb2Nlc3NQYWdlKHBhZ2UsIHN0YXJ0dGltZSwgdHJhbnNmb3JtKSxcclxuXHRcdFx0Ly8gRmFpbHVyZTogdHJ5IGFnYWluXHJcblx0XHRcdCgpID0+IGdldFBhZ2UodGl0bGUsIGdldFBhcmFtcykudGhlbihwcm9jZXNzUGFnZSwgdHJhbnNmb3JtKVxyXG5cdFx0KVxyXG5cdFx0LnRoZW4oZWRpdFBhcmFtcyA9PlxyXG5cdFx0XHRBUEkucG9zdFdpdGhUb2tlbihcImNzcmZcIiwgZWRpdFBhcmFtcylcclxuXHRcdFx0XHQuY2F0Y2goIGVycm9yQ29kZSA9PiB7XHJcblx0XHRcdFx0XHRpZiAoIGVycm9yQ29kZSA9PT0gXCJlZGl0Y29uZmxpY3RcIiApIHtcclxuXHRcdFx0XHRcdFx0Ly8gVHJ5IGFnYWluLCBzdGFydGluZyBvdmVyXHJcblx0XHRcdFx0XHRcdHJldHVybiBBUEkuZWRpdFdpdGhSZXRyeSh0aXRsZSwgZ2V0UGFyYW1zLCB0cmFuc2Zvcm0pO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0Ly8gVHJ5IGFnYWluXHJcblx0XHRcdFx0XHRyZXR1cm4gQVBJLnBvc3RXaXRoVG9rZW4oXCJjc3JmXCIsIGVkaXRQYXJhbXMpO1xyXG5cdFx0XHRcdH0pXHJcblx0XHQpO1xyXG59O1xyXG5cclxudmFyIG1ha2VFcnJvck1zZyA9IGZ1bmN0aW9uKGZpcnN0LCBzZWNvbmQpIHtcclxuXHR2YXIgY29kZSwgeGhyLCBtZXNzYWdlO1xyXG5cdGlmICggdHlwZW9mIGZpcnN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBzZWNvbmQgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHQvLyBFcnJvcnMgZnJvbSAkLmdldCBiZWluZyByZWplY3RlZCAoT1JFUyAmIFJhdyB3aWtpdGV4dClcclxuXHRcdHZhciBlcnJvck9iaiA9IGZpcnN0LnJlc3BvbnNlSlNPTiAmJiBmaXJzdC5yZXNwb25zZUpTT04uZXJyb3I7XHJcblx0XHRpZiAoIGVycm9yT2JqICkge1xyXG5cdFx0XHQvLyBHb3QgYW4gYXBpLXNwZWNpZmljIGVycm9yIGNvZGUvbWVzc2FnZVxyXG5cdFx0XHRjb2RlID0gZXJyb3JPYmouY29kZTtcclxuXHRcdFx0bWVzc2FnZSA9IGVycm9yT2JqLm1lc3NhZ2U7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR4aHIgPSBmaXJzdDtcclxuXHRcdH1cclxuXHR9IGVsc2UgaWYgKCB0eXBlb2YgZmlyc3QgPT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIHNlY29uZCA9PT0gXCJvYmplY3RcIiApIHtcclxuXHRcdC8vIEVycm9ycyBmcm9tIG13LkFwaSBvYmplY3RcclxuXHRcdHZhciBtd0Vycm9yT2JqID0gc2Vjb25kLmVycm9yO1xyXG5cdFx0aWYgKG13RXJyb3JPYmopIHtcclxuXHRcdFx0Ly8gR290IGFuIGFwaS1zcGVjaWZpYyBlcnJvciBjb2RlL21lc3NhZ2VcclxuXHRcdFx0Y29kZSA9IGVycm9yT2JqLmNvZGU7XHJcblx0XHRcdG1lc3NhZ2UgPSBlcnJvck9iai5pbmZvO1xyXG5cdFx0fSBlbHNlIGlmIChmaXJzdCA9PT0gXCJvay1idXQtZW1wdHlcIikge1xyXG5cdFx0XHRjb2RlID0gbnVsbDtcclxuXHRcdFx0bWVzc2FnZSA9IFwiR290IGFuIGVtcHR5IHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlclwiO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0eGhyID0gc2Vjb25kICYmIHNlY29uZC54aHI7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoY29kZSAmJiBtZXNzYWdlKSB7XHJcblx0XHRyZXR1cm4gYEFQSSBlcnJvciAke2NvZGV9OiAke21lc3NhZ2V9YDtcclxuXHR9IGVsc2UgaWYgKG1lc3NhZ2UpIHtcclxuXHRcdHJldHVybiBgQVBJIGVycm9yOiAke21lc3NhZ2V9YDtcclxuXHR9IGVsc2UgaWYgKHhocikge1xyXG5cdFx0cmV0dXJuIGBIVFRQIGVycm9yICR7eGhyLnN0YXR1c31gO1xyXG5cdH0gZWxzZSBpZiAoXHJcblx0XHR0eXBlb2YgZmlyc3QgPT09IFwic3RyaW5nXCIgJiYgZmlyc3QgIT09IFwiZXJyb3JcIiAmJlxyXG5cdFx0dHlwZW9mIHNlY29uZCA9PT0gXCJzdHJpbmdcIiAmJiBzZWNvbmQgIT09IFwiZXJyb3JcIlxyXG5cdCkge1xyXG5cdFx0cmV0dXJuIGBFcnJvciAke2ZpcnN0fTogJHtzZWNvbmR9YDtcclxuXHR9IGVsc2UgaWYgKHR5cGVvZiBmaXJzdCA9PT0gXCJzdHJpbmdcIiAmJiBmaXJzdCAhPT0gXCJlcnJvclwiKSB7XHJcblx0XHRyZXR1cm4gYEVycm9yOiAke2ZpcnN0fWA7XHJcblx0fSBlbHNlIHtcclxuXHRcdHJldHVybiBcIlVua25vd24gQVBJIGVycm9yXCI7XHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQVBJO1xyXG5leHBvcnQgeyBtYWtlRXJyb3JNc2cgfTtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IGNvbmZpZyBmcm9tIFwiLi9jb25maWdcIjtcclxuaW1wb3J0IHsgZ2V0UHJlZnMgfSBmcm9tIFwiLi9wcmVmc1wiO1xyXG5pbXBvcnQgQVBJLCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQgc2V0dXBSYXRlciBmcm9tIFwiLi9zZXR1cFwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxudmFyIGF1dG9TdGFydCA9IGZ1bmN0aW9uIGF1dG9TdGFydCgpIHtcclxuXHJcblx0cmV0dXJuIGdldFByZWZzKCkudGhlbihwcmVmcyA9PiB7XHJcblx0XHQvLyBDaGVjayBpZiBwcmVmIGlzIHR1cm5lZCBvZmZcclxuXHRcdGlmICghcHJlZnMuYXV0b3N0YXJ0KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdC8vIENoZWNrIGlmIHByZWYgaXMgdHVybmVkIG9mZiBmb3IgcmVkaXJlY3RzLCBhbmQgY3VycmVudCBwYWdlIGlzIGEgcmVkaXJlY3RcclxuXHRcdGlmICghcHJlZnMuYXV0b3N0YXJ0UmVkaXJlY3RzICYmIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guaW5jbHVkZXMoXCJyZWRpcmVjdD1ub1wiKSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHQvLyBDaGVjayBpZiB2aWV3aW5nIGRpZmYvaGlzdG9yeS9vbGQgdmVyc2lvblxyXG5cdFx0aWYgKC8oYWN0aW9ufGRpZmZ8b2xkaWQpLy50ZXN0KHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IHN1YmplY3RUaXRsZSA9IG13LlRpdGxlLm5ld0Zyb21UZXh0KGNvbmZpZy5tdy53Z1BhZ2VOYW1lKS5nZXRTdWJqZWN0UGFnZSgpO1xyXG5cdFx0Ly8gQ2hlY2sgaWYgc3ViamVjdCBwYWdlIGlzIHRoZSBtYWluIHBhZ2VcclxuXHRcdGlmIChzdWJqZWN0VGl0bGUuZ2V0UHJlZml4ZWRUZXh0KCkgPT09IFwiTWFpbiBQYWdlXCIpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0Ly8gQ2hlY2sgc3ViamVjdCBwYWdlIG5hbWVzcGFjZVxyXG5cdFx0aWYgKFxyXG5cdFx0XHRwcmVmcy5hdXRvc3RhcnROYW1lc3BhY2VzICYmXHJcblx0XHRcdHByZWZzLmF1dG9zdGFydE5hbWVzcGFjZXMubGVuZ3RoICYmXHJcblx0XHRcdCFwcmVmcy5hdXRvc3RhcnROYW1lc3BhY2VzLmluY2x1ZGVzKGNvbmZpZy5tdy53Z05hbWVzcGFjZU51bWJlcilcclxuXHRcdCkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHJcblx0XHQvLyBJZiB0YWxrIHBhZ2UgZG9lcyBub3QgZXhpc3QsIGNhbiBqdXN0IGF1dG9zdGFydFxyXG5cdFx0aWYgKCAkKFwiI2NhLXRhbGsubmV3XCIpLmxlbmd0aCApIHtcclxuXHRcdFx0cmV0dXJuIHNldHVwUmF0ZXIoKTtcclxuXHRcdH1cdFxyXG5cclxuXHRcdC8qIENoZWNrIHRlbXBsYXRlcyBwcmVzZW50IG9uIHRhbGsgcGFnZS4gRmV0Y2hlcyBpbmRpcmVjdGx5IHRyYW5zY2x1ZGVkIHRlbXBsYXRlcywgc28gd2lsbCBmaW5kXHJcblx0XHRcdFRlbXBsYXRlOldQQmFubmVyTWV0YSAoYW5kIGl0cyBzdWJ0ZW1wbGF0ZXMpLiBCdXQgc29tZSBiYW5uZXJzIHN1Y2ggYXMgTUlMSElTVCBkb24ndCB1c2UgdGhhdFxyXG5cdFx0XHRtZXRhIHRlbXBsYXRlLCBzbyB3ZSBhbHNvIGhhdmUgdG8gY2hlY2sgZm9yIHRlbXBsYXRlIHRpdGxlcyBjb250YWluZyAnV2lraVByb2plY3QnXHJcblx0XHQqL1xyXG5cdFx0Y29uc3QgdGFsa1RpdGxlID0gbXcuVGl0bGUubmV3RnJvbVRleHQoY29uZmlnLm13LndnUGFnZU5hbWUpLmdldFRhbGtQYWdlKCk7XHJcblx0XHRyZXR1cm4gQVBJLmdldCh7XHJcblx0XHRcdGFjdGlvbjogXCJxdWVyeVwiLFxyXG5cdFx0XHRmb3JtYXQ6IFwianNvblwiLFxyXG5cdFx0XHRwcm9wOiBcInRlbXBsYXRlc1wiLFxyXG5cdFx0XHR0aXRsZXM6IHRhbGtUaXRsZS5nZXRQcmVmaXhlZFRleHQoKSxcclxuXHRcdFx0dGxuYW1lc3BhY2U6IFwiMTBcIixcclxuXHRcdFx0dGxsaW1pdDogXCI1MDBcIixcclxuXHRcdFx0aW5kZXhwYWdlaWRzOiAxXHJcblx0XHR9KVxyXG5cdFx0XHQudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcclxuXHRcdFx0XHR2YXIgaWQgPSByZXN1bHQucXVlcnkucGFnZWlkcztcclxuXHRcdFx0XHR2YXIgdGVtcGxhdGVzID0gcmVzdWx0LnF1ZXJ5LnBhZ2VzW2lkXS50ZW1wbGF0ZXM7XHJcblx0XHRcdFxyXG5cdFx0XHRcdGlmICggIXRlbXBsYXRlcyApIHtcclxuXHRcdFx0XHRcdHJldHVybiBzZXR1cFJhdGVyKCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcclxuXHRcdFx0XHR2YXIgaGFzV2lraXByb2plY3QgPSB0ZW1wbGF0ZXMuc29tZSh0ZW1wbGF0ZSA9PiAvKFdpa2lQcm9qZWN0fFdQQmFubmVyKS8udGVzdCh0ZW1wbGF0ZS50aXRsZSkpO1xyXG5cdFx0XHRcclxuXHRcdFx0XHRpZiAoICFoYXNXaWtpcHJvamVjdCApIHtcclxuXHRcdFx0XHRcdHJldHVybiBzZXR1cFJhdGVyKCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcclxuXHRcdFx0fSxcclxuXHRcdFx0ZnVuY3Rpb24oY29kZSwganF4aHIpIHtcclxuXHRcdFx0Ly8gU2lsZW50bHkgaWdub3JlIGZhaWx1cmVzIChqdXN0IGxvZyB0byBjb25zb2xlKVxyXG5cdFx0XHRcdGNvbnNvbGUud2FybihcclxuXHRcdFx0XHRcdFwiW1JhdGVyXSBFcnJvciB3aGlsZSBjaGVja2luZyB3aGV0aGVyIHRvIGF1dG9zdGFydC5cIiArXHJcblx0XHRcdFx0KCBjb2RlID09IG51bGwgKSA/IFwiXCIgOiBcIiBcIiArIG1ha2VFcnJvck1zZyhjb2RlLCBqcXhocilcclxuXHRcdFx0XHQpO1xyXG5cdFx0XHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVqZWN0KCk7XHJcblx0XHRcdH0pO1xyXG5cdH0pO1xyXG5cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGF1dG9TdGFydDtcclxuLy8gPC9ub3dpa2k+IiwiaW1wb3J0IHtpc0FmdGVyRGF0ZX0gZnJvbSBcIi4vdXRpbFwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxuLyoqIHdyaXRlXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcclxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IHZhbFxyXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhbGVEYXlzIE51bWJlciBvZiBkYXlzIGFmdGVyIHdoaWNoIHRoZSBkYXRhIGJlY29tZXMgc3RhbGUgKHVzYWJsZSwgYnV0IHNob3VsZFxyXG4gKiAgYmUgdXBkYXRlZCBmb3IgbmV4dCB0aW1lKS5cclxuICogQHBhcmFtIHtOdW1iZXJ9IGV4cGlyeURheXMgTnVtYmVyIG9mIGRheXMgYWZ0ZXIgd2hpY2ggdGhlIGNhY2hlZCBkYXRhIG1heSBiZSBkZWxldGVkLlxyXG4gKi9cclxuY29uc3Qgd3JpdGUgPSBmdW5jdGlvbihrZXksIHZhbCwgc3RhbGVEYXlzLCBleHBpcnlEYXlzKSB7XHJcblx0dHJ5IHtcclxuXHRcdGNvbnN0IGRlZmF1bHRTdGFsZURheXMgPSAxO1xyXG5cdFx0Y29uc3QgZGVmYXVsdEV4cGlyeURheXMgPSAzMDtcclxuXHRcdGNvbnN0IG1pbGxpc2Vjb25kc1BlckRheSA9IDI0KjYwKjYwKjEwMDA7XHJcblxyXG5cdFx0Y29uc3Qgc3RhbGVEdXJhdGlvbiA9IChzdGFsZURheXMgfHwgZGVmYXVsdFN0YWxlRGF5cykqbWlsbGlzZWNvbmRzUGVyRGF5O1xyXG5cdFx0Y29uc3QgZXhwaXJ5RHVyYXRpb24gPSAoZXhwaXJ5RGF5cyB8fCBkZWZhdWx0RXhwaXJ5RGF5cykqbWlsbGlzZWNvbmRzUGVyRGF5O1xyXG5cclxuXHRcdGNvbnN0IHN0cmluZ1ZhbCA9IEpTT04uc3RyaW5naWZ5KHtcclxuXHRcdFx0dmFsdWU6IHZhbCxcclxuXHRcdFx0c3RhbGVEYXRlOiBuZXcgRGF0ZShEYXRlLm5vdygpICsgc3RhbGVEdXJhdGlvbikudG9JU09TdHJpbmcoKSxcclxuXHRcdFx0ZXhwaXJ5RGF0ZTogbmV3IERhdGUoRGF0ZS5ub3coKSArIGV4cGlyeUR1cmF0aW9uKS50b0lTT1N0cmluZygpXHJcblx0XHR9KTtcclxuXHRcdGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwiUmF0ZXItXCIra2V5LCBzdHJpbmdWYWwpO1xyXG5cdH0gIGNhdGNoKGUpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZW1wdHlcclxufTtcclxuLyoqIHJlYWRcclxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxyXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fFN0cmluZ3xOdWxsfSBDYWNoZWQgYXJyYXkgb3Igb2JqZWN0LCBvciBlbXB0eSBzdHJpbmcgaWYgbm90IHlldCBjYWNoZWQsXHJcbiAqICAgICAgICAgIG9yIG51bGwgaWYgdGhlcmUgd2FzIGVycm9yLlxyXG4gKi9cclxuY29uc3QgcmVhZCA9IGZ1bmN0aW9uKGtleSkge1xyXG5cdGxldCB2YWw7XHJcblx0dHJ5IHtcclxuXHRcdGNvbnN0IHN0cmluZ1ZhbCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiUmF0ZXItXCIra2V5KTtcclxuXHRcdGlmICggc3RyaW5nVmFsICE9PSBcIlwiICkge1xyXG5cdFx0XHR2YWwgPSBKU09OLnBhcnNlKHN0cmluZ1ZhbCk7XHJcblx0XHR9XHJcblx0fSAgY2F0Y2goZSkge1xyXG5cdFx0Y29uc29sZS5sb2coXCJbUmF0ZXJdIGVycm9yIHJlYWRpbmcgXCIgKyBrZXkgKyBcIiBmcm9tIGxvY2FsU3RvcmFnZSBjYWNoZTpcIik7XHJcblx0XHRjb25zb2xlLmxvZyhcclxuXHRcdFx0XCJcXHRcIiArIGUubmFtZSArIFwiIG1lc3NhZ2U6IFwiICsgZS5tZXNzYWdlICtcclxuXHRcdFx0KCBlLmF0ID8gXCIgYXQ6IFwiICsgZS5hdCA6IFwiXCIpICtcclxuXHRcdFx0KCBlLnRleHQgPyBcIiB0ZXh0OiBcIiArIGUudGV4dCA6IFwiXCIpXHJcblx0XHQpO1xyXG5cdH1cclxuXHRyZXR1cm4gdmFsIHx8IG51bGw7XHJcbn07XHJcblxyXG5jb25zdCBpc1JhdGVyS2V5ID0ga2V5ID0+IGtleSAmJiBrZXkuaW5kZXhPZihcIlJhdGVyLVwiKSA9PT0gMDtcclxuXHJcbmNvbnN0IGNsZWFySXRlbUlmSW52YWxpZCA9IGZ1bmN0aW9uKGtleSkge1xyXG5cdGlmICggIWlzUmF0ZXJLZXkoa2V5KSApIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblx0Y29uc3QgaXRlbSA9IHJlYWQoa2V5LnJlcGxhY2UoXCJSYXRlci1cIixcIlwiKSk7XHJcblx0Y29uc3QgaXNJbnZhbGlkID0gIWl0ZW0gfHwgIWl0ZW0uZXhwaXJ5RGF0ZSB8fCBpc0FmdGVyRGF0ZShpdGVtLmV4cGlyeURhdGUpO1xyXG5cdGlmICggaXNJbnZhbGlkICkge1xyXG5cdFx0bG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oa2V5KTtcclxuXHR9XHJcbn07XHJcblxyXG5jb25zdCBjbGVhckludmFsaWRJdGVtcyA9IGZ1bmN0aW9uKCkge1xyXG5cdC8vIExvb3AgYmFja3dhcmRzIGFzIGxvY2FsU3RvcmFnZSBsZW5ndGggd2lsbCBkZWNyZWFzZSBhcyBpdGVtcyBhcmUgcmVtb3ZlZFxyXG5cdGZvciAobGV0IGkgPSBsb2NhbFN0b3JhZ2UubGVuZ3RoOyBpID49IDA7IGktLSkge1xyXG5cdFx0c2V0VGltZW91dChjbGVhckl0ZW1JZkludmFsaWQsIDEwMCwgbG9jYWxTdG9yYWdlLmtleShpKSk7XHJcblx0fVxyXG59O1xyXG5cclxuY29uc3QgY2xlYXJBbGxJdGVtcyA9IGZ1bmN0aW9uKCkge1xyXG5cdC8vIExvb3AgYmFja3dhcmRzIGFzIGxvY2FsU3RvcmFnZSBsZW5ndGggd2lsbCBkZWNyZWFzZSBhcyBpdGVtcyBhcmUgcmVtb3ZlZFxyXG5cdGZvciAobGV0IGkgPSBsb2NhbFN0b3JhZ2UubGVuZ3RoOyBpID49IDA7IGktLSkge1xyXG5cdFx0bGV0IGtleSA9IGxvY2FsU3RvcmFnZS5rZXkoaSk7XHJcblx0XHRpZiAoaXNSYXRlcktleShrZXkpKSB7XHJcblx0XHRcdGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGtleSk7XHJcblx0XHR9XHJcblx0fVxyXG59O1xyXG5cclxuZXhwb3J0IHsgd3JpdGUsIHJlYWQsIGNsZWFySXRlbUlmSW52YWxpZCwgY2xlYXJJbnZhbGlkSXRlbXMsIGNsZWFyQWxsSXRlbXMgfTtcclxuLy8gPC9ub3dpa2k+IiwiLy8gPG5vd2lraT5cclxuY29uc3QgcGFja2FnZWpzb24gPSByZXF1aXJlKFwiLi4vcGFja2FnZS5qc29uXCIpO1xyXG52YXIgdmVyc2lvbiA9IHBhY2thZ2Vqc29uLnZlcnNpb247XHJcblxyXG4vLyBBIGdsb2JhbCBvYmplY3QgdGhhdCBzdG9yZXMgYWxsIHRoZSBwYWdlIGFuZCB1c2VyIGNvbmZpZ3VyYXRpb24gYW5kIHNldHRpbmdzXHJcbnZhciBjb25maWcgPSB7XHJcblx0Ly8gU2NyaXB0IGluZm9cclxuXHRzY3JpcHQ6IHtcclxuXHRcdC8vIEFkdmVydCB0byBhcHBlbmQgdG8gZWRpdCBzdW1tYXJpZXNcclxuXHRcdGFkdmVydDogIGAgKFtbV1A6UkFURVIjJHt2ZXJzaW9ufXxSYXRlcl1dKWAsXHJcblx0XHR2ZXJzaW9uOiB2ZXJzaW9uXHJcblx0fSxcclxuXHQvLyBEZWZhdWx0IHByZWZlcmVuY2VzLCBpZiB1c2VyIHN1YnBhZ2UgcmF0ZXJQcmVmcy5qc29uIGRvZXMgbm90IGV4aXN0XHJcblx0ZGVmYXVsdFByZWZzOiB7XHJcblx0XHRcImF1dG9zdGFydFwiOiBmYWxzZSxcclxuXHRcdFwiYXV0b3N0YXJ0UmVkaXJlY3RzXCI6IGZhbHNlLFxyXG5cdFx0XCJhdXRvc3RhcnROYW1lc3BhY2VzXCI6IFswXSxcclxuXHRcdFwibWluRm9yU2hlbGxcIjogMSxcclxuXHRcdFwiYnlwYXNzUmVkaXJlY3RzXCI6IHRydWUsXHJcblx0XHRcImF1dG9maWxsQ2xhc3NGcm9tT3RoZXJzXCI6IHRydWUsXHJcblx0XHRcImF1dG9maWxsQ2xhc3NGcm9tT3Jlc1wiOiB0cnVlLFxyXG5cdFx0XCJhdXRvZmlsbEltcG9ydGFuY2VcIjogdHJ1ZSxcclxuXHRcdFwiY29sbGFwc2VQYXJhbXNMb3dlckxpbWl0XCI6IDYsXHJcblx0XHRcIndhdGNobGlzdFwiOiBcInByZWZlcmVuY2VzXCJcclxuXHR9LFxyXG5cdC8vIE1lZGlhV2lraSBjb25maWd1cmF0aW9uIHZhbHVlc1xyXG5cdG13OiBtdy5jb25maWcuZ2V0KCBbXHJcblx0XHRcInNraW5cIixcclxuXHRcdFwid2dQYWdlTmFtZVwiLFxyXG5cdFx0XCJ3Z05hbWVzcGFjZU51bWJlclwiLFxyXG5cdFx0XCJ3Z1VzZXJOYW1lXCIsXHJcblx0XHRcIndnRm9ybWF0dGVkTmFtZXNwYWNlc1wiLFxyXG5cdFx0XCJ3Z01vbnRoTmFtZXNcIixcclxuXHRcdFwid2dSZXZpc2lvbklkXCIsXHJcblx0XHRcIndnU2NyaXB0UGF0aFwiLFxyXG5cdFx0XCJ3Z1NlcnZlclwiLFxyXG5cdFx0XCJ3Z0NhdGVnb3JpZXNcIixcclxuXHRcdFwid2dJc01haW5QYWdlXCJcclxuXHRdICksXHJcblx0YmFubmVyRGVmYXVsdHM6IHtcclxuXHRcdGNsYXNzZXM6IFtcclxuXHRcdFx0XCJGQVwiLFxyXG5cdFx0XHRcIkZMXCIsXHJcblx0XHRcdFwiQVwiLFxyXG5cdFx0XHRcIkdBXCIsXHJcblx0XHRcdFwiQlwiLFxyXG5cdFx0XHRcIkNcIixcclxuXHRcdFx0XCJTdGFydFwiLFxyXG5cdFx0XHRcIlN0dWJcIixcclxuXHRcdFx0XCJMaXN0XCJcclxuXHRcdF0sXHJcblx0XHRpbXBvcnRhbmNlczogW1xyXG5cdFx0XHRcIlRvcFwiLFxyXG5cdFx0XHRcIkhpZ2hcIixcclxuXHRcdFx0XCJNaWRcIixcclxuXHRcdFx0XCJMb3dcIlxyXG5cdFx0XSxcclxuXHRcdGV4dGVuZGVkQ2xhc3NlczogW1xyXG5cdFx0XHRcIkNhdGVnb3J5XCIsXHJcblx0XHRcdFwiRHJhZnRcIixcclxuXHRcdFx0XCJGaWxlXCIsXHJcblx0XHRcdFwiRk1cIixcclxuXHRcdFx0XCJQb3J0YWxcIixcclxuXHRcdFx0XCJQcm9qZWN0XCIsXHJcblx0XHRcdFwiVGVtcGxhdGVcIixcclxuXHRcdFx0XCJCcGx1c1wiLFxyXG5cdFx0XHRcIkZ1dHVyZVwiLFxyXG5cdFx0XHRcIkN1cnJlbnRcIixcclxuXHRcdFx0XCJEaXNhbWJpZ1wiLFxyXG5cdFx0XHRcIk5BXCIsXHJcblx0XHRcdFwiUmVkaXJlY3RcIixcclxuXHRcdFx0XCJCb29rXCJcclxuXHRcdF0sXHJcblx0XHRleHRlbmRlZEltcG9ydGFuY2VzOiBbXHJcblx0XHRcdFwiVG9wXCIsXHJcblx0XHRcdFwiSGlnaFwiLFxyXG5cdFx0XHRcIk1pZFwiLFxyXG5cdFx0XHRcIkxvd1wiLFxyXG5cdFx0XHRcIkJvdHRvbVwiLFxyXG5cdFx0XHRcIk5BXCJcclxuXHRcdF1cclxuXHR9LFxyXG5cdGN1c3RvbUJhbm5lcnM6IHtcclxuXHRcdFwiV2lraVByb2plY3QgTWlsaXRhcnkgaGlzdG9yeVwiOiB7XHJcblx0XHRcdGNsYXNzZXM6IFtcclxuXHRcdFx0XHRcIkZBXCIsXHJcblx0XHRcdFx0XCJGTFwiLFxyXG5cdFx0XHRcdFwiQVwiLFxyXG5cdFx0XHRcdFwiR0FcIixcclxuXHRcdFx0XHRcIkJcIixcclxuXHRcdFx0XHRcIkNcIixcclxuXHRcdFx0XHRcIlN0YXJ0XCIsXHJcblx0XHRcdFx0XCJTdHViXCIsXHJcblx0XHRcdFx0XCJMaXN0XCIsXHJcblx0XHRcdFx0XCJBTFwiLFxyXG5cdFx0XHRcdFwiQkxcIixcclxuXHRcdFx0XHRcIkNMXCIsXHJcblx0XHRcdFx0XCJDYXRlZ29yeVwiLFxyXG5cdFx0XHRcdFwiRHJhZnRcIixcclxuXHRcdFx0XHRcIkZpbGVcIixcclxuXHRcdFx0XHRcIlBvcnRhbFwiLFxyXG5cdFx0XHRcdFwiUHJvamVjdFwiLFxyXG5cdFx0XHRcdFwiVGVtcGxhdGVcIixcclxuXHRcdFx0XHRcIkRpc2FtYmlnXCIsXHJcblx0XHRcdFx0XCJSZWRpcmVjdFwiLFxyXG5cdFx0XHRcdFwiQm9va1wiXHRcdFx0XHJcblx0XHRcdF0sXHJcblx0XHRcdGltcG9ydGFuY2VzOiBbXVxyXG5cdFx0fSxcclxuXHRcdFwiV2lraVByb2plY3QgUG9ydGFsc1wiOiB7XHJcblx0XHRcdGNsYXNzZXM6IFtcclxuXHRcdFx0XHRcIkZQb1wiLFxyXG5cdFx0XHRcdFwiQ29tcGxldGVcIixcclxuXHRcdFx0XHRcIlN1YnN0YW50aWFsXCIsXHJcblx0XHRcdFx0XCJCYXNpY1wiLFxyXG5cdFx0XHRcdFwiSW5jb21wbGV0ZVwiLFxyXG5cdFx0XHRcdFwiTWV0YVwiLFxyXG5cdFx0XHRcdFwiTGlzdFwiLFxyXG5cdFx0XHRcdFwiQ2F0ZWdvcnlcIixcclxuXHRcdFx0XHRcIkRyYWZ0XCIsXHJcblx0XHRcdFx0XCJGaWxlXCIsXHJcblx0XHRcdFx0XCJQcm9qZWN0XCIsXHJcblx0XHRcdFx0XCJUZW1wbGF0ZVwiLFxyXG5cdFx0XHRcdFwiRGlzYW1iaWdcIixcclxuXHRcdFx0XHRcIk5BXCIsXHJcblx0XHRcdFx0XCJSZWRpcmVjdFwiXHJcblx0XHRcdF0sXHJcblx0XHRcdGltcG9ydGFuY2VzOiBbXHJcblx0XHRcdFx0XCJUb3BcIixcclxuXHRcdFx0XHRcIkhpZ2hcIixcclxuXHRcdFx0XHRcIk1pZFwiLFxyXG5cdFx0XHRcdFwiTG93XCIsXHJcblx0XHRcdFx0XCJCb3R0b21cIixcclxuXHRcdFx0XHRcIk5BXCJcclxuXHRcdFx0XVxyXG5cdFx0fSxcclxuXHRcdFwiV2lraVByb2plY3QgVmlkZW8gZ2FtZXNcIjoge1xyXG5cdFx0XHRjbGFzc2VzOiBbXHJcblx0XHRcdFx0XCJGQVwiLFwiRkxcIixcIkZNXCIsXCJHQVwiLFwiQlwiLFwiQ1wiLFwiU3RhcnRcIixcIlN0dWJcIixcIkxpc3RcIixcIkNhdGVnb3J5XCIsXCJEcmFmdFwiLFwiRmlsZVwiLFwiUG9ydGFsXCIsXCJQcm9qZWN0XCIsXCJUZW1wbGF0ZVwiLFwiRGlzYW1iaWdcIixcIlJlZGlyZWN0XCJcclxuXHRcdFx0XSxcclxuXHRcdFx0aW1wb3J0YW5jZXM6IFtcclxuXHRcdFx0XHRcIlRvcFwiLFwiSGlnaFwiLFwiTWlkXCIsXCJMb3dcIixcIk5BXCJcclxuXHRcdFx0XVxyXG5cdFx0fVxyXG5cdH0sXHJcblx0c2hlbGxUZW1wbGF0ZXM6IFtcclxuXHRcdFwiV2lraVByb2plY3QgYmFubmVyIHNoZWxsXCIsXHJcblx0XHRcIldpa2lQcm9qZWN0QmFubmVyc1wiLFxyXG5cdFx0XCJXaWtpUHJvamVjdCBCYW5uZXJzXCIsXHJcblx0XHRcIldQQlwiLFxyXG5cdFx0XCJXUEJTXCIsXHJcblx0XHRcIldpa2lwcm9qZWN0YmFubmVyc2hlbGxcIixcclxuXHRcdFwiV2lraVByb2plY3QgQmFubmVyIFNoZWxsXCIsXHJcblx0XHRcIldwYlwiLFxyXG5cdFx0XCJXUEJhbm5lclNoZWxsXCIsXHJcblx0XHRcIldwYnNcIixcclxuXHRcdFwiV2lraXByb2plY3RiYW5uZXJzXCIsXHJcblx0XHRcIldQIEJhbm5lciBTaGVsbFwiLFxyXG5cdFx0XCJXUCBiYW5uZXIgc2hlbGxcIixcclxuXHRcdFwiQmFubmVyc2hlbGxcIixcclxuXHRcdFwiV2lraXByb2plY3QgYmFubmVyIHNoZWxsXCIsXHJcblx0XHRcIldpa2lQcm9qZWN0IEJhbm5lcnMgU2hlbGxcIixcclxuXHRcdFwiV2lraVByb2plY3RCYW5uZXIgU2hlbGxcIixcclxuXHRcdFwiV2lraVByb2plY3RCYW5uZXJTaGVsbFwiLFxyXG5cdFx0XCJXaWtpUHJvamVjdCBCYW5uZXJTaGVsbFwiLFxyXG5cdFx0XCJXaWtpcHJvamVjdEJhbm5lclNoZWxsXCIsXHJcblx0XHRcIldpa2lQcm9qZWN0IGJhbm5lciBzaGVsbC9yZWRpcmVjdFwiLFxyXG5cdFx0XCJXaWtpUHJvamVjdCBTaGVsbFwiLFxyXG5cdFx0XCJCYW5uZXIgc2hlbGxcIixcclxuXHRcdFwiU2NvcGUgc2hlbGxcIixcclxuXHRcdFwiUHJvamVjdCBzaGVsbFwiLFxyXG5cdFx0XCJXaWtpUHJvamVjdCBiYW5uZXJcIlxyXG5cdF0sXHJcblx0ZGVmYXVsdFBhcmFtZXRlckRhdGE6IHtcclxuXHRcdFwiYXV0b1wiOiB7XHJcblx0XHRcdFwibGFiZWxcIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJBdXRvLXJhdGVkXCJcclxuXHRcdFx0fSxcclxuXHRcdFx0XCJkZXNjcmlwdGlvblwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIkF1dG9tYXRpY2FsbHkgcmF0ZWQgYnkgYSBib3QuIEFsbG93ZWQgdmFsdWVzOiBbJ3llcyddLlwiXHJcblx0XHRcdH0sXHJcblx0XHRcdFwiYXV0b3ZhbHVlXCI6IFwieWVzXCJcclxuXHRcdH0sXHJcblx0XHRcImxpc3Rhc1wiOiB7XHJcblx0XHRcdFwibGFiZWxcIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJMaXN0IGFzXCJcclxuXHRcdFx0fSxcclxuXHRcdFx0XCJkZXNjcmlwdGlvblwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIlNvcnRrZXkgZm9yIHRhbGsgcGFnZVwiXHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblx0XHRcInNtYWxsXCI6IHtcclxuXHRcdFx0XCJsYWJlbFwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIlNtYWxsP1wiLFxyXG5cdFx0XHR9LFxyXG5cdFx0XHRcImRlc2NyaXB0aW9uXCI6IHtcclxuXHRcdFx0XHRcImVuXCI6IFwiRGlzcGxheSBhIHNtYWxsIHZlcnNpb24uIEFsbG93ZWQgdmFsdWVzOiBbJ3llcyddLlwiXHJcblx0XHRcdH0sXHJcblx0XHRcdFwiYXV0b3ZhbHVlXCI6IFwieWVzXCJcclxuXHRcdH0sXHJcblx0XHRcImF0dGVudGlvblwiOiB7XHJcblx0XHRcdFwibGFiZWxcIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJBdHRlbnRpb24gcmVxdWlyZWQ/XCIsXHJcblx0XHRcdH0sXHJcblx0XHRcdFwiZGVzY3JpcHRpb25cIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJJbW1lZGlhdGUgYXR0ZW50aW9uIHJlcXVpcmVkLiBBbGxvd2VkIHZhbHVlczogWyd5ZXMnXS5cIlxyXG5cdFx0XHR9LFxyXG5cdFx0XHRcImF1dG92YWx1ZVwiOiBcInllc1wiXHJcblx0XHR9LFxyXG5cdFx0XCJuZWVkcy1pbWFnZVwiOiB7XHJcblx0XHRcdFwibGFiZWxcIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJOZWVkcyBpbWFnZT9cIixcclxuXHRcdFx0fSxcclxuXHRcdFx0XCJkZXNjcmlwdGlvblwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIlJlcXVlc3QgdGhhdCBhbiBpbWFnZSBvciBwaG90b2dyYXBoIG9mIHRoZSBzdWJqZWN0IGJlIGFkZGVkIHRvIHRoZSBhcnRpY2xlLiBBbGxvd2VkIHZhbHVlczogWyd5ZXMnXS5cIlxyXG5cdFx0XHR9LFxyXG5cdFx0XHRcImFsaWFzZXNcIjogW1xyXG5cdFx0XHRcdFwibmVlZHMtcGhvdG9cIlxyXG5cdFx0XHRdLFxyXG5cdFx0XHRcImF1dG92YWx1ZVwiOiBcInllc1wiLFxyXG5cdFx0XHRcInN1Z2dlc3RlZFwiOiB0cnVlXHJcblx0XHR9LFxyXG5cdFx0XCJuZWVkcy1pbmZvYm94XCI6IHtcclxuXHRcdFx0XCJsYWJlbFwiOiB7XHJcblx0XHRcdFx0XCJlblwiOiBcIk5lZWRzIGluZm9ib3g/XCIsXHJcblx0XHRcdH0sXHJcblx0XHRcdFwiZGVzY3JpcHRpb25cIjoge1xyXG5cdFx0XHRcdFwiZW5cIjogXCJSZXF1ZXN0IHRoYXQgYW4gaW5mb2JveCBiZSBhZGRlZCB0byB0aGUgYXJ0aWNsZS4gQWxsb3dlZCB2YWx1ZXM6IFsneWVzJ10uXCJcclxuXHRcdFx0fSxcclxuXHRcdFx0XCJhbGlhc2VzXCI6IFtcclxuXHRcdFx0XHRcIm5lZWRzLXBob3RvXCJcclxuXHRcdFx0XSxcclxuXHRcdFx0XCJhdXRvdmFsdWVcIjogXCJ5ZXNcIixcclxuXHRcdFx0XCJzdWdnZXN0ZWRcIjogdHJ1ZVxyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNvbmZpZztcclxuLy8gPC9ub3dpa2k+IiwiLy8gPG5vd2lraT5cclxuXHJcbi8vIEF0dHJpYnV0aW9uOiBEaWZmIHN0eWxlcyBiYXNlZCBvbiA8aHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvV2lraXBlZGlhOkF1dG9XaWtpQnJvd3Nlci9zdHlsZS5jc3M+XHJcbmNvbnN0IHN0eWxlcyA9IGB0YWJsZS5kaWZmLCB0ZC5kaWZmLW90aXRsZSwgdGQuZGlmZi1udGl0bGUgeyB0YWJsZS1sYXlvdXQ6IGF1dG8gIWltcG9ydGFudDs7IH1cclxudGQuZGlmZi1vdGl0bGUsIHRkLmRpZmYtbnRpdGxlIHsgdGV4dC1hbGlnbjogY2VudGVyOyB9XHJcbnRkLmRpZmYtbWFya2VyIHsgdGV4dC1hbGlnbjogcmlnaHQ7IGZvbnQtd2VpZ2h0OiBib2xkOyBmb250LXNpemU6IDEuMjVlbTsgfVxyXG50ZC5kaWZmLWxpbmVubyB7IGZvbnQtd2VpZ2h0OiBib2xkOyB9XHJcbnRkLmRpZmYtYWRkZWRsaW5lLCB0ZC5kaWZmLWRlbGV0ZWRsaW5lLCB0ZC5kaWZmLWNvbnRleHQgeyBmb250LXNpemU6IDg4JTsgdmVydGljYWwtYWxpZ246IHRvcDsgd2hpdGUtc3BhY2U6IC1tb3otcHJlLXdyYXA7IHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsgfVxyXG50ZC5kaWZmLWFkZGVkbGluZSwgdGQuZGlmZi1kZWxldGVkbGluZSB7IGJvcmRlci1zdHlsZTogc29saWQ7IGJvcmRlci13aWR0aDogMXB4IDFweCAxcHggNHB4OyBib3JkZXItcmFkaXVzOiAwLjMzZW07IH1cclxudGQuZGlmZi1hZGRlZGxpbmUgeyBib3JkZXItY29sb3I6ICNhM2QzZmY7IH1cclxudGQuZGlmZi1kZWxldGVkbGluZSB7IGJvcmRlci1jb2xvcjogI2ZmZTQ5YzsgfVxyXG50ZC5kaWZmLWNvbnRleHQgeyBiYWNrZ3JvdW5kOiAjZjNmM2YzOyBjb2xvcjogIzMzMzMzMzsgYm9yZGVyLXN0eWxlOiBzb2xpZDsgYm9yZGVyLXdpZHRoOiAxcHggMXB4IDFweCA0cHg7IGJvcmRlci1jb2xvcjogI2U2ZTZlNjsgYm9yZGVyLXJhZGl1czogMC4zM2VtOyB9XHJcbi5kaWZmY2hhbmdlIHsgZm9udC13ZWlnaHQ6IGJvbGQ7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgfVxyXG50YWJsZS5kaWZmIHtcclxuICAgIGJvcmRlcjogbm9uZTtcclxuICAgIHdpZHRoOiA5OCU7IGJvcmRlci1zcGFjaW5nOiA0cHg7XHJcbiAgICB0YWJsZS1sYXlvdXQ6IGZpeGVkOyAvKiBFbnN1cmVzIHRoYXQgY29sdW1zIGFyZSBvZiBlcXVhbCB3aWR0aCAqL1xyXG59XHJcbnRkLmRpZmYtYWRkZWRsaW5lIC5kaWZmY2hhbmdlLCB0ZC5kaWZmLWRlbGV0ZWRsaW5lIC5kaWZmY2hhbmdlIHsgYm9yZGVyLXJhZGl1czogMC4zM2VtOyBwYWRkaW5nOiAwLjI1ZW0gMDsgfVxyXG50ZC5kaWZmLWFkZGVkbGluZSAuZGlmZmNoYW5nZSB7XHRiYWNrZ3JvdW5kOiAjZDhlY2ZmOyB9XHJcbnRkLmRpZmYtZGVsZXRlZGxpbmUgLmRpZmZjaGFuZ2UgeyBiYWNrZ3JvdW5kOiAjZmVlZWM4OyB9XHJcbnRhYmxlLmRpZmYgdGQge1x0cGFkZGluZzogMC4zM2VtIDAuNjZlbTsgfVxyXG50YWJsZS5kaWZmIGNvbC5kaWZmLW1hcmtlciB7IHdpZHRoOiAyJTsgfVxyXG50YWJsZS5kaWZmIGNvbC5kaWZmLWNvbnRlbnQgeyB3aWR0aDogNDglOyB9XHJcbnRhYmxlLmRpZmYgdGQgZGl2IHtcclxuICAgIC8qIEZvcmNlLXdyYXAgdmVyeSBsb25nIGxpbmVzIHN1Y2ggYXMgVVJMcyBvciBwYWdlLXdpZGVuaW5nIGNoYXIgc3RyaW5ncy4gKi9cclxuICAgIHdvcmQtd3JhcDogYnJlYWstd29yZDtcclxuICAgIC8qIEFzIGZhbGxiYWNrIChGRjwzLjUsIE9wZXJhIDwxMC41KSwgc2Nyb2xsYmFycyB3aWxsIGJlIGFkZGVkIGZvciB2ZXJ5IHdpZGUgY2VsbHNcclxuICAgICAgICBpbnN0ZWFkIG9mIHRleHQgb3ZlcmZsb3dpbmcgb3Igd2lkZW5pbmcgKi9cclxuICAgIG92ZXJmbG93OiBhdXRvO1xyXG59YCArXHJcblxyXG4vLyBPdmVycmlkZSBPT1VJIHdpbmRvdyBtYW5hZ2VyIHByZXZlbnRpbmcgYmFja2dyb3VuZCBzY3JvbGxpbmcvaW50ZXJhY3Rpb24uXHJcbi8vIFNjb3BlZCB0byBSYXRlcidzIG93biB3aW5kb3cgbWFuYWdlciAoLnJhdGVyLXdpbmRvd01hbmFnZXIpLCBzbyB0aGF0IG90aGVyXHJcbi8vIE9PVUkgZGlhbG9ncyAoZS5nLiBPTy51aS5jb25maXJtIGluICNtdy10ZWxlcG9ydC10YXJnZXQpIGtlZXAgdGhlaXIgZGVmYXVsdFxyXG4vLyBmaXhlZCBwb3NpdGlvbmluZyBhbmQgcmVtYWluIHZpc2libGUuXHJcbmBodG1sIGJvZHkucmF0ZXItbWFpbldpbmRvdy1vcGVuIHtcclxuXHRwb3NpdGlvbjogdW5zZXQ7XHJcblx0b3ZlcmZsb3c6IHVuc2V0O1xyXG59XHJcbmh0bWwgYm9keS5yYXRlci1tYWluV2luZG93LW9wZW4gLnJhdGVyLXdpbmRvd01hbmFnZXIgPiAub28tdWktZGlhbG9nLm9vLXVpLXdpbmRvdy1hY3RpdmUge1xyXG4gICAgcG9zaXRpb246IHN0YXRpYztcclxuICAgIHBhZGRpbmc6IDA7XHJcbn1gICtcclxuLy8gSW5jcmVhc2Ugei1pbmRleCwgdG8gYmUgYWJvdmUgc2tpbiBtZW51cyBldGM7IHNtb290aCB0cmFuc2l0aW9uIGZvciBkcmFnZ2luZyAodHJhbnNmb3JtOnRyYW5zbGF0ZSlcclxuLy8gNDAwIGtlZXBzIFJhdGVyIGFib3ZlIFRpbWVsZXNzIHNpZGViYXIgZHJvcGRvd25zICguc2lkZWJhci1pbm5lciwgMzUwKSAvIG1lbnVzLWNvdmVyICgzMDApIC9cclxuLy8gZml4ZWQgaGVhZGVyICgyMDApLCBidXQgYmVsb3cgI213LXRlbGVwb3J0LXRhcmdldCAoNDUwKSBzbyBPTy51aS5jb25maXJtIGRpYWxvZ3Mgc3RheSBvbiB0b3AuXHJcbmBodG1sIGJvZHkucmF0ZXItbWFpbldpbmRvdy1vcGVuIC5yYXRlci13aW5kb3dNYW5hZ2VyID4gLm9vLXVpLWRpYWxvZy5vby11aS13aW5kb3ctYWN0aXZlID4gZGl2IHtcclxuICAgIHotaW5kZXg6IDQwMDtcclxuICAgIHRyYW5zaXRpb246IGFsbCAwLjI1cyBlYXNlLW91dCAwcywgdHJhbnNmb3JtIDBzICFpbXBvcnRhbnRcclxufVxyXG5gO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgc3R5bGVzO1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgQVBJLCB7IG1ha2VFcnJvck1zZyB9IGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQgeyBpc0FmdGVyRGF0ZSB9IGZyb20gXCIuL3V0aWxcIjtcclxuaW1wb3J0ICogYXMgY2FjaGUgZnJvbSBcIi4vY2FjaGVcIjtcclxuLy8gPG5vd2lraT5cclxuXHJcbnZhciBjYWNoZUJhbm5lcnMgPSBmdW5jdGlvbihiYW5uZXJzKSB7XHJcblx0Y2FjaGUud3JpdGUoXCJiYW5uZXJzXCIsIGJhbm5lcnMsIDIsIDYwKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIGJhbm5lcnMvb3B0aW9ucyBmcm9tIHRoZSBBcGlcclxuICogXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlfSBSZXNvbHZlZCB3aXRoOiBiYW5uZXJzIG9iamVjdCwgYmFubmVyT3B0aW9ucyBhcnJheVxyXG4gKi9cclxudmFyIGdldExpc3RPZkJhbm5lcnNGcm9tQXBpID0gZnVuY3Rpb24oKSB7XHJcblxyXG5cdHZhciBmaW5pc2hlZFByb21pc2UgPSAkLkRlZmVycmVkKCk7XHJcblxyXG5cdHZhciBxdWVyeVNrZWxldG9uID0ge1xyXG5cdFx0YWN0aW9uOiBcInF1ZXJ5XCIsXHJcblx0XHRmb3JtYXQ6IFwianNvblwiLFxyXG5cdFx0bGlzdDogXCJjYXRlZ29yeW1lbWJlcnNcIixcclxuXHRcdGNtcHJvcDogXCJ0aXRsZVwiLFxyXG5cdFx0Y21uYW1lc3BhY2U6IFwiMTBcIixcclxuXHRcdGNtbGltaXQ6IFwiNTAwXCJcclxuXHR9O1xyXG5cclxuXHR2YXIgY2F0ZWdvcmllcyA9IFtcclxuXHRcdHtcclxuXHRcdFx0dGl0bGU6IFwiQ2F0ZWdvcnk6V2lraVByb2plY3QgYmFubmVycyB3aXRoIHF1YWxpdHkgYXNzZXNzbWVudFwiLFxyXG5cdFx0XHRhYmJyZXZpYXRpb246IFwid2l0aFJhdGluZ3NcIixcclxuXHRcdFx0YmFubmVyczogW10sXHJcblx0XHRcdHByb2Nlc3NlZDogJC5EZWZlcnJlZCgpXHJcblx0XHR9LFxyXG5cdFx0e1xyXG5cdFx0XHR0aXRsZTogXCJDYXRlZ29yeTpXaWtpUHJvamVjdCBiYW5uZXJzIHdpdGhvdXQgcXVhbGl0eSBhc3Nlc3NtZW50XCIsXHJcblx0XHRcdGFiYnJldmlhdGlvbjogXCJ3aXRob3V0UmF0aW5nc1wiLFxyXG5cdFx0XHRiYW5uZXJzOiBbXSxcclxuXHRcdFx0cHJvY2Vzc2VkOiAkLkRlZmVycmVkKClcclxuXHRcdH0sXHJcblx0XHR7XHJcblx0XHRcdHRpdGxlOiBcIkNhdGVnb3J5Oldpa2lQcm9qZWN0IGJhbm5lciB3cmFwcGVyIHRlbXBsYXRlc1wiLFxyXG5cdFx0XHRhYmJyZXZpYXRpb246IFwid3JhcHBlcnNcIixcclxuXHRcdFx0YmFubmVyczogW10sXHJcblx0XHRcdHByb2Nlc3NlZDogJC5EZWZlcnJlZCgpXHJcblx0XHR9LFxyXG5cdFx0e1xyXG5cdFx0XHR0aXRsZTogXCJDYXRlZ29yeTpXaWtpUHJvamVjdCBiYW5uZXIgdGVtcGxhdGVzIG5vdCBiYXNlZCBvbiBXUEJhbm5lck1ldGFcIixcclxuXHRcdFx0YWJicmV2aWF0aW9uOiBcIm5vdFdQQk1cIixcclxuXHRcdFx0YmFubmVyczogW10sXHJcblx0XHRcdHByb2Nlc3NlZDogJC5EZWZlcnJlZCgpXHJcblx0XHR9LFxyXG5cdFx0e1xyXG5cdFx0XHR0aXRsZTogXCJDYXRlZ29yeTpJbmFjdGl2ZSBXaWtpUHJvamVjdCBiYW5uZXJzXCIsXHJcblx0XHRcdGFiYnJldmlhdGlvbjogXCJpbmFjdGl2ZVwiLFxyXG5cdFx0XHRiYW5uZXJzOiBbXSxcclxuXHRcdFx0cHJvY2Vzc2VkOiAkLkRlZmVycmVkKClcclxuXHRcdH0sXHJcblx0XHR7XHJcblx0XHRcdHRpdGxlOiBcIkNhdGVnb3J5OldyYXBwZXIgdGVtcGxhdGVzIGZvciBXaWtpUHJvamVjdCBXb21lbiBpbiBSZWRcIixcclxuXHRcdFx0YWJicmV2aWF0aW9uOiBcIndpclwiLFxyXG5cdFx0XHRiYW5uZXJzOiBbXSxcclxuXHRcdFx0cHJvY2Vzc2VkOiAkLkRlZmVycmVkKClcclxuXHRcdH1cclxuXHRdO1xyXG5cclxuXHR2YXIgcHJvY2Vzc1F1ZXJ5ID0gZnVuY3Rpb24ocmVzdWx0LCBjYXRJbmRleCkge1xyXG5cdFx0aWYgKCAhcmVzdWx0LnF1ZXJ5IHx8ICFyZXN1bHQucXVlcnkuY2F0ZWdvcnltZW1iZXJzICkge1xyXG5cdFx0XHQvLyBObyByZXN1bHRzXHJcblx0XHRcdC8vIFRPRE86IGVycm9yIG9yIHdhcm5pbmcgKioqKioqKipcclxuXHRcdFx0ZmluaXNoZWRQcm9taXNlLnJlamVjdCgpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdC8vIEdhdGhlciB0aXRsZXMgaW50byBhcnJheSAtIGV4Y2x1ZGluZyBcIlRlbXBsYXRlOlwiIHByZWZpeFxyXG5cdFx0dmFyIHJlc3VsdFRpdGxlcyA9IHJlc3VsdC5xdWVyeS5jYXRlZ29yeW1lbWJlcnMubWFwKGZ1bmN0aW9uKGluZm8pIHtcclxuXHRcdFx0cmV0dXJuIGluZm8udGl0bGUuc2xpY2UoOSk7XHJcblx0XHR9KTtcclxuXHRcdEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNhdGVnb3JpZXNbY2F0SW5kZXhdLmJhbm5lcnMsIHJlc3VsdFRpdGxlcyk7XHJcblx0XHRcclxuXHRcdC8vIENvbnRpbnVlIHF1ZXJ5IGlmIG5lZWRlZFxyXG5cdFx0aWYgKCByZXN1bHQuY29udGludWUgKSB7XHJcblx0XHRcdGRvQXBpUXVlcnkoJC5leHRlbmQoY2F0ZWdvcmllc1tjYXRJbmRleF0ucXVlcnksIHJlc3VsdC5jb250aW51ZSksIGNhdEluZGV4KTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHRjYXRlZ29yaWVzW2NhdEluZGV4XS5wcm9jZXNzZWQucmVzb2x2ZSgpO1xyXG5cdH07XHJcblxyXG5cdHZhciBkb0FwaVF1ZXJ5ID0gZnVuY3Rpb24ocSwgY2F0SW5kZXgpIHtcclxuXHRcdEFQSS5nZXQoIHEgKVxyXG5cdFx0XHQuZG9uZSggZnVuY3Rpb24ocmVzdWx0KSB7XHJcblx0XHRcdFx0cHJvY2Vzc1F1ZXJ5KHJlc3VsdCwgY2F0SW5kZXgpO1xyXG5cdFx0XHR9IClcclxuXHRcdFx0LmZhaWwoIGZ1bmN0aW9uKGNvZGUsIGpxeGhyKSB7XHJcblx0XHRcdFx0Y29uc29sZS53YXJuKFwiW1JhdGVyXSBcIiArIG1ha2VFcnJvck1zZyhjb2RlLCBqcXhociwgXCJDb3VsZCBub3QgcmV0cmlldmUgcGFnZXMgZnJvbSBbWzpcIiArIHEuY210aXRsZSArIFwiXV1cIikpO1xyXG5cdFx0XHRcdGZpbmlzaGVkUHJvbWlzZS5yZWplY3QoKTtcclxuXHRcdFx0fSApO1xyXG5cdH07XHJcblx0XHJcblx0Y2F0ZWdvcmllcy5mb3JFYWNoKGZ1bmN0aW9uKGNhdCwgaW5kZXgsIGFycikge1xyXG5cdFx0Y2F0LnF1ZXJ5ID0gJC5leHRlbmQoIHsgXCJjbXRpdGxlXCI6Y2F0LnRpdGxlIH0sIHF1ZXJ5U2tlbGV0b24gKTtcclxuXHRcdCQud2hlbiggYXJyW2luZGV4LTFdICYmIGFycltpbmRleC0xXS5wcm9jZXNzZWQgfHwgdHJ1ZSApLnRoZW4oZnVuY3Rpb24oKXtcclxuXHRcdFx0ZG9BcGlRdWVyeShjYXQucXVlcnksIGluZGV4KTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdFxyXG5cdGNhdGVnb3JpZXNbY2F0ZWdvcmllcy5sZW5ndGgtMV0ucHJvY2Vzc2VkLnRoZW4oZnVuY3Rpb24oKXtcclxuXHRcdGxldCBiYW5uZXJzID0ge307XHJcblx0XHRjYXRlZ29yaWVzLmZvckVhY2goY2F0T2JqZWN0ID0+IHtcclxuXHRcdFx0YmFubmVyc1tjYXRPYmplY3QuYWJicmV2aWF0aW9uXSA9IGNhdE9iamVjdC5iYW5uZXJzO1xyXG5cdFx0fSk7XHJcblx0XHRcclxuXHRcdGZpbmlzaGVkUHJvbWlzZS5yZXNvbHZlKGJhbm5lcnMpO1xyXG5cdH0pO1xyXG5cdFxyXG5cdHJldHVybiBmaW5pc2hlZFByb21pc2U7XHJcbn07XHJcblxyXG4vKipcclxuICogR2V0cyBiYW5uZXJzIGZyb20gY2FjaGUsIGlmIHRoZXJlIGFuZCBub3QgdG9vIG9sZFxyXG4gKiBcclxuICogQHJldHVybnMge1Byb21pc2V9IFJlc29sdmVkIHdpdGggYmFubmVycyBvYmplY3RcclxuICovXHJcbnZhciBnZXRCYW5uZXJzRnJvbUNhY2hlID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIGNhY2hlZEJhbm5lcnMgPSBjYWNoZS5yZWFkKFwiYmFubmVyc1wiKTtcclxuXHRpZiAoXHJcblx0XHQhY2FjaGVkQmFubmVycyB8fFxyXG5cdFx0IWNhY2hlZEJhbm5lcnMudmFsdWUgfHxcclxuXHRcdCFjYWNoZWRCYW5uZXJzLnN0YWxlRGF0ZVxyXG5cdCkge1xyXG5cdFx0cmV0dXJuICQuRGVmZXJyZWQoKS5yZWplY3QoKTtcclxuXHR9XHJcblx0aWYgKCBpc0FmdGVyRGF0ZShjYWNoZWRCYW5uZXJzLnN0YWxlRGF0ZSkgKSB7XHJcblx0XHQvLyBVcGRhdGUgaW4gdGhlIGJhY2tncm91bmQ7IHN0aWxsIHVzZSBvbGQgbGlzdCB1bnRpbCB0aGVuICBcclxuXHRcdGdldExpc3RPZkJhbm5lcnNGcm9tQXBpKCkudGhlbihjYWNoZUJhbm5lcnMpO1xyXG5cdH1cclxuXHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlc29sdmUoY2FjaGVkQmFubmVycy52YWx1ZSk7XHJcbn07XHJcblxyXG4vKipcclxuICogR2V0cyBiYW5uZXIgbmFtZXMsIGdyb3VwZWQgYnkgdHlwZSAod2l0aFJhdGluZ3MsIHdpdGhvdXRSYXRpbmdzLCB3cmFwcGVycywgbm90V1BCTSlcclxuICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gT2JqZWN0IG9mIHN0cmluZyBhcnJheXMga2V5ZWQgYnkgdHlwZSAod2l0aFJhdGluZ3MsIHdpdGhvdXRSYXRpbmdzLCB3cmFwcGVycywgbm90V1BCTSlcclxuICovXHJcbnZhciBnZXRCYW5uZXJOYW1lcyA9ICgpID0+IGdldEJhbm5lcnNGcm9tQ2FjaGUoKVxyXG5cdC50aGVuKCBiYW5uZXJzID0+IHtcclxuXHRcdC8vIEVuc3VyZSBhbGwga2V5cyBleGlzdFxyXG5cdFx0aWYgKCFiYW5uZXJzLndpdGhSYXRpbmdzIHx8ICFiYW5uZXJzLndpdGhvdXRSYXRpbmdzIHx8ICFiYW5uZXJzLndyYXBwZXJzIHx8ICFiYW5uZXJzLm5vdFdQQk0gfHwgIWJhbm5lcnMuaW5hY3RpdmUgfHwgIWJhbm5lcnMud2lyKSB7XHJcblx0XHRcdGdldExpc3RPZkJhbm5lcnNGcm9tQXBpKCkudGhlbihjYWNoZUJhbm5lcnMpO1xyXG5cdFx0XHRyZXR1cm4gJC5leHRlbmQoXHJcblx0XHRcdFx0eyB3aXRoUmF0aW5nczogW10sIHdpdGhvdXRSYXRpbmdzOiBbXSwgd3JhcHBlcnM6IFtdLCBub3RXUEJNOiBbXSwgaW5hY3RpdmU6IFtdLCB3aXI6IFtdIH0sXHJcblx0XHRcdFx0YmFubmVyc1xyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gU3VjY2VzczogcGFzcyB0aHJvdWdoXHJcblx0XHRyZXR1cm4gYmFubmVycztcclxuXHR9IClcclxuXHQuY2F0Y2goICgpID0+IHtcclxuXHRcdC8vIEZhaWx1cmU6IGdldCBmcm9tIEFwaSwgdGhlbiBjYWNoZSB0aGVtXHJcblx0XHRsZXQgYmFubmVyc1Byb21pc2UgPSBnZXRMaXN0T2ZCYW5uZXJzRnJvbUFwaSgpO1xyXG5cdFx0YmFubmVyc1Byb21pc2UudGhlbihjYWNoZUJhbm5lcnMpO1xyXG5cdFx0cmV0dXJuIGJhbm5lcnNQcm9taXNlO1xyXG5cdH0gKTtcclxuXHJcbmV4cG9ydCB7IGdldEJhbm5lck5hbWVzIH07XHJcbi8vIDwvbm93aWtpPiIsImltcG9ydCBBUEkgZnJvbSBcIi4vYXBpXCI7XHJcbmltcG9ydCB7IGlzQWZ0ZXJEYXRlIH0gZnJvbSBcIi4vdXRpbFwiO1xyXG5pbXBvcnQgY29uZmlnIGZyb20gXCIuL2NvbmZpZ1wiO1xyXG5pbXBvcnQgKiBhcyBjYWNoZSBmcm9tIFwiLi9jYWNoZVwiO1xyXG4vLyA8bm93aWtpPlxyXG5cclxuY29uc3QgcHJlZnNQYWdlID0gYFVzZXI6JHttdy5jb25maWcuZ2V0KFwid2dVc2VyTmFtZVwiKX0vcmF0ZXJQcmVmcy5qc29uYDtcclxuXHJcbmNvbnN0IHdyaXRlUHJlZnNUb0NhY2hlID0gcHJlZnMgPT4gY2FjaGUud3JpdGUoXHJcblx0XCJwcmVmc1wiLFxyXG5cdHByZWZzLFxyXG5cdCgxLzI0LzYwKSoxLCAvLyAxIG1pblxyXG5cdCgxLzI0LzYwKSoxICAvLyAxIG1pblxyXG4pO1xyXG5cclxuY29uc3QgZ2V0UHJlZnNGcm9tQXBpID0gZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIEFQSS5nZXQoe1xyXG5cdFx0XCJhY3Rpb25cIjogXCJxdWVyeVwiLFxyXG5cdFx0XCJmb3JtYXRcIjogXCJqc29uXCIsXHJcblx0XHRcInByb3BcIjogXCJyZXZpc2lvbnNcIixcclxuXHRcdFwidGl0bGVzXCI6IHByZWZzUGFnZSxcclxuXHRcdFwicnZwcm9wXCI6IFwiY29udGVudFwiLFxyXG5cdFx0XCJydnNsb3RzXCI6IFwibWFpblwiXHJcblx0fSkudGhlbihyZXNwb25zZSA9PiB7XHJcblx0XHRjb25zdCBwYWdlID0gcmVzcG9uc2UucXVlcnkucGFnZXNbT2JqZWN0LmtleXMocmVzcG9uc2UucXVlcnkucGFnZXMpWzBdXTtcclxuXHRcdGlmICghcGFnZS5wYWdlaWQgfHwgcGFnZS5taXNzaW5nPT09XCJcIikge1xyXG5cdFx0XHRyZXR1cm4gY29uZmlnLmRlZmF1bHRQcmVmcztcclxuXHRcdH1cclxuXHRcdGxldCBwcmVmcztcclxuXHRcdHRyeSB7XHJcblx0XHRcdHByZWZzID0gSlNPTi5wYXJzZSggcGFnZS5yZXZpc2lvbnNbMF0uc2xvdHMubWFpbltcIipcIl0gKTtcclxuXHRcdH0gY2F0Y2goZSkge1xyXG5cdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlamVjdChcIkpTT04tcGFyc2luZy1lcnJvclwiLCBlKTtcclxuXHRcdH1cclxuXHRcdHdyaXRlUHJlZnNUb0NhY2hlKHByZWZzKTtcclxuXHRcdHJldHVybiBwcmVmcztcclxuXHR9KTtcclxufTtcclxuXHJcbmNvbnN0IGdldFByZWZzRnJvbUNhY2hlID0gZnVuY3Rpb24oKSB7XHJcblx0dmFyIGNhY2hlZFByZWZzID0gY2FjaGUucmVhZChcInByZWZzXCIpO1xyXG5cdGlmIChcclxuXHRcdCFjYWNoZWRQcmVmcyB8fFxyXG5cdFx0IWNhY2hlZFByZWZzLnZhbHVlIHx8XHJcblx0XHQhY2FjaGVkUHJlZnMuc3RhbGVEYXRlIHx8XHJcblx0XHRpc0FmdGVyRGF0ZShjYWNoZWRQcmVmcy5zdGFsZURhdGUpXHJcblx0KSB7XHJcblx0XHQvLyBObyBjYWNoZWQgdmFsdWUsIG9yIGlzIHRvbyBvbGRcclxuXHRcdHJldHVybiAkLkRlZmVycmVkKCkucmVqZWN0KCk7XHJcblx0fVxyXG5cdHJldHVybiAkLkRlZmVycmVkKCkucmVzb2x2ZShjYWNoZWRQcmVmcy52YWx1ZSk7XHJcbn07XHJcblxyXG5jb25zdCBnZXRQcmVmcyA9ICgpID0+IGdldFByZWZzRnJvbUNhY2hlKCkudGhlbihcclxuXHQvLyBTdWNjZXNzOiBwYXNzIHRocm91Z2ggKGZpcnN0IHBhcmFtIG9ubHkpXHJcblx0cHJlZnMgPT4gJC5EZWZlcnJlZCgpLnJlc29sdmUocHJlZnMpLFxyXG5cdC8vIEZhaWx1cmU6IGdldCBmcm9tIEFwaVxyXG5cdCgpID0+IGdldFByZWZzRnJvbUFwaSgpXHJcbik7XHJcblxyXG4vKipcclxuICogXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSB1cGRhdGVkUHJlZnMgb2JqZWN0IHdpdGgga2V5OnZhbHVlIHBhaXJzIGZvciBwcmVmZXJlbmNlcyBqc29uLlxyXG4gKi9cclxuY29uc3Qgc2V0UHJlZnMgPSBmdW5jdGlvbih1cGRhdGVkUHJlZnMpIHtcclxuXHRyZXR1cm4gQVBJLmVkaXRXaXRoUmV0cnkocHJlZnNQYWdlLFx0bnVsbCxcclxuXHRcdCgpID0+ICh7XHJcblx0XHRcdFwidGV4dFwiOiBKU09OLnN0cmluZ2lmeSh1cGRhdGVkUHJlZnMpLFxyXG5cdFx0XHRcInN1bW1hcnlcIjogXCJTYXZpbmcgUmF0ZXIgcHJlZmVyZW5jZXMgXCIgKyBjb25maWcuc2NyaXB0LmFkdmVydFxyXG5cdFx0fSlcclxuXHQpXHJcblx0XHQudGhlbiggKCkgPT4gd3JpdGVQcmVmc1RvQ2FjaGUodXBkYXRlZFByZWZzKSApO1xyXG59O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgKHtnZXQ6IGdldFByZWZzLCBzZXQ6IHNldFByZWZzfSk7XHJcbmV4cG9ydCB7IGdldFByZWZzLCBzZXRQcmVmcyB9O1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgY29uZmlnIGZyb20gXCIuL2NvbmZpZ1wiO1xyXG5pbXBvcnQgQVBJIGZyb20gXCIuL2FwaVwiO1xyXG5pbXBvcnQgeyBwYXJzZVRlbXBsYXRlcywgZ2V0V2l0aFJlZGlyZWN0VG8gfSBmcm9tIFwiLi9UZW1wbGF0ZVwiO1xyXG5pbXBvcnQge2dldEJhbm5lck5hbWVzfSBmcm9tIFwiLi9nZXRCYW5uZXJzXCI7XHJcbmltcG9ydCAqIGFzIGNhY2hlIGZyb20gXCIuL2NhY2hlXCI7XHJcbmltcG9ydCB3aW5kb3dNYW5hZ2VyIGZyb20gXCIuL3dpbmRvd01hbmFnZXJcIjtcclxuaW1wb3J0IHsgZ2V0UHJlZnMgfSBmcm9tIFwiLi9wcmVmc1wiO1xyXG5pbXBvcnQgeyBmaWx0ZXJBbmRNYXAgfSBmcm9tIFwiLi91dGlsXCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG52YXIgc2V0dXBSYXRlciA9IGZ1bmN0aW9uKGNsaWNrRXZlbnQpIHtcclxuXHRpZiAoIGNsaWNrRXZlbnQgKSB7XHJcblx0XHRjbGlja0V2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0fVxyXG5cclxuXHR2YXIgc2V0dXBDb21wbGV0ZWRQcm9taXNlID0gJC5EZWZlcnJlZCgpO1xyXG4gICAgXHJcblx0dmFyIGN1cnJlbnRQYWdlID0gbXcuVGl0bGUubmV3RnJvbVRleHQoY29uZmlnLm13LndnUGFnZU5hbWUpO1xyXG5cdHZhciB0YWxrUGFnZSA9IGN1cnJlbnRQYWdlICYmIGN1cnJlbnRQYWdlLmdldFRhbGtQYWdlKCk7XHJcblx0dmFyIHN1YmplY3RQYWdlID0gY3VycmVudFBhZ2UgJiYgY3VycmVudFBhZ2UuZ2V0U3ViamVjdFBhZ2UoKTtcclxuXHR2YXIgc3ViamVjdElzQXJ0aWNsZSA9IGNvbmZpZy5tdy53Z05hbWVzcGFjZU51bWJlciA8PSAxO1xyXG4gXHJcblx0Ly8gR2V0IHByZWZlcmVuY2VzICh0YXNrIDApXHJcblx0dmFyIHByZWZzUHJvbWlzZSA9IGdldFByZWZzKCk7XHJcblxyXG5cdC8vIEdldCBsaXN0cyBvZiBhbGwgYmFubmVycyAodGFzayAxKVxyXG5cdHZhciBiYW5uZXJzUHJvbWlzZSA9IGdldEJhbm5lck5hbWVzKCk7XHJcblxyXG5cdC8vIExvYWQgdGFsayBwYWdlICh0YXNrIDIpXHJcblx0dmFyIGxvYWRUYWxrUHJvbWlzZSA9IEFQSS5nZXQoIHtcclxuXHRcdGFjdGlvbjogXCJxdWVyeVwiLFxyXG5cdFx0cHJvcDogXCJyZXZpc2lvbnNcIixcclxuXHRcdHJ2cHJvcDogXCJjb250ZW50XCIsXHJcblx0XHRydnNlY3Rpb246IFwiMFwiLFxyXG5cdFx0dGl0bGVzOiB0YWxrUGFnZS5nZXRQcmVmaXhlZFRleHQoKSxcclxuXHRcdGluZGV4cGFnZWlkczogMVxyXG5cdH0gKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcclxuXHRcdHZhciBpZCA9IHJlc3VsdC5xdWVyeS5wYWdlaWRzO1x0XHRcclxuXHRcdHZhciB3aWtpdGV4dCA9ICggaWQgPCAwICkgPyBcIlwiIDogcmVzdWx0LnF1ZXJ5LnBhZ2VzW2lkXS5yZXZpc2lvbnNbMF1bXCIqXCJdO1xyXG5cdFx0cmV0dXJuIHdpa2l0ZXh0O1xyXG5cdH0pO1xyXG5cclxuXHQvLyBQYXJzZSB0YWxrIHBhZ2UgZm9yIGJhbm5lcnMgKHRhc2sgMylcclxuXHR2YXIgcGFyc2VUYWxrUHJvbWlzZSA9IGxvYWRUYWxrUHJvbWlzZS50aGVuKHdpa2l0ZXh0ID0+IHBhcnNlVGVtcGxhdGVzKHdpa2l0ZXh0LCB0cnVlKSkgLy8gR2V0IGFsbCB0ZW1wbGF0ZXNcclxuXHRcdC50aGVuKHRlbXBsYXRlcyA9PiB0ZW1wbGF0ZXMuZmlsdGVyKHRlbXBsYXRlID0+IHRlbXBsYXRlLmdldFRpdGxlKCkgIT09IG51bGwpKSAvLyBGaWx0ZXIgb3V0IGludmFsaWQgdGVtcGxhdGVzIChlLmcuIHBhcnNlciBmdW5jdGlvbnMpXHJcblx0XHQudGhlbih0ZW1wbGF0ZXMgPT4gZ2V0V2l0aFJlZGlyZWN0VG8odGVtcGxhdGVzKSkgLy8gQ2hlY2sgZm9yIHJlZGlyZWN0c1xyXG5cdFx0LnRoZW4odGVtcGxhdGVzID0+IHtcclxuXHRcdFx0cmV0dXJuIGJhbm5lcnNQcm9taXNlLnRoZW4oKGFsbEJhbm5lcnMpID0+IHsgLy8gR2V0IGxpc3Qgb2YgYWxsIGJhbm5lciB0ZW1wbGF0ZXNcclxuXHRcdFx0XHRyZXR1cm4gZmlsdGVyQW5kTWFwKFxyXG5cdFx0XHRcdFx0dGVtcGxhdGVzLCBcdFx0XHRcclxuXHRcdFx0XHRcdC8vIEZpbHRlciBvdXQgbm9uLWJhbm5lcnNcclxuXHRcdFx0XHRcdHRlbXBsYXRlID0+IHsgXHJcblx0XHRcdFx0XHRcdGlmICh0ZW1wbGF0ZS5pc1NoZWxsVGVtcGxhdGUoKSkgeyByZXR1cm4gdHJ1ZTsgfVxyXG5cdFx0XHRcdFx0XHR2YXIgbWFpblRleHQgPSB0ZW1wbGF0ZS5yZWRpcmVjdFRhcmdldFxyXG5cdFx0XHRcdFx0XHRcdD8gdGVtcGxhdGUucmVkaXJlY3RUYXJnZXQuZ2V0TWFpblRleHQoKVxyXG5cdFx0XHRcdFx0XHRcdDogdGVtcGxhdGUuZ2V0VGl0bGUoKS5nZXRNYWluVGV4dCgpO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gYWxsQmFubmVycy53aXRoUmF0aW5ncy5pbmNsdWRlcyhtYWluVGV4dCkgfHwgXHJcblx0XHRcdFx0XHRcdGFsbEJhbm5lcnMud2l0aG91dFJhdGluZ3MuaW5jbHVkZXMobWFpblRleHQpIHx8XHJcblx0XHRcdFx0XHRcdGFsbEJhbm5lcnMud3JhcHBlcnMuaW5jbHVkZXMobWFpblRleHQpIHx8XHJcblx0XHRcdFx0XHRcdGFsbEJhbm5lcnMubm90V1BCTS5pbmNsdWRlcyhtYWluVGV4dCkgfHxcclxuXHRcdFx0XHRcdFx0YWxsQmFubmVycy5pbmFjdGl2ZS5pbmNsdWRlcyhtYWluVGV4dCkgfHxcclxuXHRcdFx0XHRcdFx0YWxsQmFubmVycy53aXIuaW5jbHVkZXMobWFpblRleHQpO1xyXG5cdFx0XHRcdFx0fSxcclxuXHRcdFx0XHRcdC8vIFNldCBhZGRpdGlvbmFsIHByb3BlcnRpZXMgaWYgbmVlZGVkXHJcblx0XHRcdFx0XHR0ZW1wbGF0ZSA9PiB7XHJcblx0XHRcdFx0XHRcdHZhciBtYWluVGV4dCA9IHRlbXBsYXRlLnJlZGlyZWN0VGFyZ2V0XHJcblx0XHRcdFx0XHRcdFx0PyB0ZW1wbGF0ZS5yZWRpcmVjdFRhcmdldC5nZXRNYWluVGV4dCgpXHJcblx0XHRcdFx0XHRcdFx0OiB0ZW1wbGF0ZS5nZXRUaXRsZSgpLmdldE1haW5UZXh0KCk7XHJcblx0XHRcdFx0XHRcdGlmIChhbGxCYW5uZXJzLndyYXBwZXJzLmluY2x1ZGVzKG1haW5UZXh0KSkge1xyXG5cdFx0XHRcdFx0XHRcdHRlbXBsYXRlLnJlZGlyZWN0VGFyZ2V0ID0gbXcuVGl0bGUubmV3RnJvbVRleHQoXCJUZW1wbGF0ZTpTdWJzdDpcIiArIG1haW5UZXh0KTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRpZiAoXHJcblx0XHRcdFx0XHRcdFx0YWxsQmFubmVycy53aXRob3V0UmF0aW5ncy5pbmNsdWRlcyhtYWluVGV4dCkgfHxcclxuXHRcdFx0XHRcdFx0XHRhbGxCYW5uZXJzLndpci5pbmNsdWRlcyhtYWluVGV4dClcclxuXHRcdFx0XHRcdFx0KSB7XHJcblx0XHRcdFx0XHRcdFx0dGVtcGxhdGUud2l0aG91dFJhdGluZ3MgPSB0cnVlO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGlmICggYWxsQmFubmVycy5pbmFjdGl2ZS5pbmNsdWRlcyhtYWluVGV4dCkgKSB7XHJcblx0XHRcdFx0XHRcdFx0dGVtcGxhdGUuaW5hY3RpdmVQcm9qZWN0ID0gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRyZXR1cm4gdGVtcGxhdGU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHRcclxuXHQvLyBSZXRyaWV2ZSBhbmQgc3RvcmUgY2xhc3NlcywgaW1wb3J0YW5jZXMsIGFuZCBUZW1wbGF0ZURhdGEgKHRhc2sgNClcclxuXHR2YXIgdGVtcGxhdGVEZXRhaWxzUHJvbWlzZSA9IHBhcnNlVGFsa1Byb21pc2UudGhlbihmdW5jdGlvbih0ZW1wbGF0ZXMpIHtcclxuXHRcdC8vIFdhaXQgZm9yIGFsbCBwcm9taXNlcyB0byByZXNvbHZlXHJcblx0XHRyZXR1cm4gJC53aGVuLmFwcGx5KG51bGwsIFtcclxuXHRcdFx0Li4udGVtcGxhdGVzLm1hcCh0ZW1wbGF0ZSA9PiB0ZW1wbGF0ZS5pc1NoZWxsVGVtcGxhdGUoKSA/IG51bGwgOiB0ZW1wbGF0ZS5zZXRDbGFzc2VzQW5kSW1wb3J0YW5jZXMoKSksXHJcblx0XHRcdC4uLnRlbXBsYXRlcy5tYXAodGVtcGxhdGUgPT4gdGVtcGxhdGUuc2V0UGFyYW1EYXRhQW5kU3VnZ2VzdGlvbnMoKSlcclxuXHRcdF0pLnRoZW4oKCkgPT4ge1xyXG5cdFx0XHQvLyBBZGQgbWlzc2luZyByZXF1aXJlZC9zdWdnZXN0ZWQgdmFsdWVzXHJcblx0XHRcdHRlbXBsYXRlcy5mb3JFYWNoKHRlbXBsYXRlID0+IHRlbXBsYXRlLmFkZE1pc3NpbmdQYXJhbXMoKSk7XHJcblx0XHRcdC8vIFJldHVybiB0aGUgbm93LW1vZGlmaWVkIHRlbXBsYXRlc1xyXG5cdFx0XHRyZXR1cm4gdGVtcGxhdGVzO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblxyXG5cdC8vIENoZWNrIHN1YmplY3QgcGFnZSBmZWF0dXJlcyAodGFzayA1KSAtIGJ1dCBkb24ndCBlcnJvciBvdXQgaWYgcmVxdWVzdCBmYWlsc1xyXG5cdHZhciBzdWJqZWN0UGFnZUNoZWNrUHJvbWlzZSA9IEFQSS5nZXQoe1xyXG5cdFx0YWN0aW9uOiBcInF1ZXJ5XCIsXHJcblx0XHRmb3JtYXQ6IFwianNvblwiLFxyXG5cdFx0Zm9ybWF0dmVyc2lvbjogXCIyXCIsXHJcblx0XHRwcm9wOiBcImNhdGVnb3JpZXNcIixcclxuXHRcdHRpdGxlczogc3ViamVjdFBhZ2UuZ2V0UHJlZml4ZWRUZXh0KCksXHJcblx0XHRyZWRpcmVjdHM6IDEsXHJcblx0XHRjbGNhdGVnb3JpZXM6IFtcclxuXHRcdFx0XCJDYXRlZ29yeTpBbGwgZGlzYW1iaWd1YXRpb24gcGFnZXNcIixcclxuXHRcdFx0XCJDYXRlZ29yeTpBbGwgc3R1YiBhcnRpY2xlc1wiLFxyXG5cdFx0XHRcIkNhdGVnb3J5Okdvb2QgYXJ0aWNsZXNcIixcclxuXHRcdFx0XCJDYXRlZ29yeTpGZWF0dXJlZCBhcnRpY2xlc1wiLFxyXG5cdFx0XHRcIkNhdGVnb3J5OkZlYXR1cmVkIGxpc3RzXCJcclxuXHRcdF1cclxuXHR9KS50aGVuKHJlc3BvbnNlID0+IHtcclxuXHRcdGlmICggIXJlc3BvbnNlIHx8ICFyZXNwb25zZS5xdWVyeSB8fCAhcmVzcG9uc2UucXVlcnkucGFnZXMgKSB7XHJcblx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgcmVkaXJlY3RUYXJnZXQgPSByZXNwb25zZS5xdWVyeS5yZWRpcmVjdHMgJiYgcmVzcG9uc2UucXVlcnkucmVkaXJlY3RzWzBdLnRvIHx8IGZhbHNlO1xyXG5cdFx0aWYgKCByZWRpcmVjdFRhcmdldCB8fCAhc3ViamVjdElzQXJ0aWNsZSApIHtcclxuXHRcdFx0cmV0dXJuIHsgcmVkaXJlY3RUYXJnZXQgfTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IHBhZ2UgPSByZXNwb25zZS5xdWVyeS5wYWdlc1swXTtcclxuXHRcdGNvbnN0IGhhc0NhdGVnb3J5ID0gY2F0ZWdvcnkgPT4gcGFnZS5jYXRlZ29yaWVzICYmIHBhZ2UuY2F0ZWdvcmllcy5maW5kKGNhdCA9PiBjYXQudGl0bGUgPT09IFwiQ2F0ZWdvcnk6XCIrY2F0ZWdvcnkpO1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0cmVkaXJlY3RUYXJnZXQsXHJcblx0XHRcdGRpc2FtYmlnOiBoYXNDYXRlZ29yeShcIkFsbCBkaXNhbWJpZ3VhdGlvbiBwYWdlc1wiKSxcclxuXHRcdFx0c3R1YnRhZzogaGFzQ2F0ZWdvcnkoXCJBbGwgc3R1YiBhcnRpY2xlc1wiKSxcclxuXHRcdFx0aXNHQTogaGFzQ2F0ZWdvcnkoXCJHb29kIGFydGljbGVzXCIpLFxyXG5cdFx0XHRpc0ZBOiBoYXNDYXRlZ29yeShcIkZlYXR1cmVkIGFydGljbGVzXCIpLFxyXG5cdFx0XHRpc0ZMOiBoYXNDYXRlZ29yeShcIkZlYXR1cmVkIGxpc3RzXCIpLFxyXG5cdFx0XHRpc0xpc3Q6ICFoYXNDYXRlZ29yeShcIkZlYXR1cmVkIGxpc3RzXCIpICYmIC9eTGlzdHM/IG9mLy50ZXN0KHN1YmplY3RQYWdlLmdldFByZWZpeGVkVGV4dCgpKVxyXG5cdFx0fTtcclxuXHR9KS5jYXRjaCgoKSA9PiBudWxsKTsgLy8gRmFpbHVyZSBpZ25vcmVkXHJcblxyXG5cdC8vIFJldHJpZXZlIHJhdGluZyBmcm9tIE9SRVMgKHRhc2sgNiwgb25seSBuZWVkZWQgZm9yIGFydGljbGVzKSAtIGJ1dCBkb24ndCBlcnJvciBvdXQgaWYgcmVxdWVzdCBmYWlsc1xyXG5cdHZhciBzaG91bGRHZXRPcmVzID0gKCBzdWJqZWN0SXNBcnRpY2xlICk7IC8vIFRPRE86IERvbid0IG5lZWQgdG8gZ2V0IE9SRVMgZm9yIHJlZGlyZWN0cyBvciBkaXNhbWJpZ3NcclxuXHRpZiAoIHNob3VsZEdldE9yZXMgKSB7XHJcblx0XHR2YXIgbGF0ZXN0UmV2SWRQcm9taXNlID0gIWN1cnJlbnRQYWdlLmlzVGFsa1BhZ2UoKVxyXG5cdFx0XHQ/ICQuRGVmZXJyZWQoKS5yZXNvbHZlKGNvbmZpZy5tdy53Z1JldmlzaW9uSWQpXHJcblx0XHRcdDogQVBJLmdldCgge1xyXG5cdFx0XHRcdGFjdGlvbjogXCJxdWVyeVwiLFxyXG5cdFx0XHRcdGZvcm1hdDogXCJqc29uXCIsXHJcblx0XHRcdFx0cHJvcDogXCJyZXZpc2lvbnNcIixcclxuXHRcdFx0XHR0aXRsZXM6IHN1YmplY3RQYWdlLmdldFByZWZpeGVkVGV4dCgpLFxyXG5cdFx0XHRcdHJ2cHJvcDogXCJpZHNcIixcclxuXHRcdFx0XHRpbmRleHBhZ2VpZHM6IDFcclxuXHRcdFx0fSApLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XHJcblx0XHRcdFx0aWYgKHJlc3VsdC5xdWVyeS5yZWRpcmVjdHMpIHtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dmFyIGlkID0gcmVzdWx0LnF1ZXJ5LnBhZ2VpZHM7XHJcblx0XHRcdFx0dmFyIHBhZ2UgPSByZXN1bHQucXVlcnkucGFnZXNbaWRdO1xyXG5cdFx0XHRcdGlmIChwYWdlLm1pc3NpbmcgPT09IFwiXCIpIHtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCBpZCA8IDAgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlamVjdCgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gcGFnZS5yZXZpc2lvbnNbMF0ucmV2aWQ7XHJcblx0XHRcdH0pO1xyXG5cdFx0dmFyIG9yZXNQcm9taXNlID0gbGF0ZXN0UmV2SWRQcm9taXNlLnRoZW4oZnVuY3Rpb24obGF0ZXN0UmV2SWQpIHtcclxuXHRcdFx0aWYgKCFsYXRlc3RSZXZJZCkge1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gQVBJLmdldE9SRVMobGF0ZXN0UmV2SWQpXHJcblx0XHRcdFx0LnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XHJcblx0XHRcdFx0XHR2YXIgZGF0YSA9IHJlc3VsdC5lbndpa2kuc2NvcmVzW2xhdGVzdFJldklkXS5hcnRpY2xlcXVhbGl0eTtcclxuXHRcdFx0XHRcdGlmICggZGF0YS5lcnJvciApIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuICQuRGVmZXJyZWQoKS5yZWplY3QoZGF0YS5lcnJvci50eXBlLCBkYXRhLmVycm9yLm1lc3NhZ2UpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0Y29uc3QgcHJlZGljdGlvbiA9IGRhdGEuc2NvcmUucHJlZGljdGlvbjtcclxuXHRcdFx0XHRcdGNvbnN0IHByb2JhYmlsaXRpZXMgPSBkYXRhLnNjb3JlLnByb2JhYmlsaXR5O1xyXG5cdFx0XHRcdFx0aWYgKHByZWRpY3Rpb24gPT09IFwiRkFcIiB8fCBwcmVkaWN0aW9uID09PSBcIkdBXCIpIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdFx0XHRwcmVkaWN0aW9uOiBcIkIgb3IgaGlnaGVyXCIsXHJcblx0XHRcdFx0XHRcdFx0cHJvYmFiaWxpdHk6ICgocHJvYmFiaWxpdGllcy5GQSArIHByb2JhYmlsaXRpZXMuR0EgKyBwcm9iYWJpbGl0aWVzLkIpKjEwMCkudG9GaXhlZCgxKStcIiVcIlxyXG5cdFx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdFx0cHJlZGljdGlvbixcclxuXHRcdFx0XHRcdFx0cHJvYmFiaWxpdHk6IChwcm9iYWJpbGl0aWVzWyBwcmVkaWN0aW9uIF0qMTAwKS50b0ZpeGVkKDEpK1wiJVwiXHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH0pLmNhdGNoKCgpID0+IG51bGwpOyAvLyBGYWlsdXJlIGlnbm9yZWQ7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdC8vIE9wZW4gdGhlIGxvYWQgZGlhbG9nXHJcblx0dmFyIGlzT3BlbmVkUHJvbWlzZSA9ICQuRGVmZXJyZWQoKTtcclxuXHR2YXIgbG9hZERpYWxvZ1dpbiA9IHdpbmRvd01hbmFnZXIub3BlbldpbmRvdyhcImxvYWREaWFsb2dcIiwge1xyXG5cdFx0cHJvbWlzZXM6IFtcclxuXHRcdFx0YmFubmVyc1Byb21pc2UsXHJcblx0XHRcdGxvYWRUYWxrUHJvbWlzZSxcclxuXHRcdFx0cGFyc2VUYWxrUHJvbWlzZSxcclxuXHRcdFx0dGVtcGxhdGVEZXRhaWxzUHJvbWlzZSxcclxuXHRcdFx0c3ViamVjdFBhZ2VDaGVja1Byb21pc2UsXHJcblx0XHRcdHNob3VsZEdldE9yZXMgJiYgb3Jlc1Byb21pc2VcclxuXHRcdF0sXHJcblx0XHRvcmVzOiBzaG91bGRHZXRPcmVzLFxyXG5cdFx0aXNPcGVuZWQ6IGlzT3BlbmVkUHJvbWlzZVxyXG5cdH0pO1xyXG5cclxuXHRsb2FkRGlhbG9nV2luLm9wZW5lZC50aGVuKGlzT3BlbmVkUHJvbWlzZS5yZXNvbHZlKTtcclxuXHJcblxyXG5cdCQud2hlbihcclxuXHRcdHByZWZzUHJvbWlzZSxcclxuXHRcdGxvYWRUYWxrUHJvbWlzZSxcclxuXHRcdHRlbXBsYXRlRGV0YWlsc1Byb21pc2UsXHJcblx0XHRzdWJqZWN0UGFnZUNoZWNrUHJvbWlzZSxcclxuXHRcdHNob3VsZEdldE9yZXMgJiYgb3Jlc1Byb21pc2VcclxuXHQpLnRoZW4oXHJcblx0XHQvLyBBbGwgc3VjY2VkZWRcclxuXHRcdGZ1bmN0aW9uKHByZWZlcmVuY2VzLCB0YWxrV2lraXRleHQsIGJhbm5lcnMsIHN1YmplY3RQYWdlQ2hlY2ssIG9yZXNQcmVkaWNpdGlvbiApIHtcclxuXHRcdFx0dmFyIHJlc3VsdCA9IHtcclxuXHRcdFx0XHRzdWNjZXNzOiB0cnVlLFxyXG5cdFx0XHRcdHRhbGtwYWdlOiB0YWxrUGFnZSxcclxuXHRcdFx0XHRzdWJqZWN0UGFnZTogc3ViamVjdFBhZ2UsXHJcblx0XHRcdFx0dGFsa1dpa2l0ZXh0OiB0YWxrV2lraXRleHQsXHJcblx0XHRcdFx0YmFubmVyczogYmFubmVycyxcclxuXHRcdFx0XHRwcmVmZXJlbmNlczogcHJlZmVyZW5jZXMsXHJcblx0XHRcdFx0aXNBcnRpY2xlOiBzdWJqZWN0SXNBcnRpY2xlXHJcblx0XHRcdH07XHJcblx0XHRcdGlmIChzdWJqZWN0UGFnZUNoZWNrKSB7XHJcblx0XHRcdFx0cmVzdWx0ID0geyAuLi5yZXN1bHQsIC4uLnN1YmplY3RQYWdlQ2hlY2sgfTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAob3Jlc1ByZWRpY2l0aW9uICYmIHN1YmplY3RQYWdlQ2hlY2sgJiYgIXN1YmplY3RQYWdlQ2hlY2suaXNHQSAmJiAhc3ViamVjdFBhZ2VDaGVjay5pc0ZBICYmICFzdWJqZWN0UGFnZUNoZWNrLmlzRkwpIHtcclxuXHRcdFx0XHRyZXN1bHQub3JlcyA9IG9yZXNQcmVkaWNpdGlvbjtcclxuXHRcdFx0fVxyXG5cdFx0XHR3aW5kb3dNYW5hZ2VyLmNsb3NlV2luZG93KFwibG9hZERpYWxvZ1wiLCByZXN1bHQpO1xyXG5cdFx0XHRcclxuXHRcdH1cclxuXHQpOyAvLyBBbnkgZmFpbHVyZXMgYXJlIGhhbmRsZWQgYnkgdGhlIGxvYWREaWFsb2cgd2luZG93IGl0c2VsZlxyXG5cclxuXHQvLyBPbiB3aW5kb3cgY2xvc2VkLCBjaGVjayBkYXRhLCBhbmQgcmVzb2x2ZS9yZWplY3Qgc2V0dXBDb21wbGV0ZWRQcm9taXNlXHJcblx0bG9hZERpYWxvZ1dpbi5jbG9zZWQudGhlbihmdW5jdGlvbihkYXRhKSB7XHJcblx0XHRpZiAoZGF0YSAmJiBkYXRhLnN1Y2Nlc3MpIHtcclxuXHRcdFx0Ly8gR290IGV2ZXJ5dGhpbmcgbmVlZGVkOiBSZXNvbHZlIHByb21pc2Ugd2l0aCB0aGlzIGRhdGFcclxuXHRcdFx0c2V0dXBDb21wbGV0ZWRQcm9taXNlLnJlc29sdmUoZGF0YSk7XHJcblx0XHR9IGVsc2UgaWYgKGRhdGEgJiYgZGF0YS5lcnJvcikge1xyXG5cdFx0XHQvLyBUaGVyZSB3YXMgYW4gZXJyb3I6IFJlamVjdCBwcm9taXNlIHdpdGggZXJyb3IgY29kZS9pbmZvXHJcblx0XHRcdHNldHVwQ29tcGxldGVkUHJvbWlzZS5yZWplY3QoZGF0YS5lcnJvci5jb2RlLCBkYXRhLmVycm9yLmluZm8pO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Ly8gV2luZG93IGNsb3NlZCBiZWZvcmUgY29tcGxldGlvbjogcmVzb2x2ZSBwcm9taXNlIHdpdGhvdXQgYW55IGRhdGFcclxuXHRcdFx0c2V0dXBDb21wbGV0ZWRQcm9taXNlLnJlc29sdmUobnVsbCk7XHJcblx0XHR9XHJcblx0XHRjYWNoZS5jbGVhckludmFsaWRJdGVtcygpO1xyXG5cdH0pO1xyXG5cdHJldHVybiBzZXR1cENvbXBsZXRlZFByb21pc2U7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBzZXR1cFJhdGVyO1xyXG4vLyA8L25vd2lraT4iLCIvLyA8bm93aWtpPlxyXG5cclxuLy8gVmFyaW91cyB1dGlsaXR5IGZ1bmN0aW9ucyBhbmQgb2JqZWN0cyB0aGF0IG1pZ2h0IGJlIHVzZWQgaW4gbXVsdGlwbGUgcGxhY2VzXHJcblxyXG52YXIgaXNBZnRlckRhdGUgPSBmdW5jdGlvbihkYXRlU3RyaW5nKSB7XHJcblx0cmV0dXJuIG5ldyBEYXRlKGRhdGVTdHJpbmcpIDwgbmV3IERhdGUoKTtcclxufTtcclxuXHJcbnZhciB5ZXNXb3JkcyA9IFtcclxuXHRcImFkZFwiLFxyXG5cdFwiYWRkZWRcIixcclxuXHRcImFmZmlybVwiLFxyXG5cdFwiYWZmaXJtZWRcIixcclxuXHRcImluY2x1ZGVcIixcclxuXHRcImluY2x1ZGVkXCIsXHJcblx0XCJvblwiLFxyXG5cdFwidHJ1ZVwiLFxyXG5cdFwieWVzXCIsXHJcblx0XCJ5XCIsXHJcblx0XCIxXCJcclxuXTtcclxudmFyIG5vV29yZHMgPSBbXHJcblx0XCJkZWNsaW5lXCIsXHJcblx0XCJkZWNsaW5lZFwiLFxyXG5cdFwiZXhjbHVkZVwiLFxyXG5cdFwiZXhjbHVkZWRcIixcclxuXHRcImZhbHNlXCIsXHJcblx0XCJub25lXCIsXHJcblx0XCJub3RcIixcclxuXHRcIm5vXCIsXHJcblx0XCJuXCIsXHJcblx0XCJvZmZcIixcclxuXHRcIm9taXRcIixcclxuXHRcIm9taXR0ZWRcIixcclxuXHRcInJlbW92ZVwiLFxyXG5cdFwicmVtb3ZlZFwiLFxyXG5cdFwiMFwiXHJcbl07XHJcbnZhciBub3JtYWxpc2VZZXNObyA9IGZ1bmN0aW9uKHZhbCkge1xyXG5cdGlmICh2YWwgPT0gbnVsbCkge1xyXG5cdFx0cmV0dXJuIHZhbDtcclxuXHR9XHJcblx0dmFyIHRyaW1tZWRMY1ZhbCA9IHZhbC50cmltKCkudG9Mb3dlckNhc2UoKTtcclxuXHRpZiAoeWVzV29yZHMuaW5jbHVkZXModHJpbW1lZExjVmFsKSkge1xyXG5cdFx0cmV0dXJuIFwieWVzXCI7XHJcblx0fSBlbHNlIGlmIChub1dvcmRzLmluY2x1ZGVzKHRyaW1tZWRMY1ZhbCkpIHtcclxuXHRcdHJldHVybiBcIm5vXCI7XHJcblx0fSBlbHNlIHtcclxuXHRcdHJldHVybiB0cmltbWVkTGNWYWw7XHJcblx0fVxyXG59O1xyXG5cclxuLyoqXHJcbiAqIFxyXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZmlsdGVyUHJlZGljYXRlIChjdXJyZW50VmFsLCBjdXJyZW50SW5kZXgsIGFycmF5KSA9PiB7Ym9vbGVhbn1cclxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWFwVHJhbnNmb3JtIChjdXJyZW50VmFsLCBjdXJyZW50SW5kZXgsIGFycmF5KSA9PiB7YW55fVxyXG4gKiBAcmV0dXJucyB7QXJyYXl9XHJcbiAqL1xyXG52YXIgZmlsdGVyQW5kTWFwID0gZnVuY3Rpb24oYXJyYXksIGZpbHRlclByZWRpY2F0ZSwgbWFwVHJhbnNmb3JtKSB7XHJcblx0cmV0dXJuIGFycmF5LnJlZHVjZShcclxuXHRcdChhY2N1bXVsYXRlZCwgY3VycmVudFZhbCwgY3VycmVudEluZGV4KSA9PiB7XHJcblx0XHRcdGlmIChmaWx0ZXJQcmVkaWNhdGUoY3VycmVudFZhbCwgY3VycmVudEluZGV4LCBhcnJheSkpIHtcclxuXHRcdFx0XHRyZXR1cm4gWy4uLmFjY3VtdWxhdGVkLCBtYXBUcmFuc2Zvcm0oY3VycmVudFZhbCwgY3VycmVudEluZGV4LCBhcnJheSldO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBhY2N1bXVsYXRlZDtcclxuXHRcdH0sXHJcblx0XHRbXVxyXG5cdCk7XHJcbn07XHJcblxyXG4vKipcclxuICogXHJcbiAqIEBwYXJhbSB7c3RyaW5nW118bnVtYmVyW119IGFycmF5IFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGl0ZW0gd2l0aCB0aGUgaGlnaGVzdCBmcmVxdWVuY3lcclxuICogZS5nLiBgbW9zdEZyZXF1ZW50KFtcImFwcGxlXCIsIFwiYXBwbGVcIiwgXCJvcmFuZ2VcIl0pYCByZXR1cm5zIGBcImFwcGxlXCJgXHJcbiAqL1xyXG5mdW5jdGlvbiBtb3N0RnJlcXVlbnQoYXJyYXkpIHtcclxuXHRpZiAoIWFycmF5IHx8ICFBcnJheS5pc0FycmF5KGFycmF5KSB8fCBhcnJheS5sZW5ndGggPT09IDApXHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR2YXIgbWFwID0ge307XHJcblx0dmFyIG1vc3RGcmVxID0gbnVsbDtcclxuXHRhcnJheS5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRtYXBbaXRlbV0gPSAobWFwW2l0ZW1dIHx8IDApICsgMTtcclxuXHRcdGlmIChtb3N0RnJlcSA9PT0gbnVsbCB8fCBtYXBbaXRlbV0gPiBtYXBbbW9zdEZyZXFdKSB7XHJcblx0XHRcdG1vc3RGcmVxID0gaXRlbTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHRyZXR1cm4gbW9zdEZyZXE7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBcclxuICogQHBhcmFtIHtzdHJpbmdbXXxudW1iZXJbXX0gYXJyYXkgXHJcbiAqIEByZXR1cm5zIHtzdHJpbmdbXXxudW1iZXJbXX0gYXJyYXkgd2l0aCBvbmx5IHVuaXF1ZSB2YWx1ZXNcclxuICogZS5nLiBgdW5pcXVlQXJyYXkoW1wiYXBwbGVcIiwgXCJhcHBsZVwiLCBcIm9yYW5nZVwiXSlgIHJldHVybnMgYFtcImFwcGxlXCIsIFwib3JhbmdlXCJdYFxyXG4gKi9cclxuZnVuY3Rpb24gdW5pcXVlQXJyYXkoYXJyYXkpIHtcclxuXHRpZiAoIWFycmF5IHx8ICFBcnJheS5pc0FycmF5KGFycmF5KSB8fCBhcnJheS5sZW5ndGggPT09IDApXHJcblx0XHRyZXR1cm4gW107XHJcblx0dmFyIHNlZW4gPSB7fTtcclxuXHR2YXIgdW5pcXVlID0gW107XHJcblx0YXJyYXkuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG5cdFx0aWYgKCFzZWVuW2l0ZW1dKSB7XHJcblx0XHRcdHVuaXF1ZS5wdXNoKGl0ZW0pO1xyXG5cdFx0XHRzZWVuW2l0ZW1dID0gdHJ1ZTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHRyZXR1cm4gdW5pcXVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjbGFzc01hc2soY2xhc3NWYWwpIHtcclxuXHRpZiAoIWNsYXNzVmFsKSB7XHJcblx0XHRyZXR1cm4gY2xhc3NWYWw7XHJcblx0fVxyXG5cdHN3aXRjaCAoY2xhc3NWYWwudG9Mb3dlckNhc2UoKSkge1xyXG5cdGNhc2UgXCJmYVwiOlxyXG5cdGNhc2UgXCJmbFwiOlxyXG5cdGNhc2UgXCJhXCI6XHJcblx0Y2FzZSBcImdhXCI6XHJcblx0Y2FzZSBcImJcIjpcclxuXHRjYXNlIFwiY1wiOlxyXG5cdGNhc2UgXCJuYVwiOlxyXG5cdGNhc2UgXCJmbVwiOlxyXG5cdGNhc2UgXCJhbFwiOlxyXG5cdGNhc2UgXCJibFwiOlxyXG5cdGNhc2UgXCJjbFwiOlxyXG5cdFx0cmV0dXJuIGNsYXNzVmFsLnRvVXBwZXJDYXNlKCk7XHJcblx0Y2FzZSBcInN0YXJ0XCI6XHJcblx0Y2FzZSBcInN0dWJcIjpcclxuXHRjYXNlIFwibGlzdFwiOlxyXG5cdGNhc2UgXCJwb3J0YWxcIjpcclxuXHRjYXNlIFwicHJvamVjdFwiOlxyXG5cdGNhc2UgXCJkcmFmdFwiOlxyXG5cdGNhc2UgXCJib29rXCI6XHJcblx0Y2FzZSBcImZ1dHVyZVwiOlxyXG5cdGNhc2UgXCJjdXJyZW50XCI6XHJcblx0Y2FzZSBcImNvbXBsZXRlXCI6XHJcblx0Y2FzZSBcInN1YnN0YW50aWFsXCI6XHJcblx0Y2FzZSBcImJhc2ljXCI6XHJcblx0Y2FzZSBcImluY29tcGxldGVcIjpcclxuXHRjYXNlIFwibWV0YVwiOlxyXG5cdFx0cmV0dXJuIGNsYXNzVmFsLnNsaWNlKDAsMSkudG9VcHBlckNhc2UoKSArIGNsYXNzVmFsLnNsaWNlKDEpLnRvTG93ZXJDYXNlKCk7XHJcblx0Y2FzZSBcImltYWdlXCI6XHJcblx0Y2FzZSBcImltZ1wiOlxyXG5cdGNhc2UgXCJmaWxlXCI6XHJcblx0XHRyZXR1cm4gXCJGaWxlXCI7XHJcblx0Y2FzZSBcImNhdGVnb3J5XCI6XHJcblx0Y2FzZSBcImNhdFwiOlxyXG5cdGNhc2UgXCJjYXRlZ1wiOlxyXG5cdFx0cmV0dXJuIFwiQ2F0ZWdvcnlcIjtcclxuXHRjYXNlIFwiZGlzYW1iaWd1YXRpb25cIjpcclxuXHRjYXNlIFwiZGlzYW1iaWdcIjpcclxuXHRjYXNlIFwiZGlzYW1iXCI6XHJcblx0Y2FzZSBcImRhYlwiOlxyXG5cdFx0cmV0dXJuIFwiRGlzYW1iaWdcIjtcclxuXHRjYXNlIFwicmVkaXJlY3RcIjpcclxuXHRjYXNlIFwicmVkaXJcIjpcclxuXHRjYXNlIFwicmVkXCI6XHJcblx0XHRyZXR1cm4gXCJSZWRpcmVjdFwiO1xyXG5cdGNhc2UgXCJ0ZW1wbGF0ZVwiOlxyXG5cdGNhc2UgXCJ0ZW1wXCI6XHJcblx0Y2FzZSBcInRwbFwiOlxyXG5cdFx0cmV0dXJuIFwiVGVtcGxhdGVcIjtcclxuXHRjYXNlIFwiYnBsdXNcIjpcclxuXHRjYXNlIFwiYitcIjpcclxuXHRcdHJldHVybiBcIkJwbHVzXCI7XHJcblx0Y2FzZSBcImZwb1wiOlxyXG5cdFx0cmV0dXJuIFwiRlBvXCI7XHJcblx0ZGVmYXVsdDpcclxuXHRcdHJldHVybiBjbGFzc1ZhbDtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGltcG9ydGFuY2VNYXNrKGltcG9ydGFuY2UpIHtcclxuXHRpZiAoIWltcG9ydGFuY2UpIHtcclxuXHRcdHJldHVybiBpbXBvcnRhbmNlO1xyXG5cdH1cclxuXHRpZiAoaW1wb3J0YW5jZS50b0xvd2VyQ2FzZSgpID09PSBcIm5hXCIpIHtcclxuXHRcdHJldHVybiBcIk5BXCI7XHJcblx0fVxyXG5cdHJldHVybiBpbXBvcnRhbmNlLnNsaWNlKDAsMSkudG9VcHBlckNhc2UoKSArIGltcG9ydGFuY2Uuc2xpY2UoMSkudG9Mb3dlckNhc2UoKTtcclxufVxyXG5cclxuZXhwb3J0IHtcclxuXHRpc0FmdGVyRGF0ZSxcclxuXHRmaWx0ZXJBbmRNYXAsXHJcblx0bm9ybWFsaXNlWWVzTm8sXHJcblx0bW9zdEZyZXF1ZW50LFxyXG5cdHVuaXF1ZUFycmF5LFxyXG5cdGNsYXNzTWFzayxcclxuXHRpbXBvcnRhbmNlTWFza1xyXG59O1xyXG4vLyA8L25vd2lraT4iLCJpbXBvcnQgTG9hZERpYWxvZyBmcm9tIFwiLi9XaW5kb3dzL0xvYWREaWFsb2dcIjtcclxuaW1wb3J0IE1haW5XaW5kb3cgZnJvbSBcIi4vV2luZG93cy9NYWluV2luZG93XCI7XHJcbi8vIDxub3dpa2k+XHJcblxyXG52YXIgZmFjdG9yeSA9IG5ldyBPTy5GYWN0b3J5KCk7XHJcblxyXG4vLyBSZWdpc3RlciB3aW5kb3cgY29uc3RydWN0b3JzIHdpdGggdGhlIGZhY3RvcnkuXHJcbmZhY3RvcnkucmVnaXN0ZXIoTG9hZERpYWxvZyk7XHJcbmZhY3RvcnkucmVnaXN0ZXIoTWFpbldpbmRvdyk7XHJcblxyXG52YXIgbWFuYWdlciA9IG5ldyBPTy51aS5XaW5kb3dNYW5hZ2VyKCB7XHJcblx0XCJmYWN0b3J5XCI6IGZhY3RvcnlcclxufSApO1xyXG4vLyBNYXJrZXIgY2xhc3MsIHNvIENTUyBydWxlcyBjYW4gdGFyZ2V0IFJhdGVyJ3Mgb3duIHdpbmRvd3Mgd2l0aG91dCBhZmZlY3RpbmdcclxuLy8gb3RoZXIgT09VSSBkaWFsb2dzIChlLmcuIE9PLnVpLmNvbmZpcm0sIHdoaWNoIHJlbmRlcnMgaW4gI213LXRlbGVwb3J0LXRhcmdldClcclxubWFuYWdlci4kZWxlbWVudC5hZGRDbGFzcyggXCJyYXRlci13aW5kb3dNYW5hZ2VyXCIgKTtcclxuJCggZG9jdW1lbnQuYm9keSApLmFwcGVuZCggbWFuYWdlci4kZWxlbWVudCApO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgbWFuYWdlcjtcclxuLy8gPC9ub3dpa2k+Il19
7my2pxbudb57swjb65hb26vbtj4xrok
Talk:Mainspace
1
174793
754652
754377
2026-08-02T10:03:31Z
Novem Linguae
49714
Assessment (Low): banner shell, +China ([[WP:RATER#2.7.2|Rater]])
754652
wikitext
text/x-wiki
{{Old AfD multi |date=14 May 2026 |result='''soft merge selectively''' |page=Mainspace (30th nomination)}}
{{WikiProject banner shell |class=Start |1=
{{WikiProject Africa |importance=Low}}
{{WikiProject Belgium |importance=Low}}
{{WikiProject China |importance=Low}}
}}
== Question ==
Hello? [[User:Novem Linguae|<span style="color:darkorange;">'''Novem Linguae'''</span>]] [[User talk:Novem Linguae|<span style="color:darkorange;">(Talk)</span>]] 11:22, 17 May 2026 (UTC)
a32alus5kao6l4zkpgig71j0ca8mx77
User talk:Enbi
3
175451
754569
754530
2026-08-01T20:00:39Z
Enbi
72574
Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:uw-vandalism1|uw-vandalism1]]}} (Fortress-Beta)
754569
wikitext
text/x-wiki
== July 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello. This is a message to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]], such as the edit(s) you made to [[:Hi]], did not appear to be constructive and have been [[Help:Reverting|reverted]]. Please take some time to familiarise yourself with our [[Wikipedia:Policies and guidelines|policies and guidelines]]. You can find information about these at our [[Help:Getting started|welcome page]] which also provides further information about [[Wikipedia:Contributing to Wikipedia|contributing constructively to this encyclopedia]]. If you only meant to make test edits, please use {{safesubst:If temporary account|the [[Wikipedia:Sandbox|sandbox]]|[[User:Enbi/sandbox|your sandbox]]}} for that. If you think I made a mistake, or if you have any questions, you may leave a message on [[User_talk:Enbi|my talk page]]. Thank you.<!-- Template:uw-disruptive1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 13:46, 31 July 2026 (UTC)
{{subst:uw-test2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 21:28, 31 July 2026 (UTC)
{{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:34, 31 July 2026 (UTC)
{{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:36, 31 July 2026 (UTC)
{{subst:uw-npov2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:37, 31 July 2026 (UTC)
<div style=clear: both></div>[[Image:Information.svg|25px|alt=|link=]] Please do not remove content or templates from pages on Wikipedia, as you did to [[:Test234]] with <span class="plainlinks">[{{{2}}} this edit]</span>, without giving a valid reason for the removal in the [[Help:Edit summary|edit summary]]. Your content removal does not appear constructive, and has been [[Help:Reverting|reverted]]. Please make use of the [[Wikipedia:Sandbox|sandbox]] if you'd like to experiment with test edits. Thank you. <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)<!-- Template:Huggle/warn-delete-2 --><!-- Template:uw-delete2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)
{{subst:uw-engvar|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)
{{subst:uw-error3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:58, 31 July 2026 (UTC)
{{subst:uw-test3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:59, 31 July 2026 (UTC)
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:00, 1 August 2026 (UTC)
k90vpdlrgdzw6pkx05e6sie4yx0mqc1
754573
754569
2026-08-01T20:02:54Z
Enbi
72574
Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:uw-vandalism2|uw-vandalism2]]}} (Fortress-Beta)
754573
wikitext
text/x-wiki
== July 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello. This is a message to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]], such as the edit(s) you made to [[:Hi]], did not appear to be constructive and have been [[Help:Reverting|reverted]]. Please take some time to familiarise yourself with our [[Wikipedia:Policies and guidelines|policies and guidelines]]. You can find information about these at our [[Help:Getting started|welcome page]] which also provides further information about [[Wikipedia:Contributing to Wikipedia|contributing constructively to this encyclopedia]]. If you only meant to make test edits, please use {{safesubst:If temporary account|the [[Wikipedia:Sandbox|sandbox]]|[[User:Enbi/sandbox|your sandbox]]}} for that. If you think I made a mistake, or if you have any questions, you may leave a message on [[User_talk:Enbi|my talk page]]. Thank you.<!-- Template:uw-disruptive1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 13:46, 31 July 2026 (UTC)
{{subst:uw-test2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 21:28, 31 July 2026 (UTC)
{{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:34, 31 July 2026 (UTC)
{{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:36, 31 July 2026 (UTC)
{{subst:uw-npov2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:37, 31 July 2026 (UTC)
<div style=clear: both></div>[[Image:Information.svg|25px|alt=|link=]] Please do not remove content or templates from pages on Wikipedia, as you did to [[:Test234]] with <span class="plainlinks">[{{{2}}} this edit]</span>, without giving a valid reason for the removal in the [[Help:Edit summary|edit summary]]. Your content removal does not appear constructive, and has been [[Help:Reverting|reverted]]. Please make use of the [[Wikipedia:Sandbox|sandbox]] if you'd like to experiment with test edits. Thank you. <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)<!-- Template:Huggle/warn-delete-2 --><!-- Template:uw-delete2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)
{{subst:uw-engvar|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)
{{subst:uw-error3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:58, 31 July 2026 (UTC)
{{subst:uw-test3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:59, 31 July 2026 (UTC)
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:00, 1 August 2026 (UTC)
[[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:02, 1 August 2026 (UTC)
8klgj4hkql3fui2h4zf5zl969b7n9bq
754576
754573
2026-08-01T20:04:56Z
Enbi
72574
Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:uw-vandalism3|uw-vandalism3]]}} (Fortress-Beta)
754576
wikitext
text/x-wiki
== July 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello. This is a message to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]], such as the edit(s) you made to [[:Hi]], did not appear to be constructive and have been [[Help:Reverting|reverted]]. Please take some time to familiarise yourself with our [[Wikipedia:Policies and guidelines|policies and guidelines]]. You can find information about these at our [[Help:Getting started|welcome page]] which also provides further information about [[Wikipedia:Contributing to Wikipedia|contributing constructively to this encyclopedia]]. If you only meant to make test edits, please use {{safesubst:If temporary account|the [[Wikipedia:Sandbox|sandbox]]|[[User:Enbi/sandbox|your sandbox]]}} for that. If you think I made a mistake, or if you have any questions, you may leave a message on [[User_talk:Enbi|my talk page]]. Thank you.<!-- Template:uw-disruptive1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 13:46, 31 July 2026 (UTC)
{{subst:uw-test2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 21:28, 31 July 2026 (UTC)
{{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:34, 31 July 2026 (UTC)
{{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:36, 31 July 2026 (UTC)
{{subst:uw-npov2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:37, 31 July 2026 (UTC)
<div style=clear: both></div>[[Image:Information.svg|25px|alt=|link=]] Please do not remove content or templates from pages on Wikipedia, as you did to [[:Test234]] with <span class="plainlinks">[{{{2}}} this edit]</span>, without giving a valid reason for the removal in the [[Help:Edit summary|edit summary]]. Your content removal does not appear constructive, and has been [[Help:Reverting|reverted]]. Please make use of the [[Wikipedia:Sandbox|sandbox]] if you'd like to experiment with test edits. Thank you. <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)<!-- Template:Huggle/warn-delete-2 --><!-- Template:uw-delete2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)
{{subst:uw-engvar|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)
{{subst:uw-error3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:58, 31 July 2026 (UTC)
{{subst:uw-test3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:59, 31 July 2026 (UTC)
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:00, 1 August 2026 (UTC)
[[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:02, 1 August 2026 (UTC)
[[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:04, 1 August 2026 (UTC)
jtf8lgbcikjkd6p0gcpjccgf1ikz45z
754579
754576
2026-08-01T20:06:33Z
Enbi
72574
Warning user: {{[[Template:uw-vandalism4|uw-vandalism4]]}} (test summary)
754579
wikitext
text/x-wiki
== July 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello. This is a message to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]], such as the edit(s) you made to [[:Hi]], did not appear to be constructive and have been [[Help:Reverting|reverted]]. Please take some time to familiarise yourself with our [[Wikipedia:Policies and guidelines|policies and guidelines]]. You can find information about these at our [[Help:Getting started|welcome page]] which also provides further information about [[Wikipedia:Contributing to Wikipedia|contributing constructively to this encyclopedia]]. If you only meant to make test edits, please use {{safesubst:If temporary account|the [[Wikipedia:Sandbox|sandbox]]|[[User:Enbi/sandbox|your sandbox]]}} for that. If you think I made a mistake, or if you have any questions, you may leave a message on [[User_talk:Enbi|my talk page]]. Thank you.<!-- Template:uw-disruptive1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 13:46, 31 July 2026 (UTC)
{{subst:uw-test2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 21:28, 31 July 2026 (UTC)
{{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:34, 31 July 2026 (UTC)
{{subst:uw-promo2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:36, 31 July 2026 (UTC)
{{subst:uw-npov2|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:37, 31 July 2026 (UTC)
<div style=clear: both></div>[[Image:Information.svg|25px|alt=|link=]] Please do not remove content or templates from pages on Wikipedia, as you did to [[:Test234]] with <span class="plainlinks">[{{{2}}} this edit]</span>, without giving a valid reason for the removal in the [[Help:Edit summary|edit summary]]. Your content removal does not appear constructive, and has been [[Help:Reverting|reverted]]. Please make use of the [[Wikipedia:Sandbox|sandbox]] if you'd like to experiment with test edits. Thank you. <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)<!-- Template:Huggle/warn-delete-2 --><!-- Template:uw-delete2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)
{{subst:uw-engvar|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:41, 31 July 2026 (UTC)
{{subst:uw-error3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:58, 31 July 2026 (UTC)
{{subst:uw-test3|Test234}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 22:59, 31 July 2026 (UTC)
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:00, 1 August 2026 (UTC)
[[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:02, 1 August 2026 (UTC)
[[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:04, 1 August 2026 (UTC)
[[File:Stop hand nuvola.svg|30px]] This is the '''last warning''' you will receive for your disruptive edits{{#if:Hi|, such as the one you made to [[:Hi]]}}. If you [[Wikipedia:Vandalism|vandalize]] Wikipedia again, you '''will''' be [[Wikipedia:Blocking policy|blocked]] from editing. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism4 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:06, 1 August 2026 (UTC)
0rjabl4mi9fdnr1d92zob0vsarj18qo
754583
754579
2026-08-01T20:08:40Z
Enbi
72574
Blanked the page
754583
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
754586
754583
2026-08-01T20:08:59Z
Enbi
72574
Test Summary
754586
wikitext
text/x-wiki
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:08, 1 August 2026 (UTC)
8zrsblfrerwje0iiexmuceo7vs0tyv5
754589
754586
2026-08-01T20:09:14Z
Enbi
72574
Test Summary
754589
wikitext
text/x-wiki
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:08, 1 August 2026 (UTC)
{{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:09, 1 August 2026 (UTC)
1rpc4oo7bfquuloxfkk7r8inddn0wrc
754596
754589
2026-08-01T20:14:08Z
Enbi
72574
Test Summary
754596
wikitext
text/x-wiki
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:08, 1 August 2026 (UTC)
{{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:09, 1 August 2026 (UTC)
[[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:14, 1 August 2026 (UTC)
d7durb1vnz5f6el9wxe6cmijut4vz56
754600
754596
2026-08-01T20:17:56Z
Enbi
72574
Warning [[Special:Contributions/uw-vandalism3|uw-vandalism3]]: {{[[Template:$2|$2]]}}
754600
wikitext
text/x-wiki
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:08, 1 August 2026 (UTC)
{{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:09, 1 August 2026 (UTC)
[[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:14, 1 August 2026 (UTC)
[[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:17, 1 August 2026 (UTC)
tn29kk5ehyolyurmyhhubava8pdm84f
754603
754600
2026-08-01T20:23:23Z
Enbi
72574
Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:uw-test4|uw-test4]]}}
754603
wikitext
text/x-wiki
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:08, 1 August 2026 (UTC)
{{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:09, 1 August 2026 (UTC)
[[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:14, 1 August 2026 (UTC)
[[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:17, 1 August 2026 (UTC)
{{subst:uw-test4|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:23, 1 August 2026 (UTC)
csxl84nrisxdmr4y9192xjmtl8n8l86
754606
754603
2026-08-01T20:23:51Z
Enbi
72574
Warning [[Special:Contributions/Enbi|Enbi]]: {{[[Template:engvar|engvar]]}}
754606
wikitext
text/x-wiki
== August 2026 ==
[[File:Information.svg|25px|alt=Information icon]] Hello, I'm [[User:Enbi|Enbi]]. I wanted to let you know that one or more of [[Special:Contributions/Enbi|your recent contributions]] to [[:Hi]] have been undone because they did not appear constructive. If you would like to experiment, please use the [[WP:sandbox|sandbox]]. If you have any questions, you can ask for assistance at the [[Wikipedia:Help desk|help desk]]. Thanks.<!-- Template:uw-vandalism1 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:08, 1 August 2026 (UTC)
{{subst:uw-test2|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:09, 1 August 2026 (UTC)
[[File:Information orange.svg|25px]] Please refrain from making unconstructive edits to Wikipedia{{#if:Hi|, as you did to [[:Hi]]}}. Your edits appear to constitute [[Wikipedia:Vandalism|vandalism]] and have been [[Help:Reverting|reverted]]. If you would like to experiment, please use the [[Wikipedia:Sandbox|sandbox]]. {{#if:|{{{2}}}|Thank you.}}<!-- Template:uw-vandalism2 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:14, 1 August 2026 (UTC)
[[File:Nuvola apps important.svg|25px]] Please stop your disruptive editing{{#if:Hi|, such as the edit you made to [[:Hi]]}}. If your [[Wikipedia:Vandalism|vandalism]] continues, you will be [[Wikipedia:Blocking policy|blocked]] from editing Wikipedia. {{#if:|{{{2}}}|}}<!-- Template:uw-vandalism3 --> <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:17, 1 August 2026 (UTC)
{{subst:uw-test4|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:23, 1 August 2026 (UTC)
{{subst:uw-engvar|Hi}} <b style="font-family:Trebuchet MS">[[User:enbi|<span style="color:#E28C00">enbi</span>]] [<span style="color:#9C59D1">they</span>/<span style="color:#FFC107">them</span>] • [[[User talk:enbi|talk]]]</b> 20:23, 1 August 2026 (UTC)
h9eizboa3e4joacab6vk1ua1bvva9my
MediaWiki:Gadget-hanja-reading.js
8
177043
754643
753727
2026-08-02T08:22:17Z
Namoroka
19627
754643
javascript
text/javascript
// 한자 독음 표시해주는 소도구
// 설명은 [[사용자:Aspere/한자 독음 소도구]] 참조
// 하위 문서: [[사용자:Aspere/hanja-base.js]], [[사용자:Aspere/hanja-variants.js]], [[사용자:Aspere/hanja-variants-cjkvi.js]], [[사용자:Aspere/hanja-overrides.js]]
$(function () {
const skin = mw.config.get('skin');
const portlet = 'p-associated-pages' // 버튼 위치
const buttontooltip = '한자를 한글 음가로 표시합니다.'
if (![0, 2, 4, 250].includes(mw.config.get('wgNamespaceNumber'))) return; // 적용할 이름공간 번호
var dict = {};
var subWordDict = {}; // 복합어 사전 객체
var subWordKeys = []; // 매칭 정렬용 키 배열
var dictReady = null;
var toggled = false;
// 기본적으로 한 번 캐시를 받아 1주일 간 사용
var DICT_CACHE_KEY = 'alphatest_v11'; // 이 값을 바꾸면 캐시가 강제로 갱신됨 (1주일 안 기다린다는 얘기)
var DICT_CACHE_MAX_AGE = 1000 * 30; // 캐시의 자동 갱신 주기 (1주일)
// 한자(정자/이체자/호환용 한자, 기본 다국어 평면 밖의 확장 영역, 반복 부호)
var HAN_RE = /[\p{Script=Han}々〻]/u;
var HAN_RUN_RE = /[\p{Script=Han}々〻]+/gu;
// ---- 두음법칙 ----
// 사전에 담긴 독음은 "비어두형(사전 표제음)"이 기본이므로(예: 樂→락, 女→녀),
// "한자 덩어리의 첫 글자인 경우" 두음법칙 규칙을 적용하여 변경
// (적용한 규칙: 한글 맞춤법 제10~12항: ㄴ/ㄹ+이야여예요유 → ㅇ, ㄹ+그 외 모음 → ㄴ)
var YI_MEDIALS = new Set([2, 3, 6, 7, 12, 17, 20]); // ㅑㅒㅕㅖㅛㅠㅣ
// 아라비아 숫자, 한글 수사, 한자 수사를 아우르는 숫자 패턴 (공백 허용)
// 한자 수사 문자 목록은 HANJA_NUMERAL_CHARS 하나로 관리하고 아래 정규식에도 재사용
var HANJA_NUMERAL_CHARS = '一二三四五六七八九十百千萬万億兆〇零';
var NUMBER_SUFX_RE = new RegExp(
'(?:[0-9\uFF10-\uFF19' + HANJA_NUMERAL_CHARS + ']' +
'|일|이|삼|사|오|육|칠|팔|구|십|백|천|만|억|조' +
'|한|두|세|네|다섯|여섯|일곱|여덟|아홉|열|스무|몇|매|수)\\s*$'
);
var PAREN_HANGUL_RE = /([가-힣]+)\s*\(\s*$/;
// ---- 아라비아 숫자 변환 관련 상수 ----
var ARABIC_NUM_MAP = {
'〇': '0', '一': '1', '二': '2', '三': '3', '四': '4',
'五': '5', '六': '6', '七': '7', '八': '8', '九': '9'
};
function applyDueum(syllable) {
if (!syllable) return syllable;
var first = syllable.charAt(0);
var code = first.charCodeAt(0) - 0xAC00;
if (code < 0 || code > 11171) return syllable; // 한글 음절이 아니면 그대로
var initial = Math.floor(code / (21 * 28));
var medial = Math.floor((code % (21 * 28)) / 28);
var final = code % 28;
var newInitial = initial;
if (initial === 2 /* ㄴ */ && YI_MEDIALS.has(medial)) {
newInitial = 11; // ㅇ
} else if (initial === 5 /* ㄹ */) {
newInitial = YI_MEDIALS.has(medial) ? 11 /* ㅇ */ : 2 /* ㄴ */;
} else {
return syllable;
}
var newFirst = String.fromCharCode(0xAC00 + (newInitial * 21 + medial) * 28 + final);
return newFirst + syllable.slice(1);
}
// 앞 글자가 모음(받침 없음)이거나 'ㄴ' 받침인지 확인하는 함수
function isVowelOrNieunEnding(syllable) {
if (!syllable) return false;
var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00;
if (code < 0 || code > 11171) return false;
var final = code % 28;
return final === 0 || final === 4; // 0: 받침 없음(모음), 4: ㄴ 받침
}
// 앞 글자가 'ㄹ' 받침인지 확인하는 함수 (의존 명사 '리' 예외 처리용)
function isRieulEnding(syllable) {
if (!syllable) return false;
var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00;
if (code < 0 || code > 11171) return false;
var final = code % 28;
return final === 8; // 8: ㄹ 받침
}
// 글자의 초성이 'ㄷ' 또는 'ㅈ'인지 확인하는 함수 ('不' 예외 처리용)
function isDigeutOrJieutStarting(syllable) {
if (!syllable) return false;
var first = syllable.charAt(0);
var code = first.charCodeAt(0) - 0xAC00;
if (code < 0 || code > 11171) return false;
var initial = Math.floor(code / (21 * 28));
return initial === 3 /* ㄷ */ || initial === 12 /* ㅈ */;
}
function fetchJson(pageName) {
var url = mw.util.wikiScript() + '?title=MediaWiki:Gadget-' + encodeURIComponent(pageName) +
'&action=raw&ctype=application/json';
return fetch(url).then(function (res) {
if (!res.ok) throw new Error(pageName + ' 응답 오류: ' + res.status);
return res.json();
});
}
function loadDict() {
if (dictReady) return dictReady;
dictReady = new Promise(function (resolve) {
try {
var cached = JSON.parse(localStorage.getItem(DICT_CACHE_KEY) || 'null');
if (cached && (Date.now() - cached.time) < DICT_CACHE_MAX_AGE) {
dict = cached.dict;
subWordDict = cached.subWordDict || {};
subWordKeys = Object.keys(subWordDict).sort(function (a, b) {
return b.length - a.length;
});
resolve();
return;
}
} catch (e) { /* 캐시 손상 시 무시 */ }
var files = [
'hanja-base2.json',
'hanja-variants.json',
'hanja-variants-cjkvi.json',
'hanja-history.json',
'hanja-overrides.json',
'hanja-word.json'
];
Promise.all(files.map(fetchJson))
.then(function (results) {
// 0~3번 결과는 단일 글자 사전에 병합
dict = Object.assign({}, results[0], results[1], results[2], results[3]);
// 4번 결과는 복합어 사전에 할당 후 길이순 정렬
subWordDict = results[4] || {};
subWordKeys = Object.keys(subWordDict).sort(function (a, b) {
return b.length - a.length;
});
try {
localStorage.setItem(DICT_CACHE_KEY, JSON.stringify({
time: Date.now(),
dict: dict,
subWordDict: subWordDict
}));
} catch (e) { /* 캐시 실패 무시 */ }
resolve();
})
.catch(function (e) {
console.error('[한자독음] 사전 로딩 실패:', e);
dictReady = null; // 다음 클릭 때 재시도되도록 초기화
resolve();
});
});
return dictReady;
}
function applyManualOverrides(root) {
root.querySelectorAll('.hanja-manual-reading:not(.hanja-converted)').forEach(function (el) {
var reading = el.dataset.reading;
if (!reading) return;
el.dataset.original = el.textContent;
el.textContent = reading;
el.classList.add('hanja-converted');
el.title = el.dataset.original;
});
}
// 한자가 아닌 부분은 그대로 두고, 한자 블록(연속된 한자 구간)만 개별 <span>으로 감싼다.
// 이렇게 하면 블록 단위로 두음법칙 적용 + 원문 title 표시 + 스타일 지정이 가능하다.
function buildConvertedFragment(text, precedingText) {
var frag = document.createDocumentFragment();
var lastIndex = 0;
var m;
HAN_RUN_RE.lastIndex = 0;
while ((m = HAN_RUN_RE.exec(text))) {
if (m.index > lastIndex) {
frag.appendChild(document.createTextNode(text.slice(lastIndex, m.index)));
}
var run = m[0];
var context = precedingText + text.slice(0, m.index);
var convertedChars = [];
var chars = Array.from(run); // 코드포인트 단위(확장 한자 서로게이트 쌍 포함) 분리
// 반복 부호(々, 〻)를 바로 앞의 한자로 치환
for (var j = 0; j < chars.length; j++) {
if (chars[j] === '々' || chars[j] === '〻') {
if (j > 0) {
chars[j] = chars[j - 1];
}
}
}
// 한자 수사로만 이루어진 덩어리(예: 六千六百六十六)는 각 자릿수를 독립된 단어처럼 취급해
// 위치와 무관하게 두음법칙을 적용한다.
var isPureNumeralRun = chars.length > 1 && chars.every(function (c) {
return HANJA_NUMERAL_CHARS.indexOf(c) !== -1;
});
for (var i = 0; i < chars.length; ) {
// 1) 아라비아 숫자 연속 표기(〇 포함 또는 2자리 이상)의 치환 처리 (예: 二〇二六 -> 2026)
var arabicLen = 0;
while (i + arabicLen < chars.length && Object.prototype.hasOwnProperty.call(ARABIC_NUM_MAP, chars[i + arabicLen])) {
arabicLen++;
}
var arabicSubRun = chars.slice(i, i + arabicLen);
// 길이가 2이상이거나 〇가 포함되어 있으면 아라비아 숫자로 간주
var isArabicCandidate = arabicLen >= 2;
if (isArabicCandidate) {
var arabicStr = arabicSubRun.map(function(c) { return ARABIC_NUM_MAP[c]; }).join('');
convertedChars.push(arabicStr);
i += arabicLen;
continue; // 변환 완료 후 다음 글자로 건너뜀
}
var ch = chars[i];
if (isPureNumeralRun) {
convertedChars.push(applyDueum(dict[ch] || ch));
i++;
continue;
}
var fullBefore = context + convertedChars.join('');
var isAfterNum = NUMBER_SUFX_RE.test(fullBefore);
var parenMatch = fullBefore.match(PAREN_HANGUL_RE);
var parenHangul = parenMatch ? parenMatch[1] : null;
var matchedWord = null;
var matchedReading = null;
var matchedWordLen = 0;
// 2) 전역 복합어 사전을 참조하여 매칭 확인 (Surrogate Pair 오류 방지를 위해 배열 슬라이싱 사용)
for (var k = 0; k < subWordKeys.length; k++) {
var key = subWordKeys[k];
var keyChars = Array.from(key);
if (chars.slice(i, i + keyChars.length).join('') === key) {
matchedWord = key;
matchedWordLen = keyChars.length;
matchedReading = subWordDict[key];
break;
}
}
if (matchedWord) {
// 수량사 뒤 "年度" 예외 조정 (연도 -> 년도)
if (isAfterNum && matchedWord === "年度") {
matchedReading = "년도";
}
convertedChars.push(matchedReading);
i += matchedWordLen; // 올바른 글자수만큼 인덱스 전진
} else {
// 3) 개별 글자 처리 및 문맥 검사
var reading = dict[ch] || ch;
// '不' 예외 처리: 뒤에 오는 글자의 초성이 'ㄷ', 'ㅈ'이거나 '實'인 경우 '부'로 발음
if (ch === '不') {
var nextCharObj = (i + 1 < chars.length) ? chars[i + 1] : text.charAt(m.index + run.length);
var nextCharReading = dict[nextCharObj] || nextCharObj;
if (nextCharObj === '實' || isDigeutOrJieutStarting(nextCharReading)) {
reading = '부';
}
}
// '金' 예외 처리: 한자 덩어리 내에서 첫 글자면(앞에 한자가 없으면) '김', 아니면 '금'
if (ch === '金' || ch === '金') {
reading = (i === 0) ? '김' : '금';
}
var finalReading = reading;
// 이전 글자(방금 변환된 한글이거나 한자 블록 앞의 일반 텍스트)를 추적
// 띄어쓰기가 있어도 직전 한글을 올바르게 찾도록 정규식 활용
var prevMatch = context.match(/([가-힣])\s*$/);
var prevHangul = convertedChars.length > 0
? convertedChars[convertedChars.length - 1]
: (prevMatch ? prevMatch[1] : context.slice(-1));
if (isAfterNum) {
if (ch === '兩') finalReading = '냥';
else if (ch === '年') finalReading = '년';
else finalReading = reading; // 일반적인 경우 두음법칙 무력화 (예: 3里 -> 3리)
} else if (parenHangul) {
// 괄호 바로 앞 한글 가이드와 부합하면 원음 반영 (예: 냥(兩) -> 냥, 냥쭝(兩쭝) -> 냥쭝)
if (ch === '兩' && parenHangul.startsWith('냥')) finalReading = '냥';
else if (ch === '兩' && parenHangul.startsWith('양')) finalReading = '양';
else if (ch === '年' && parenHangul.startsWith('년')) finalReading = '년';
else if (ch === '年' && parenHangul.startsWith('연')) finalReading = '연';
else finalReading = (i === 0) ? applyDueum(reading) : reading;
} else {
// 모음이나 ㄴ 받침 뒤에 이어지는 '렬, 률'은 '열, 율'로 발음
if ((reading === '렬' || reading === '률') && isVowelOrNieunEnding(prevHangul)) {
finalReading = (reading === '렬') ? '열' : '율';
} else if (ch === '理' && i === 0 && chars.length === 1 && isRieulEnding(prevHangul)) {
// '-을/ㄹ' 어미 뒤에 단독으로 쓰인 '理'는 의존 명사이므로 두음법칙 예외
finalReading = '리';
} else {
// 일반적인 한자 덩어리의 첫머리에만 두음법칙 적용
finalReading = (i === 0) ? applyDueum(reading) : reading;
}
}
convertedChars.push(finalReading);
i++;
}
}
var span = document.createElement('span');
span.textContent = convertedChars.join('');
span.dataset.original = run;
span.title = run; // 마우스 오버 시 원문 한자 확인
span.classList.add('hanja-converted');
frag.appendChild(span);
lastIndex = m.index + run.length;
}
if (lastIndex < text.length) {
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
}
return frag;
}
// root를 화면(DOM)에서 잠시 떼어낸 뒤 fn(root)를 실행하고 다시 붙인다.
function withDetached(root, fn) {
var parent = root.parentNode;
var nextSibling = root.nextSibling;
var wasDetached = !parent;
if (!wasDetached) parent.removeChild(root);
try {
fn(root);
} finally {
if (!wasDetached) {
if (nextSibling) parent.insertBefore(root, nextSibling);
else parent.appendChild(root);
}
}
}
function convertNode(root) {
withDetached(root, function (root) {
applyManualOverrides(root); // 1) 틀로 지정된 부분 먼저 처리
// 2) 문서를 순서대로 한 번만 훑으며, 직전 글자를 흘려보낸다 (O(n))
var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
var lastText = "";
var toProcess = [];
var node;
while ((node = walker.nextNode())) {
var text = node.nodeValue;
if (!text) continue;
var insideConverted = node.parentNode && node.parentNode.closest &&
node.parentNode.closest('.hanja-converted');
if (!insideConverted && HAN_RE.test(text)) {
toProcess.push({ node: node, precedingText: lastText });
}
if (!insideConverted && text.length) {
lastText = (lastText + text).slice(-50); // 최근 50글자까지만 버퍼에 보존
}
}
toProcess.forEach(function (item) {
var frag = buildConvertedFragment(item.node.nodeValue, item.precedingText);
item.node.parentNode.replaceChild(frag, item.node);
});
});
}
function restore(root) {
withDetached(root, function (root) {
root.querySelectorAll('.hanja-converted').forEach(function (span) {
if (span.classList.contains('hanja-manual-reading')) {
span.textContent = span.dataset.original;
span.classList.remove('hanja-converted');
span.removeAttribute('title');
} else {
span.replaceWith(document.createTextNode(span.dataset.original));
}
});
});
}
mw.loader.using('mediawiki.util').then(function () {
// 변환된 한자에 옅은 점선 밑줄을 넣어, 원문과 구분되게 하되 가독성은 해치지 않도록 함.
mw.util.addCSS(
'.hanja-converted {' +
' border-bottom: 1px dotted rgba(128,128,128,0.6);' +
' cursor: help;' +
' text-decoration: none;' +
'}'
);
mw.util.addPortletLink(portlet, '#', '한자 독음', 'ca-hanja2hangul', buttontooltip);
$('#ca-hanja2hangul').on('click', function (e) {
e.preventDefault();
loadDict().then(function () {
var content = document.querySelector('#mw-content-text .mw-parser-output');
if (!content) return;
toggled = !toggled;
toggled ? convertNode(content) : restore(content);
});
});
});
});
63ztlek7xjz5su5fndhjys1mkzy089k
754644
754643
2026-08-02T08:28:35Z
Namoroka
19627
754644
javascript
text/javascript
// 한자 독음 표시해주는 소도구
// 설명은 [[사용자:Aspere/한자 독음 소도구]] 참조
// 하위 문서: [[사용자:Aspere/hanja-base.js]], [[사용자:Aspere/hanja-variants.js]], [[사용자:Aspere/hanja-variants-cjkvi.js]], [[사용자:Aspere/hanja-overrides.js]]
$(function () {
const skin = mw.config.get('skin');
const portlet = 'p-associated-pages' // 버튼 위치
const buttontooltip = '한자를 한글 음가로 표시합니다.'
if (![0, 2, 4, 250].includes(mw.config.get('wgNamespaceNumber'))) return; // 적용할 이름공간 번호
var dict = {};
var subWordDict = {}; // 복합어 사전 객체
var subWordKeys = []; // 매칭 정렬용 키 배열
var dictReady = null;
var toggled = false;
// 기본적으로 한 번 캐시를 받아 1주일 간 사용
var DICT_CACHE_KEY = 'alphatest_v11'; // 이 값을 바꾸면 캐시가 강제로 갱신됨 (1주일 안 기다린다는 얘기)
var DICT_CACHE_MAX_AGE = 1000 * 30; // 캐시의 자동 갱신 주기 (1주일)
// 한자(정자/이체자/호환용 한자, 기본 다국어 평면 밖의 확장 영역, 반복 부호)
var HAN_RE = /[\p{Script=Han}々〻]/u;
var HAN_RUN_RE = /[\p{Script=Han}々〻]+/gu;
// ---- 두음법칙 ----
// 사전에 담긴 독음은 "비어두형(사전 표제음)"이 기본이므로(예: 樂→락, 女→녀),
// "한자 덩어리의 첫 글자인 경우" 두음법칙 규칙을 적용하여 변경
// (적용한 규칙: 한글 맞춤법 제10~12항: ㄴ/ㄹ+이야여예요유 → ㅇ, ㄹ+그 외 모음 → ㄴ)
var YI_MEDIALS = new Set([2, 3, 6, 7, 12, 17, 20]); // ㅑㅒㅕㅖㅛㅠㅣ
// 아라비아 숫자, 한글 수사, 한자 수사를 아우르는 숫자 패턴 (공백 허용)
// 한자 수사 문자 목록은 HANJA_NUMERAL_CHARS 하나로 관리하고 아래 정규식에도 재사용
var HANJA_NUMERAL_CHARS = '一二三四五六七八九十百千萬万億兆〇零';
var NUMBER_SUFX_RE = new RegExp(
'(?:[0-9\uFF10-\uFF19' + HANJA_NUMERAL_CHARS + ']' +
'|일|이|삼|사|오|육|칠|팔|구|십|백|천|만|억|조' +
'|한|두|세|네|다섯|여섯|일곱|여덟|아홉|열|스무|몇|매|수)\\s*$'
);
var PAREN_HANGUL_RE = /([가-힣]+)\s*\(\s*$/;
// ---- 아라비아 숫자 변환 관련 상수 ----
var ARABIC_NUM_MAP = {
'〇': '0', '一': '1', '二': '2', '三': '3', '四': '4',
'五': '5', '六': '6', '七': '7', '八': '8', '九': '9'
};
function applyDueum(syllable) {
if (!syllable) return syllable;
var first = syllable.charAt(0);
var code = first.charCodeAt(0) - 0xAC00;
if (code < 0 || code > 11171) return syllable; // 한글 음절이 아니면 그대로
var initial = Math.floor(code / (21 * 28));
var medial = Math.floor((code % (21 * 28)) / 28);
var final = code % 28;
var newInitial = initial;
if (initial === 2 /* ㄴ */ && YI_MEDIALS.has(medial)) {
newInitial = 11; // ㅇ
} else if (initial === 5 /* ㄹ */) {
newInitial = YI_MEDIALS.has(medial) ? 11 /* ㅇ */ : 2 /* ㄴ */;
} else {
return syllable;
}
var newFirst = String.fromCharCode(0xAC00 + (newInitial * 21 + medial) * 28 + final);
return newFirst + syllable.slice(1);
}
// 앞 글자가 모음(받침 없음)이거나 'ㄴ' 받침인지 확인하는 함수
function isVowelOrNieunEnding(syllable) {
if (!syllable) return false;
var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00;
if (code < 0 || code > 11171) return false;
var final = code % 28;
return final === 0 || final === 4; // 0: 받침 없음(모음), 4: ㄴ 받침
}
// 앞 글자가 'ㄹ' 받침인지 확인하는 함수 (의존 명사 '리' 예외 처리용)
function isRieulEnding(syllable) {
if (!syllable) return false;
var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00;
if (code < 0 || code > 11171) return false;
var final = code % 28;
return final === 8; // 8: ㄹ 받침
}
// 글자의 초성이 'ㄷ' 또는 'ㅈ'인지 확인하는 함수 ('不' 예외 처리용)
function isDigeutOrJieutStarting(syllable) {
if (!syllable) return false;
var first = syllable.charAt(0);
var code = first.charCodeAt(0) - 0xAC00;
if (code < 0 || code > 11171) return false;
var initial = Math.floor(code / (21 * 28));
return initial === 3 /* ㄷ */ || initial === 12 /* ㅈ */;
}
function fetchJson(pageName) {
var url = mw.util.wikiScript() + '?title=MediaWiki:Gadget-' + encodeURIComponent(pageName) +
'&action=raw&ctype=application/json';
return fetch(url).then(function (res) {
if (!res.ok) throw new Error(pageName + ' 응답 오류: ' + res.status);
return res.json();
});
}
function loadDict() {
if (dictReady) return dictReady;
dictReady = new Promise(function (resolve) {
try {
var cached = JSON.parse(localStorage.getItem(DICT_CACHE_KEY) || 'null');
if (cached && (Date.now() - cached.time) < DICT_CACHE_MAX_AGE) {
dict = cached.dict;
subWordDict = cached.subWordDict || {};
subWordKeys = Object.keys(subWordDict).sort(function (a, b) {
return b.length - a.length;
});
resolve();
return;
}
} catch (e) { /* 캐시 손상 시 무시 */ }
var files = [
'hanja-base2.json',
'hanja-variants.json',
'hanja-variants-cjkvi.json',
'hanja-history.json',
'hanja-overrides.json',
'hanja-word.json'
];
Promise.all(files.map(fetchJson))
.then(function (results) {
// 0~4번 결과는 단일 글자 사전에 병합
dict = Object.assign({}, results[0], results[1], results[2], results[3], results[4]);
// 5번 결과는 복합어 사전에 할당 후 길이순 정렬
subWordDict = results[5] || {};
subWordKeys = Object.keys(subWordDict).sort(function (a, b) {
return b.length - a.length;
});
try {
localStorage.setItem(DICT_CACHE_KEY, JSON.stringify({
time: Date.now(),
dict: dict,
subWordDict: subWordDict
}));
} catch (e) { /* 캐시 실패 무시 */ }
resolve();
})
.catch(function (e) {
console.error('[한자독음] 사전 로딩 실패:', e);
dictReady = null; // 다음 클릭 때 재시도되도록 초기화
resolve();
});
});
return dictReady;
}
function applyManualOverrides(root) {
root.querySelectorAll('.hanja-manual-reading:not(.hanja-converted)').forEach(function (el) {
var reading = el.dataset.reading;
if (!reading) return;
el.dataset.original = el.textContent;
el.textContent = reading;
el.classList.add('hanja-converted');
el.title = el.dataset.original;
});
}
// 한자가 아닌 부분은 그대로 두고, 한자 블록(연속된 한자 구간)만 개별 <span>으로 감싼다.
// 이렇게 하면 블록 단위로 두음법칙 적용 + 원문 title 표시 + 스타일 지정이 가능하다.
function buildConvertedFragment(text, precedingText) {
var frag = document.createDocumentFragment();
var lastIndex = 0;
var m;
HAN_RUN_RE.lastIndex = 0;
while ((m = HAN_RUN_RE.exec(text))) {
if (m.index > lastIndex) {
frag.appendChild(document.createTextNode(text.slice(lastIndex, m.index)));
}
var run = m[0];
var context = precedingText + text.slice(0, m.index);
var convertedChars = [];
var chars = Array.from(run); // 코드포인트 단위(확장 한자 서로게이트 쌍 포함) 분리
// 반복 부호(々, 〻)를 바로 앞의 한자로 치환
for (var j = 0; j < chars.length; j++) {
if (chars[j] === '々' || chars[j] === '〻') {
if (j > 0) {
chars[j] = chars[j - 1];
}
}
}
// 한자 수사로만 이루어진 덩어리(예: 六千六百六十六)는 각 자릿수를 독립된 단어처럼 취급해
// 위치와 무관하게 두음법칙을 적용한다.
var isPureNumeralRun = chars.length > 1 && chars.every(function (c) {
return HANJA_NUMERAL_CHARS.indexOf(c) !== -1;
});
for (var i = 0; i < chars.length; ) {
// 1) 아라비아 숫자 연속 표기(〇 포함 또는 2자리 이상)의 치환 처리 (예: 二〇二六 -> 2026)
var arabicLen = 0;
while (i + arabicLen < chars.length && Object.prototype.hasOwnProperty.call(ARABIC_NUM_MAP, chars[i + arabicLen])) {
arabicLen++;
}
var arabicSubRun = chars.slice(i, i + arabicLen);
// 길이가 2이상이거나 〇가 포함되어 있으면 아라비아 숫자로 간주
var isArabicCandidate = arabicLen >= 2;
if (isArabicCandidate) {
var arabicStr = arabicSubRun.map(function(c) { return ARABIC_NUM_MAP[c]; }).join('');
convertedChars.push(arabicStr);
i += arabicLen;
continue; // 변환 완료 후 다음 글자로 건너뜀
}
var ch = chars[i];
if (isPureNumeralRun) {
convertedChars.push(applyDueum(dict[ch] || ch));
i++;
continue;
}
var fullBefore = context + convertedChars.join('');
var isAfterNum = NUMBER_SUFX_RE.test(fullBefore);
var parenMatch = fullBefore.match(PAREN_HANGUL_RE);
var parenHangul = parenMatch ? parenMatch[1] : null;
var matchedWord = null;
var matchedReading = null;
var matchedWordLen = 0;
// 2) 전역 복합어 사전을 참조하여 매칭 확인 (Surrogate Pair 오류 방지를 위해 배열 슬라이싱 사용)
for (var k = 0; k < subWordKeys.length; k++) {
var key = subWordKeys[k];
var keyChars = Array.from(key);
if (chars.slice(i, i + keyChars.length).join('') === key) {
matchedWord = key;
matchedWordLen = keyChars.length;
matchedReading = subWordDict[key];
break;
}
}
if (matchedWord) {
// 수량사 뒤 "年度" 예외 조정 (연도 -> 년도)
if (isAfterNum && matchedWord === "年度") {
matchedReading = "년도";
}
convertedChars.push(matchedReading);
i += matchedWordLen; // 올바른 글자수만큼 인덱스 전진
} else {
// 3) 개별 글자 처리 및 문맥 검사
var reading = dict[ch] || ch;
// '不' 예외 처리: 뒤에 오는 글자의 초성이 'ㄷ', 'ㅈ'이거나 '實'인 경우 '부'로 발음
if (ch === '不') {
var nextCharObj = (i + 1 < chars.length) ? chars[i + 1] : text.charAt(m.index + run.length);
var nextCharReading = dict[nextCharObj] || nextCharObj;
if (nextCharObj === '實' || isDigeutOrJieutStarting(nextCharReading)) {
reading = '부';
}
}
// '金' 예외 처리: 한자 덩어리 내에서 첫 글자면(앞에 한자가 없으면) '김', 아니면 '금'
if (ch === '金' || ch === '金') {
reading = (i === 0) ? '김' : '금';
}
var finalReading = reading;
// 이전 글자(방금 변환된 한글이거나 한자 블록 앞의 일반 텍스트)를 추적
// 띄어쓰기가 있어도 직전 한글을 올바르게 찾도록 정규식 활용
var prevMatch = context.match(/([가-힣])\s*$/);
var prevHangul = convertedChars.length > 0
? convertedChars[convertedChars.length - 1]
: (prevMatch ? prevMatch[1] : context.slice(-1));
if (isAfterNum) {
if (ch === '兩') finalReading = '냥';
else if (ch === '年') finalReading = '년';
else finalReading = reading; // 일반적인 경우 두음법칙 무력화 (예: 3里 -> 3리)
} else if (parenHangul) {
// 괄호 바로 앞 한글 가이드와 부합하면 원음 반영 (예: 냥(兩) -> 냥, 냥쭝(兩쭝) -> 냥쭝)
if (ch === '兩' && parenHangul.startsWith('냥')) finalReading = '냥';
else if (ch === '兩' && parenHangul.startsWith('양')) finalReading = '양';
else if (ch === '年' && parenHangul.startsWith('년')) finalReading = '년';
else if (ch === '年' && parenHangul.startsWith('연')) finalReading = '연';
else finalReading = (i === 0) ? applyDueum(reading) : reading;
} else {
// 모음이나 ㄴ 받침 뒤에 이어지는 '렬, 률'은 '열, 율'로 발음
if ((reading === '렬' || reading === '률') && isVowelOrNieunEnding(prevHangul)) {
finalReading = (reading === '렬') ? '열' : '율';
} else if (ch === '理' && i === 0 && chars.length === 1 && isRieulEnding(prevHangul)) {
// '-을/ㄹ' 어미 뒤에 단독으로 쓰인 '理'는 의존 명사이므로 두음법칙 예외
finalReading = '리';
} else {
// 일반적인 한자 덩어리의 첫머리에만 두음법칙 적용
finalReading = (i === 0) ? applyDueum(reading) : reading;
}
}
convertedChars.push(finalReading);
i++;
}
}
var span = document.createElement('span');
span.textContent = convertedChars.join('');
span.dataset.original = run;
span.title = run; // 마우스 오버 시 원문 한자 확인
span.classList.add('hanja-converted');
frag.appendChild(span);
lastIndex = m.index + run.length;
}
if (lastIndex < text.length) {
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
}
return frag;
}
// root를 화면(DOM)에서 잠시 떼어낸 뒤 fn(root)를 실행하고 다시 붙인다.
function withDetached(root, fn) {
var parent = root.parentNode;
var nextSibling = root.nextSibling;
var wasDetached = !parent;
if (!wasDetached) parent.removeChild(root);
try {
fn(root);
} finally {
if (!wasDetached) {
if (nextSibling) parent.insertBefore(root, nextSibling);
else parent.appendChild(root);
}
}
}
function convertNode(root) {
withDetached(root, function (root) {
applyManualOverrides(root); // 1) 틀로 지정된 부분 먼저 처리
// 2) 문서를 순서대로 한 번만 훑으며, 직전 글자를 흘려보낸다 (O(n))
var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
var lastText = "";
var toProcess = [];
var node;
while ((node = walker.nextNode())) {
var text = node.nodeValue;
if (!text) continue;
var insideConverted = node.parentNode && node.parentNode.closest &&
node.parentNode.closest('.hanja-converted');
if (!insideConverted && HAN_RE.test(text)) {
toProcess.push({ node: node, precedingText: lastText });
}
if (!insideConverted && text.length) {
lastText = (lastText + text).slice(-50); // 최근 50글자까지만 버퍼에 보존
}
}
toProcess.forEach(function (item) {
var frag = buildConvertedFragment(item.node.nodeValue, item.precedingText);
item.node.parentNode.replaceChild(frag, item.node);
});
});
}
function restore(root) {
withDetached(root, function (root) {
root.querySelectorAll('.hanja-converted').forEach(function (span) {
if (span.classList.contains('hanja-manual-reading')) {
span.textContent = span.dataset.original;
span.classList.remove('hanja-converted');
span.removeAttribute('title');
} else {
span.replaceWith(document.createTextNode(span.dataset.original));
}
});
});
}
mw.loader.using('mediawiki.util').then(function () {
// 변환된 한자에 옅은 점선 밑줄을 넣어, 원문과 구분되게 하되 가독성은 해치지 않도록 함.
mw.util.addCSS(
'.hanja-converted {' +
' border-bottom: 1px dotted rgba(128,128,128,0.6);' +
' cursor: help;' +
' text-decoration: none;' +
'}'
);
mw.util.addPortletLink(portlet, '#', '한자 독음', 'ca-hanja2hangul', buttontooltip);
$('#ca-hanja2hangul').on('click', function (e) {
e.preventDefault();
loadDict().then(function () {
var content = document.querySelector('#mw-content-text .mw-parser-output');
if (!content) return;
toggled = !toggled;
toggled ? convertNode(content) : restore(content);
});
});
});
});
9ncdkej370qwbhvhwg5n2lm4bf975sq
754649
754644
2026-08-02T08:45:56Z
Namoroka
19627
754649
javascript
text/javascript
// 한자 독음 표시해주는 소도구
// 설명은 [[사용자:Aspere/한자 독음 소도구]] 참조
// 하위 문서: [[사용자:Aspere/hanja-base.js]], [[사용자:Aspere/hanja-variants.js]], [[사용자:Aspere/hanja-variants-cjkvi.js]], [[사용자:Aspere/hanja-overrides.js]]
$(function () {
const skin = mw.config.get('skin');
const portlet = 'p-associated-pages' // 버튼 위치
const buttontooltip = '한자를 한글 음가로 표시합니다.'
if (![0, 2, 4, 250].includes(mw.config.get('wgNamespaceNumber'))) return; // 적용할 이름공간 번호
var dict = {};
var subWordDict = {}; // 복합어 사전 객체
var subWordKeys = []; // 매칭 정렬용 키 배열
var dictReady = null;
var toggled = false;
// 기본적으로 한 번 캐시를 받아 1주일 간 사용
var DICT_CACHE_KEY = 'alphatest_v11'; // 이 값을 바꾸면 캐시가 강제로 갱신됨 (1주일 안 기다린다는 얘기)
var DICT_CACHE_MAX_AGE = 1000 * 30; // 캐시의 자동 갱신 주기 (1주일)
// 한자(정자/이체자/호환용 한자, 기본 다국어 평면 밖의 확장 영역, 반복 부호)
var HAN_RE = /[\p{Script=Han}々〻]/u;
var HAN_RUN_RE = /[\p{Script=Han}々〻]+/gu;
// ---- 두음법칙 ----
// 사전에 담긴 독음은 "비어두형(사전 표제음)"이 기본이므로(예: 樂→락, 女→녀),
// "한자 덩어리의 첫 글자인 경우" 두음법칙 규칙을 적용하여 변경
// (적용한 규칙: 한글 맞춤법 제10~12항: ㄴ/ㄹ+이야여예요유 → ㅇ, ㄹ+그 외 모음 → ㄴ)
var YI_MEDIALS = new Set([2, 3, 6, 7, 12, 17, 20]); // ㅑㅒㅕㅖㅛㅠㅣ
// 아라비아 숫자, 한글 수사, 한자 수사를 아우르는 숫자 패턴 (공백 허용)
// 한자 수사 문자 목록은 HANJA_NUMERAL_CHARS 하나로 관리하고 아래 정규식에도 재사용
var HANJA_NUMERAL_CHARS = '一二三四五六七八九十百千萬万億兆〇零';
var NUMBER_SUFX_RE = new RegExp(
'(?:[0-9\uFF10-\uFF19' + HANJA_NUMERAL_CHARS + ']' +
'|일|이|삼|사|오|육|칠|팔|구|십|백|천|만|억|조' +
'|한|두|세|네|다섯|여섯|일곱|여덟|아홉|열|스무|몇|매|수)\\s*$'
);
var PAREN_HANGUL_RE = /([가-힣]+)\s*\(\s*$/;
// ---- 아라비아 숫자 변환 관련 상수 ----
var ARABIC_NUM_MAP = {
'〇': '0', '一': '1', '二': '2', '三': '3', '四': '4',
'五': '5', '六': '6', '七': '7', '八': '8', '九': '9'
};
function applyDueum(syllable) {
if (!syllable) return syllable;
var first = syllable.charAt(0);
var code = first.charCodeAt(0) - 0xAC00;
if (code < 0 || code > 11171) return syllable; // 한글 음절이 아니면 그대로
var initial = Math.floor(code / (21 * 28));
var medial = Math.floor((code % (21 * 28)) / 28);
var final = code % 28;
var newInitial = initial;
if (initial === 2 /* ㄴ */ && YI_MEDIALS.has(medial)) {
newInitial = 11; // ㅇ
} else if (initial === 5 /* ㄹ */) {
newInitial = YI_MEDIALS.has(medial) ? 11 /* ㅇ */ : 2 /* ㄴ */;
} else {
return syllable;
}
var newFirst = String.fromCharCode(0xAC00 + (newInitial * 21 + medial) * 28 + final);
return newFirst + syllable.slice(1);
}
// 앞 글자가 모음(받침 없음)이거나 'ㄴ' 받침인지 확인하는 함수
function isVowelOrNieunEnding(syllable) {
if (!syllable) return false;
var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00;
if (code < 0 || code > 11171) return false;
var final = code % 28;
return final === 0 || final === 4; // 0: 받침 없음(모음), 4: ㄴ 받침
}
// 앞 글자가 'ㄹ' 받침인지 확인하는 함수 (의존 명사 '리' 예외 처리용)
function isRieulEnding(syllable) {
if (!syllable) return false;
var code = syllable.charCodeAt(syllable.length - 1) - 0xAC00;
if (code < 0 || code > 11171) return false;
var final = code % 28;
return final === 8; // 8: ㄹ 받침
}
// 글자의 초성이 'ㄷ' 또는 'ㅈ'인지 확인하는 함수 ('不' 예외 처리용)
function isDigeutOrJieutStarting(syllable) {
if (!syllable) return false;
var first = syllable.charAt(0);
var code = first.charCodeAt(0) - 0xAC00;
if (code < 0 || code > 11171) return false;
var initial = Math.floor(code / (21 * 28));
return initial === 3 /* ㄷ */ || initial === 12 /* ㅈ */;
}
function fetchJson(pageName) {
var url = mw.util.wikiScript() + '?title=MediaWiki:Gadget-' + encodeURIComponent(pageName) +
'&action=raw&ctype=application/json';
return fetch(url).then(function (res) {
if (!res.ok) throw new Error(pageName + ' 응답 오류: ' + res.status);
return res.json();
});
}
function loadDict() {
if (dictReady) return dictReady;
dictReady = new Promise(function (resolve) {
try {
var cached = JSON.parse(localStorage.getItem(DICT_CACHE_KEY) || 'null');
if (cached && (Date.now() - cached.time) < DICT_CACHE_MAX_AGE) {
dict = cached.dict;
subWordDict = cached.subWordDict || {};
subWordKeys = Object.keys(subWordDict).sort(function (a, b) {
return b.length - a.length;
});
resolve();
return;
}
} catch (e) { /* 캐시 손상 시 무시 */ }
var files = [
'hanja-base2.json',
'hanja-variants.json',
'hanja-variants-cjkvi.json',
'hanja-history.json',
'hanja-overrides.json',
'hanja-word.json'
];
Promise.all(files.map(fetchJson))
.then(function (results) {
// 0~4번 결과는 단일 글자 사전에 병합
dict = Object.assign({}, results[0], results[1], results[2], results[3], results[4]);
// 5번 결과는 복합어 사전에 할당 후 길이순 정렬
subWordDict = results[5] || {};
subWordKeys = Object.keys(subWordDict).sort(function (a, b) {
return b.length - a.length;
});
try {
localStorage.setItem(DICT_CACHE_KEY, JSON.stringify({
time: Date.now(),
dict: dict,
subWordDict: subWordDict
}));
} catch (e) { /* 캐시 실패 무시 */ }
resolve();
})
.catch(function (e) {
console.error('[한자독음] 사전 로딩 실패:', e);
dictReady = null; // 다음 클릭 때 재시도되도록 초기화
resolve();
});
});
return dictReady;
}
function applyManualOverrides(root) {
root.querySelectorAll('.hanja-manual-reading:not(.hanja-converted)').forEach(function (el) {
var reading = el.dataset.reading;
if (!reading) return;
el.dataset.original = el.textContent;
el.textContent = reading;
el.classList.add('hanja-converted');
el.title = el.dataset.original;
});
}
// 한자가 아닌 부분은 그대로 두고, 한자 블록(연속된 한자 구간)만 개별 <span>으로 감싼다.
// 이렇게 하면 블록 단위로 두음법칙 적용 + 원문 title 표시 + 스타일 지정이 가능하다.
function buildConvertedFragment(text, precedingText) {
var frag = document.createDocumentFragment();
var lastIndex = 0;
var m;
HAN_RUN_RE.lastIndex = 0;
while ((m = HAN_RUN_RE.exec(text))) {
if (m.index > lastIndex) {
frag.appendChild(document.createTextNode(text.slice(lastIndex, m.index)));
}
var run = m[0];
var context = precedingText + text.slice(0, m.index);
var convertedChars = [];
var chars = Array.from(run); // 코드포인트 단위(확장 한자 서로게이트 쌍 포함) 분리
// 반복 부호(々, 〻)를 바로 앞의 한자로 치환
for (var j = 0; j < chars.length; j++) {
if (chars[j] === '々' || chars[j] === '〻') {
if (j > 0) {
chars[j] = chars[j - 1];
}
}
}
// 한자 수사로만 이루어진 덩어리(예: 六千六百六十六)는 각 자릿수를 독립된 단어처럼 취급해
// 위치와 무관하게 두음법칙을 적용한다.
var isPureNumeralRun = chars.length > 1 && chars.every(function (c) {
return HANJA_NUMERAL_CHARS.indexOf(c) !== -1;
});
for (var i = 0; i < chars.length; ) {
// 1) 아라비아 숫자 연속 표기(전화번호/일련번호 등 "코드형" 숫자열)의 치환 처리
// (예: 二〇二六 -> 2026, 〇二-一二三-四五六七 -> 02-123-4567)
// 단, 一一/一々처럼 그냥 같은 수사가 반복된 경우(예: 일일이)는 국어 발음으로 읽어야 하므로
// "〇(영) 포함" 또는 "앞/뒤가 하이픈으로 이어진 자릿수 그룹"일 때만 코드로 간주한다.
var arabicLen = 0;
while (i + arabicLen < chars.length && Object.prototype.hasOwnProperty.call(ARABIC_NUM_MAP, chars[i + arabicLen])) {
arabicLen++;
}
var arabicSubRun = chars.slice(i, i + arabicLen);
var beforeCandidate = context + convertedChars.join('');
var afterRun = chars.slice(i + arabicLen).join('') + text.slice(m.index + run.length);
var containsZero = arabicSubRun.indexOf('〇') !== -1;
var adjacentDash = /[-–—]\s*$/.test(beforeCandidate) || /^\s*[-–—]/.test(afterRun);
var isArabicCandidate = arabicLen >= 2 && (containsZero || adjacentDash);
if (isArabicCandidate) {
var arabicStr = arabicSubRun.map(function(c) { return ARABIC_NUM_MAP[c]; }).join('');
convertedChars.push(arabicStr);
i += arabicLen;
continue; // 변환 완료 후 다음 글자로 건너뜀
}
var ch = chars[i];
if (isPureNumeralRun) {
convertedChars.push(applyDueum(dict[ch] || ch));
i++;
continue;
}
var fullBefore = context + convertedChars.join('');
var isAfterNum = NUMBER_SUFX_RE.test(fullBefore);
var parenMatch = fullBefore.match(PAREN_HANGUL_RE);
var parenHangul = parenMatch ? parenMatch[1] : null;
var matchedWord = null;
var matchedReading = null;
var matchedWordLen = 0;
// 2) 전역 복합어 사전을 참조하여 매칭 확인 (Surrogate Pair 오류 방지를 위해 배열 슬라이싱 사용)
for (var k = 0; k < subWordKeys.length; k++) {
var key = subWordKeys[k];
var keyChars = Array.from(key);
if (chars.slice(i, i + keyChars.length).join('') === key) {
matchedWord = key;
matchedWordLen = keyChars.length;
matchedReading = subWordDict[key];
break;
}
}
if (matchedWord) {
// 수량사 뒤 "年度" 예외 조정 (연도 -> 년도)
if (isAfterNum && matchedWord === "年度") {
matchedReading = "년도";
}
convertedChars.push(matchedReading);
i += matchedWordLen; // 올바른 글자수만큼 인덱스 전진
} else {
// 3) 개별 글자 처리 및 문맥 검사
var reading = dict[ch] || ch;
// '不' 예외 처리: 뒤에 오는 글자의 초성이 'ㄷ', 'ㅈ'이거나 '實'인 경우 '부'로 발음
if (ch === '不') {
var nextCharObj = (i + 1 < chars.length) ? chars[i + 1] : text.charAt(m.index + run.length);
var nextCharReading = dict[nextCharObj] || nextCharObj;
if (nextCharObj === '實' || isDigeutOrJieutStarting(nextCharReading)) {
reading = '부';
}
}
// '金' 예외 처리: 한자 덩어리 내에서 첫 글자면(앞에 한자가 없으면) '김', 아니면 '금'
if (ch === '金' || ch === '金') {
reading = (i === 0) ? '김' : '금';
}
var finalReading = reading;
// 이전 글자(방금 변환된 한글이거나 한자 블록 앞의 일반 텍스트)를 추적
// 띄어쓰기가 있어도 직전 한글을 올바르게 찾도록 정규식 활용
var prevMatch = context.match(/([가-힣])\s*$/);
var prevHangul = convertedChars.length > 0
? convertedChars[convertedChars.length - 1]
: (prevMatch ? prevMatch[1] : context.slice(-1));
if (isAfterNum) {
if (ch === '兩') finalReading = '냥';
else if (ch === '年') finalReading = '년';
else finalReading = reading; // 일반적인 경우 두음법칙 무력화 (예: 3里 -> 3리)
} else if (parenHangul) {
// 괄호 바로 앞 한글 가이드와 부합하면 원음 반영 (예: 냥(兩) -> 냥, 냥쭝(兩쭝) -> 냥쭝)
if (ch === '兩' && parenHangul.startsWith('냥')) finalReading = '냥';
else if (ch === '兩' && parenHangul.startsWith('양')) finalReading = '양';
else if (ch === '年' && parenHangul.startsWith('년')) finalReading = '년';
else if (ch === '年' && parenHangul.startsWith('연')) finalReading = '연';
else finalReading = (i === 0) ? applyDueum(reading) : reading;
} else {
// 모음이나 ㄴ 받침 뒤에 이어지는 '렬, 률'은 '열, 율'로 발음
if ((reading === '렬' || reading === '률') && isVowelOrNieunEnding(prevHangul)) {
finalReading = (reading === '렬') ? '열' : '율';
} else if (ch === '理' && i === 0 && chars.length === 1 && isRieulEnding(prevHangul)) {
// '-을/ㄹ' 어미 뒤에 단독으로 쓰인 '理'는 의존 명사이므로 두음법칙 예외
finalReading = '리';
} else {
// 일반적인 한자 덩어리의 첫머리에만 두음법칙 적용
finalReading = (i === 0) ? applyDueum(reading) : reading;
}
}
convertedChars.push(finalReading);
i++;
}
}
var span = document.createElement('span');
span.textContent = convertedChars.join('');
span.dataset.original = run;
span.title = run; // 마우스 오버 시 원문 한자 확인
span.classList.add('hanja-converted');
frag.appendChild(span);
lastIndex = m.index + run.length;
}
if (lastIndex < text.length) {
frag.appendChild(document.createTextNode(text.slice(lastIndex)));
}
return frag;
}
// root를 화면(DOM)에서 잠시 떼어낸 뒤 fn(root)를 실행하고 다시 붙인다.
function withDetached(root, fn) {
var parent = root.parentNode;
var nextSibling = root.nextSibling;
var wasDetached = !parent;
if (!wasDetached) parent.removeChild(root);
try {
fn(root);
} finally {
if (!wasDetached) {
if (nextSibling) parent.insertBefore(root, nextSibling);
else parent.appendChild(root);
}
}
}
function convertNode(root) {
withDetached(root, function (root) {
applyManualOverrides(root); // 1) 틀로 지정된 부분 먼저 처리
// 2) 문서를 순서대로 한 번만 훑으며, 직전 글자를 흘려보낸다 (O(n))
var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
var lastText = "";
var toProcess = [];
var node;
while ((node = walker.nextNode())) {
var text = node.nodeValue;
if (!text) continue;
var insideConverted = node.parentNode && node.parentNode.closest &&
node.parentNode.closest('.hanja-converted');
if (!insideConverted && HAN_RE.test(text)) {
toProcess.push({ node: node, precedingText: lastText });
}
if (!insideConverted && text.length) {
lastText = (lastText + text).slice(-50); // 최근 50글자까지만 버퍼에 보존
}
}
toProcess.forEach(function (item) {
var frag = buildConvertedFragment(item.node.nodeValue, item.precedingText);
item.node.parentNode.replaceChild(frag, item.node);
});
});
}
function restore(root) {
withDetached(root, function (root) {
root.querySelectorAll('.hanja-converted').forEach(function (span) {
if (span.classList.contains('hanja-manual-reading')) {
span.textContent = span.dataset.original;
span.classList.remove('hanja-converted');
span.removeAttribute('title');
} else {
span.replaceWith(document.createTextNode(span.dataset.original));
}
});
});
}
mw.loader.using('mediawiki.util').then(function () {
// 변환된 한자에 옅은 점선 밑줄을 넣어, 원문과 구분되게 하되 가독성은 해치지 않도록 함.
mw.util.addCSS(
'.hanja-converted {' +
' border-bottom: 1px dotted rgba(128,128,128,0.6);' +
' cursor: help;' +
' text-decoration: none;' +
'}'
);
mw.util.addPortletLink(portlet, '#', '한자 독음', 'ca-hanja2hangul', buttontooltip);
$('#ca-hanja2hangul').on('click', function (e) {
e.preventDefault();
loadDict().then(function () {
var content = document.querySelector('#mw-content-text .mw-parser-output');
if (!content) return;
toggled = !toggled;
toggled ? convertNode(content) : restore(content);
});
});
});
});
dz4wu3n3dhhrr55lsh40n2ojjq6d2vt
User:Namoroka/sandbox/1
2
177074
754645
754561
2026-08-02T08:31:33Z
Namoroka
19627
754645
wikitext
text/x-wiki
* [[MediaWiki:Gadget-hanja-reading.js]]
** [[MediaWiki:Gadget-hanja-base2.json]]
** [[MediaWiki:Gadget-hanja-variants.json]]
** [[MediaWiki:Gadget-hanja-variants-cjkvi.json]]
** [[MediaWiki:Gadget-hanja-history.json]]
** [[MediaWiki:Gadget-hanja-overrides.json]]
** [[MediaWiki:Gadget-hanja-word.json]]
*량(輛), 리(理, 里, 厘, 釐)
*량(輛), 列車 한 輛
**차량(車輛)
**차량세(車輛稅)
**차량용품(車輛用品)
*不+ㄷ/ㅈ = 부, 나머지는 전부 불
**불가(不可), 불량(不良), 불합리(不合理)
**부당(不當), 절대부등식(絶對不等式), 부적절(不適切)
**예외: 부실(不實), 3불정책(三不政策), 독불장군(獨不將軍)
(어미 ‘-을’ 뒤에 ‘있다’, ‘없다’ 따위와 함께 쓰여) 1. ‘까닭’, ‘이치’의 뜻을 나타내는 말.
*그럴 理가 없다.
*그럴理가 없다.
*그럴理가없다.
*雲養 大監이나 나나 이미 허리 부러진 虎狼인데, 저들이 危險을 무릅쓰면서까지 도와줄 理 있겠소?
*外部에서 侵入한 痕跡이 없고 門은 잠겨져 있었으므로 나갔을 理 萬無다.
*閔箕의 性格으로 그 祕密을 그의 妻에게 告白하지 않았을 理 또한 없을 터였다.
*자네가 모르는 일을 낸들 알 理 있나?
*그러나 조만춘이가 逃亡兵인 그를 찾아 이런 後方에까지 내려올 理가 萬無하다.
*벌써 데려왔을 理는 없고 마침 제풀에 왔나 하고 가만히 앉았으려니 門이 활짝 열리며 경애가 딱 섰다.
*신여성(新女性)
*新女性(신여성)
*新女性
*女性
*女
*省略
* 金: 김/금
** 김해 김씨(金海金氏, 金海 金氏), 金海, 金氏
**개금(改金), 과금(課金), 과징금(課懲金), 금강(金剛), 금속(金屬), 비금속(非金屬), 금요일(金曜日), 비자금(秘資金), 장학금(奬學金), 황금(黃金), 금전(金錢), 입금(入金)
**김구(金九), 김대중(金大中), 김부겸(金富謙), 김종필(金鍾泌), 김무성(金武星), 김상곤(金相坤)
**가서만금(家書萬金), 견금여석(見金如石), 금과옥조(金科玉條), 금란지교(金蘭之交), 금석뇌약(金石牢約), 금자탑(金字塔), 금지옥엽(金枝玉葉), 단금지계교(斷金之契交),일확천금(一攫千金)
**금강산(金剛山), 금련산(金連山), 금오산(金烏山), 금정산(金井山), 몽금포(夢金浦), 새만금(새萬金)
* 반복부호
**正々堂々(정정당당)
**明々白々(명명백백)
**各々(각각), 云々(운운), 繼々承々(계계승승), 一々히(일일이), 一一히
**續々(속속)
**着々(착착)
**歷々히(역력히)
**默々히(묵묵히)
**細々한(세세한)
**赫々한(혁혁한)
**紛々할(분분할)
**紛〻할
**분々할
* 一二三四五六七八九十百千萬万億兆〇零
** 二〇二六年, 一九九九年, 二〇〇〇년대
** 六二〇〇円, 五〇〇원, 五〇〇원
** 〇二-一二三-四五六七
** 第一〇〇호, 三〇二호
** 二.〇
== 테스트 4 ==
*樂('''악''', 낙, 락, '''요''') → '''樂曲(악곡)''', 樂園(낙원), 娛樂(오락), '''樂山(요산)'''
*見(견, '''현''') → 見聞(견문), '''謁見(알현)'''
;제10항 첫음 '녀, 뇨, 뉴, 니' → '여, 요, 유, 이'
*여자(女子), 연세(年歲), 요소(尿素), 유대(紐帶), 이토(泥土), 익명(匿名), 여성(女性), 여아(女兒), 여선생(女先生), 여학생(女學生)
*예외 1: 냥(兩), 냥쭝('''兩쭝'''), 년(年) / '''十''' 年, 金 '''한 兩''', 銀 두 '''兩쭝''' / 年 降水量(연 강수량, 명사), '''十 年'''(십 년, 의존 명사), 生産 年度(생산 연도, 명사), '''2018 年度'''(2018 년도, 의존 명사), 2018年度(2018년도, 의존 명사)
*예외 2: 신여성('''新女性'''), 공염불('''空念佛'''), 남존여비('''男尊女卑''')
*예외 3: 한국여자대학('''韓國女子大學'''), 대한요소비료회사(大韓尿素肥料會社)
;제11항 첫음 '랴, 려, 례, 료, 류, 리' → '야, 여, 예, 요, 유, 이'
*양심(良心), 역사(歷史), 예의(禮義), 용궁(龍宮), 유행(流行), 이발(理髮)
*예외 1: 리(里): '''몇 理'''냐?, 리(理): '''그럴 理'''가 없다. / '''客車''' '''五十 輛'''(객차 오십 량), '''2分''' 5厘 7厘(2푼 5리 7리)
*예외 2: 나열('''羅列'''), 치열('''齒列'''), 비열('''卑劣'''), 규율('''規律'''), 비율('''比率'''), 실패율('''失敗率'''), 분열('''分裂'''), 선열('''先烈'''), 진열('''陳列'''), 선율('''旋律'''), 전율('''戰慄'''), 백분율('''百分率''')
*예외 3: 신립(申砬), 최린(崔麟), 채륜(蔡倫), 하륜('''河崙''')
*예외 4: 국제연합('''國際聯合''') → 국련(國聯), 한국시각장애인연합회('''韓國視覺障礙人聯合會''') → 한시련(韓視聯)
*예외 4: 역이용('''逆利用'''), 연이율('''年利率'''), 열역학('''熱力學'''), 해외여행('''海外旅行''')
*예외 5: 서울여관(서울旅館), 신흥이발관('''新興理髮館'''), 육천육백육십육('''六千六百六十六''')
;제12항 첫음 '라, 래, 로, 뢰, 루, 르' → '나, 내, 노, 뇌, 누, 느'
*낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓)
*예외 1: 낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓)
*예외 2: 내내월('''來來月'''), 상노인('''上老人'''), 중노동('''重勞動'''), 비논리적('''非論理的''')
;제13항 한 단어 안에서 같은 음절이나 비슷한 음절이 겹쳐 나는 부분
*연연불망('''戀戀不忘'''), 유유상종('''類類相從'''), 누누이('''屢屢이''')
*예외: 열렬히('''熱熱히'''), 늠름히('''凜凜히'''), 연년세세(年年歲歲), 낙락장송(落落長松), 냉랭하다(冷冷하다), 역력히(歷歷히), 염념불망(念念不忘)
* https://db.history.go.kr/unicode/
* https://kostma.aks.ac.kr/segment/segmentList.aspx
* https://www.heritage.go.kr/heri/mem/selectHanjUmka.do
* https://www.hanja.ne.kr/jupsu/jupsu07_01.asp
* https://oriental-dic.dankook.ac.kr/index
* http://www.e-hanja.kr/
* https://hc.jsecs.org/irg/ws2021/app/
* https://db.cyberseodang.or.kr/twochar/index.html#
== + ==
갈곶리(乫串里)
법곳동(法串洞)
대곶면(大串面)
월곶면(月串面)
보구곶(甫口串)
월곶동(月串洞)
장곳리(獐串里)
홍곳리(洪串里)
삼곶리(三串里)
갈곶동(葛串洞)
지곶동(紙串洞)
갑곶리(甲串里)
월곳리(月串里)
석곶리(石串里)
호미곶(虎尾串)
흥환리(興串里)
사곶리(仕串里)
간절곶(艮絶串)
대산곶(大山串)
모월곶(毛月串)
호미곶(虎尾串)
장기곶(艮絶串)
비파곶(比巴串)
송도곶(松島串)
장산곶(長山串)
등산곶(登山串)
전곶(箭串)
공단곶(功端串)
동외곶(冬外串)
장기곶(長鬐串)
장산곶(長山串)
갑곶(甲串)
본곶(本곶)
모래곶(모래串)
활음조 현상
거란(契丹)
동란국(東丹國)
모란(牧丹)
<pre>
"開寧民亂": "개령민란",
"敦寧": "돈령",
"靡寧": "미령",
"玉度靡寧": "옥도미령",
"會寧": "회령",
"武寧": "무령",
"孝寧": "효령",
"遼寧": "요령",
"居寧": "거령",
"巨寧": "거령",
"濟寧里": "제령리",
"宜寧": "의령",
"開寧面": "개령면",
"河寧里": "하령리",
"載寧": "재령",
"會寧里": "회령리",
"保寧": "보령",
"富寧": "부령",
"泰寧": "태령",
"古寧": "고령",
"鐵犂": "철려",
"鋤犁": "서려",
"踏犂": "답려",
"單牛犂": "단우려",
"兩牛犂": "양우려",
"蟉松": "규송",
"瘻癘": "누라",
"縶縲": "칩류",
"縲紲": "유설",
"鶆鳩": "내구",
"水剌": "수라",
"纍纍": "누누",
惹鬧 야료
起鬧 기뇨
熱鬧 열뇨
鬧擾 요요
息鬧 식뇨
息鬧 식뇨
濟州民鬧 제주민요
作鬧 작뇨
乖鬧 괴뇨
紛鬧 분뇨
喧鬧 훤뇨
煩鬧 번뇨
惹起鬧端-- 야기요단
</pre>
== Copyright ==
The Unicode database is released by Unicode Inc. under the following terms:
<blockquote>
Copyright © 1991-2022 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either
(a) this copyright and permission notice appear with all copies of the Data Files or Software, or
(b) this copyright and permission notice appear in associated Documentation.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.
</blockquote>
hon2pntwgki8tbbme8vpc87zvj910yg
754646
754645
2026-08-02T08:33:06Z
Namoroka
19627
754646
wikitext
text/x-wiki
* [[MediaWiki:Gadget-hanja-reading.js]]
** [[MediaWiki:Gadget-hanja-base2.json]]
** [[MediaWiki:Gadget-hanja-variants.json]]
** [[MediaWiki:Gadget-hanja-variants-cjkvi.json]]
** [[MediaWiki:Gadget-hanja-history.json]]
** [[MediaWiki:Gadget-hanja-overrides.json]]
** [[MediaWiki:Gadget-hanja-word.json]]
*량(輛), 리(理, 里, 厘, 釐)
*량(輛), 列車 한 輛
**차량(車輛)
**차량세(車輛稅)
**차량용품(車輛用品)
*不+ㄷ/ㅈ = 부, 나머지는 전부 불
**불가(不可), 불량(不良), 불합리(不合理)
**부당(不當), 절대부등식(絶對不等式), 부적절(不適切)
**예외: 부실(不實), 3불정책(三不政策), 독불장군(獨不將軍)
(어미 ‘-을’ 뒤에 ‘있다’, ‘없다’ 따위와 함께 쓰여) 1. ‘까닭’, ‘이치’의 뜻을 나타내는 말.
*그럴 理가 없다.
*그럴理가 없다.
*그럴理가없다.
*雲養 大監이나 나나 이미 허리 부러진 虎狼인데, 저들이 危險을 무릅쓰면서까지 도와줄 理 있겠소?
*外部에서 侵入한 痕跡이 없고 門은 잠겨져 있었으므로 나갔을 理 萬無다.
*閔箕의 性格으로 그 祕密을 그의 妻에게 告白하지 않았을 理 또한 없을 터였다.
*자네가 모르는 일을 낸들 알 理 있나?
*그러나 조만춘이가 逃亡兵인 그를 찾아 이런 後方에까지 내려올 理가 萬無하다.
*벌써 데려왔을 理는 없고 마침 제풀에 왔나 하고 가만히 앉았으려니 門이 활짝 열리며 경애가 딱 섰다.
*신여성(新女性)
*新女性(신여성)
*新女性
*女性
*女
*省略
* 金: 김/금
** 김해 김씨(金海金氏, 金海 金氏), 金海, 金氏
**개금(改金), 과금(課金), 과징금(課懲金), 금강(金剛), 금속(金屬), 비금속(非金屬), 금요일(金曜日), 비자금(秘資金), 장학금(奬學金), 황금(黃金), 금전(金錢), 입금(入金)
**김구(金九), 김대중(金大中), 김부겸(金富謙), 김종필(金鍾泌), 김무성(金武星), 김상곤(金相坤)
**가서만금(家書萬金), 견금여석(見金如石), 금과옥조(金科玉條), 금란지교(金蘭之交), 금석뇌약(金石牢約), 금자탑(金字塔), 금지옥엽(金枝玉葉), 단금지계교(斷金之契交),일확천금(一攫千金)
**금강산(金剛山), 금련산(金連山), 금오산(金烏山), 금정산(金井山), 몽금포(夢金浦), 새만금(새萬金)
* 반복부호
**正々堂々(정정당당)
**明々白々(명명백백)
**各々(각각), 云々(운운), 繼々承々(계계승승), 一々이(일일이), 一一이
**續々(속속)
**着々(착착)
**歷々히(역력히)
**默々히(묵묵히)
**細々한(세세한)
**赫々한(혁혁한)
**紛々할(분분할)
**紛〻할
**분々할
* 一二三四五六七八九十百千萬万億兆〇零
** 二〇二六年, 一九九九年, 二〇〇〇년대
** 六二〇〇円, 五〇〇원, 五〇〇원
** 〇二-一二三-四五六七
** 第一〇〇호, 三〇二호
** 二.〇
== 테스트 4 ==
*樂('''악''', 낙, 락, '''요''') → '''樂曲(악곡)''', 樂園(낙원), 娛樂(오락), '''樂山(요산)'''
*見(견, '''현''') → 見聞(견문), '''謁見(알현)'''
;제10항 첫음 '녀, 뇨, 뉴, 니' → '여, 요, 유, 이'
*여자(女子), 연세(年歲), 요소(尿素), 유대(紐帶), 이토(泥土), 익명(匿名), 여성(女性), 여아(女兒), 여선생(女先生), 여학생(女學生)
*예외 1: 냥(兩), 냥쭝('''兩쭝'''), 년(年) / '''十''' 年, 金 '''한 兩''', 銀 두 '''兩쭝''' / 年 降水量(연 강수량, 명사), '''十 年'''(십 년, 의존 명사), 生産 年度(생산 연도, 명사), '''2018 年度'''(2018 년도, 의존 명사), 2018年度(2018년도, 의존 명사)
*예외 2: 신여성('''新女性'''), 공염불('''空念佛'''), 남존여비('''男尊女卑''')
*예외 3: 한국여자대학('''韓國女子大學'''), 대한요소비료회사(大韓尿素肥料會社)
;제11항 첫음 '랴, 려, 례, 료, 류, 리' → '야, 여, 예, 요, 유, 이'
*양심(良心), 역사(歷史), 예의(禮義), 용궁(龍宮), 유행(流行), 이발(理髮)
*예외 1: 리(里): '''몇 理'''냐?, 리(理): '''그럴 理'''가 없다. / '''客車''' '''五十 輛'''(객차 오십 량), '''2分''' 5厘 7厘(2푼 5리 7리)
*예외 2: 나열('''羅列'''), 치열('''齒列'''), 비열('''卑劣'''), 규율('''規律'''), 비율('''比率'''), 실패율('''失敗率'''), 분열('''分裂'''), 선열('''先烈'''), 진열('''陳列'''), 선율('''旋律'''), 전율('''戰慄'''), 백분율('''百分率''')
*예외 3: 신립(申砬), 최린(崔麟), 채륜(蔡倫), 하륜('''河崙''')
*예외 4: 국제연합('''國際聯合''') → 국련(國聯), 한국시각장애인연합회('''韓國視覺障礙人聯合會''') → 한시련(韓視聯)
*예외 4: 역이용('''逆利用'''), 연이율('''年利率'''), 열역학('''熱力學'''), 해외여행('''海外旅行''')
*예외 5: 서울여관(서울旅館), 신흥이발관('''新興理髮館'''), 육천육백육십육('''六千六百六十六''')
;제12항 첫음 '라, 래, 로, 뢰, 루, 르' → '나, 내, 노, 뇌, 누, 느'
*낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓)
*예외 1: 낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓)
*예외 2: 내내월('''來來月'''), 상노인('''上老人'''), 중노동('''重勞動'''), 비논리적('''非論理的''')
;제13항 한 단어 안에서 같은 음절이나 비슷한 음절이 겹쳐 나는 부분
*연연불망('''戀戀不忘'''), 유유상종('''類類相從'''), 누누이('''屢屢이''')
*예외: 열렬히('''熱熱히'''), 늠름히('''凜凜히'''), 연년세세(年年歲歲), 낙락장송(落落長松), 냉랭하다(冷冷하다), 역력히(歷歷히), 염념불망(念念不忘)
* https://db.history.go.kr/unicode/
* https://kostma.aks.ac.kr/segment/segmentList.aspx
* https://www.heritage.go.kr/heri/mem/selectHanjUmka.do
* https://www.hanja.ne.kr/jupsu/jupsu07_01.asp
* https://oriental-dic.dankook.ac.kr/index
* http://www.e-hanja.kr/
* https://hc.jsecs.org/irg/ws2021/app/
* https://db.cyberseodang.or.kr/twochar/index.html#
== + ==
갈곶리(乫串里)
법곳동(法串洞)
대곶면(大串面)
월곶면(月串面)
보구곶(甫口串)
월곶동(月串洞)
장곳리(獐串里)
홍곳리(洪串里)
삼곶리(三串里)
갈곶동(葛串洞)
지곶동(紙串洞)
갑곶리(甲串里)
월곳리(月串里)
석곶리(石串里)
호미곶(虎尾串)
흥환리(興串里)
사곶리(仕串里)
간절곶(艮絶串)
대산곶(大山串)
모월곶(毛月串)
호미곶(虎尾串)
장기곶(艮絶串)
비파곶(比巴串)
송도곶(松島串)
장산곶(長山串)
등산곶(登山串)
전곶(箭串)
공단곶(功端串)
동외곶(冬外串)
장기곶(長鬐串)
장산곶(長山串)
갑곶(甲串)
본곶(本곶)
모래곶(모래串)
활음조 현상
거란(契丹)
동란국(東丹國)
모란(牧丹)
<pre>
"開寧民亂": "개령민란",
"敦寧": "돈령",
"靡寧": "미령",
"玉度靡寧": "옥도미령",
"會寧": "회령",
"武寧": "무령",
"孝寧": "효령",
"遼寧": "요령",
"居寧": "거령",
"巨寧": "거령",
"濟寧里": "제령리",
"宜寧": "의령",
"開寧面": "개령면",
"河寧里": "하령리",
"載寧": "재령",
"會寧里": "회령리",
"保寧": "보령",
"富寧": "부령",
"泰寧": "태령",
"古寧": "고령",
"鐵犂": "철려",
"鋤犁": "서려",
"踏犂": "답려",
"單牛犂": "단우려",
"兩牛犂": "양우려",
"蟉松": "규송",
"瘻癘": "누라",
"縶縲": "칩류",
"縲紲": "유설",
"鶆鳩": "내구",
"水剌": "수라",
"纍纍": "누누",
惹鬧 야료
起鬧 기뇨
熱鬧 열뇨
鬧擾 요요
息鬧 식뇨
息鬧 식뇨
濟州民鬧 제주민요
作鬧 작뇨
乖鬧 괴뇨
紛鬧 분뇨
喧鬧 훤뇨
煩鬧 번뇨
惹起鬧端-- 야기요단
</pre>
== Copyright ==
The Unicode database is released by Unicode Inc. under the following terms:
<blockquote>
Copyright © 1991-2022 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either
(a) this copyright and permission notice appear with all copies of the Data Files or Software, or
(b) this copyright and permission notice appear in associated Documentation.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.
</blockquote>
ovhl9ucvei80uauvnfov84j3c628ebt
754650
754646
2026-08-02T08:59:29Z
Namoroka
19627
754650
wikitext
text/x-wiki
* [[MediaWiki:Gadget-hanja-reading.js]]
** [[MediaWiki:Gadget-hanja-base2.json]]
** [[MediaWiki:Gadget-hanja-variants.json]]
** [[MediaWiki:Gadget-hanja-variants-cjkvi.json]]
** [[MediaWiki:Gadget-hanja-history.json]]
** [[MediaWiki:Gadget-hanja-overrides.json]]
** [[MediaWiki:Gadget-hanja-word.json]]
*량(輛), 리(理, 里, 厘, 釐)
*량(輛), 列車 한 輛
**차량(車輛)
**차량세(車輛稅)
**차량용품(車輛用品)
*不+ㄷ/ㅈ = 부, 나머지는 전부 불
**불가(不可), 불량(不良), 불합리(不合理)
**부당(不當), 절대부등식(絶對不等式), 부적절(不適切)
**예외: 부실(不實), 3불정책(三不政策), 독불장군(獨不將軍)
불가(不可)
불가결(不可缺)
불가능(不可能)
불가침조약(不可侵條約)
불가피(不可避)
불과(不過)
불구(不拘)
불구속(不拘束)
불규칙(不規則)
불균형(不均衡)
불길(不吉)
불능(不能)
불량(不良)
불량배(不良輩)
불량식품(不良食品)
불로초(不老草)
불리(不利)
불륜(不倫)
불만(不滿)
불만족(不滿足)
불면증(不眠症)
불멸(不滅)
불명예(不名譽)
불모지(不毛地)
불문(不問)
불법(不法)
불법적(不法的)
불법행위(不法行爲)
불변(不變)
불복(不服)
불복종(不服從)
불사(不辭/不死)
불사신(不死身)
불사조(不死鳥)
불상사(不祥事)
불성실(不誠實)
불순(不純/不順)
불시(不時)
불신(不信)
불안(不安)
불여귀(不如歸)
불연(不燃)
불연성(不燃性)
불연속(不連續)
불완전(不完全)
불우(不遇)
불운(不運)
불응(不應)
퇴거불응죄(退去不應罪)
불의(不義)
불이익(不利益)
불이행(不履行)
제차신호조작불이행(諸車信號操作不履行)
지시불이행(指示不履行)
불임(不妊)
불참(不參)
불청객(不請客)
불체포특권(不逮捕特權)
불초(不肖)
불쾌(不快)
불쾌감(不快感)
불투명(不透明)
불편(不便)
불평(不平)
불평등(不平等)
불필요(不必要)
불합격(不合格)
불합리(不合理)
불행(不幸)
불허(不許)
불확실(不確實)
불확실성(不確實性)
불황(不況)
불효(不孝)
불후(不朽)
부당(不當)
부도(不渡)
부도덕(不道德)
부동산(不動産)
부득이(不得已)
부등식(不等式)
절대부등식(絶對不等式)
부실(不實)
부작위(不作爲)
부재(不在)
부적절(不適切)
부정(不定/不正/不淨)
부정행위(不正行爲)
부조리(不條理)
부족(不足)
과부족(過不足)
부주의(不注意)
삼부점(三不粘)
가치부전(假痴不癲)
과유불급(過猶不及)
권불십년(權不十年)
독불장군(獨不將軍)
두문불출(杜門不出)
목불인견(目不忍見)[7]
목불식정(目不識丁)
복지부동(伏地不動)
불가항력(不可抗力)
불교이주(不敎而誅)
불구대천(不俱戴天)
오매불망(寤寐不忘)
천부당만부당(千不當萬不當)
표리부동(表裏不同)
부동방면(不動坊面)
불로동(不老洞)
불로봉무동(不老鳳舞洞)
가부(可否)
가부간(可否間)
가타부타(可타否타)
거부(拒否)
낙부(諾否)
부결(否決)
부인(否認)
부정(否定)
부정적(否定的)
안부(安否)
여부(與否)
비색(否塞)
비운(否運)
왈가왈부(曰可曰否)
(어미 ‘-을’ 뒤에 ‘있다’, ‘없다’ 따위와 함께 쓰여) 1. ‘까닭’, ‘이치’의 뜻을 나타내는 말.
*그럴 理가 없다.
*그럴理가 없다.
*그럴理가없다.
*雲養 大監이나 나나 이미 허리 부러진 虎狼인데, 저들이 危險을 무릅쓰면서까지 도와줄 理 있겠소?
*外部에서 侵入한 痕跡이 없고 門은 잠겨져 있었으므로 나갔을 理 萬無다.
*閔箕의 性格으로 그 祕密을 그의 妻에게 告白하지 않았을 理 또한 없을 터였다.
*자네가 모르는 일을 낸들 알 理 있나?
*그러나 조만춘이가 逃亡兵인 그를 찾아 이런 後方에까지 내려올 理가 萬無하다.
*벌써 데려왔을 理는 없고 마침 제풀에 왔나 하고 가만히 앉았으려니 門이 활짝 열리며 경애가 딱 섰다.
*신여성(新女性)
*新女性(신여성)
*新女性
*女性
*女
*省略
* 金: 김/금
** 김해 김씨(金海金氏, 金海 金氏), 金海, 金氏
**개금(改金), 과금(課金), 과징금(課懲金), 금강(金剛), 금속(金屬), 비금속(非金屬), 금요일(金曜日), 비자금(秘資金), 장학금(奬學金), 황금(黃金), 금전(金錢), 입금(入金)
**김구(金九), 김대중(金大中), 김부겸(金富謙), 김종필(金鍾泌), 김무성(金武星), 김상곤(金相坤)
**가서만금(家書萬金), 견금여석(見金如石), 금과옥조(金科玉條), 금란지교(金蘭之交), 금석뇌약(金石牢約), 금자탑(金字塔), 금지옥엽(金枝玉葉), 단금지계교(斷金之契交),일확천금(一攫千金)
**금강산(金剛山), 금련산(金連山), 금오산(金烏山), 금정산(金井山), 몽금포(夢金浦), 새만금(새萬金)
* 반복부호
**正々堂々(정정당당)
**明々白々(명명백백)
**各々(각각), 云々(운운), 繼々承々(계계승승), 一々이(일일이), 一一이
**續々(속속)
**着々(착착)
**歷々히(역력히)
**默々히(묵묵히)
**細々한(세세한)
**赫々한(혁혁한)
**紛々할(분분할)
**紛〻할
**분々할
* 一二三四五六七八九十百千萬万億兆〇零
** 二〇二六年, 一九九九年, 二〇〇〇년대
** 六二〇〇円, 五〇〇원, 五〇〇원
** 〇二-一二三-四五六七
** 第一〇〇호, 三〇二호
** 二.〇
== 테스트 4 ==
*樂('''악''', 낙, 락, '''요''') → '''樂曲(악곡)''', 樂園(낙원), 娛樂(오락), '''樂山(요산)'''
*見(견, '''현''') → 見聞(견문), '''謁見(알현)'''
;제10항 첫음 '녀, 뇨, 뉴, 니' → '여, 요, 유, 이'
*여자(女子), 연세(年歲), 요소(尿素), 유대(紐帶), 이토(泥土), 익명(匿名), 여성(女性), 여아(女兒), 여선생(女先生), 여학생(女學生)
*예외 1: 냥(兩), 냥쭝('''兩쭝'''), 년(年) / '''十''' 年, 金 '''한 兩''', 銀 두 '''兩쭝''' / 年 降水量(연 강수량, 명사), '''十 年'''(십 년, 의존 명사), 生産 年度(생산 연도, 명사), '''2018 年度'''(2018 년도, 의존 명사), 2018年度(2018년도, 의존 명사)
*예외 2: 신여성('''新女性'''), 공염불('''空念佛'''), 남존여비('''男尊女卑''')
*예외 3: 한국여자대학('''韓國女子大學'''), 대한요소비료회사(大韓尿素肥料會社)
;제11항 첫음 '랴, 려, 례, 료, 류, 리' → '야, 여, 예, 요, 유, 이'
*양심(良心), 역사(歷史), 예의(禮義), 용궁(龍宮), 유행(流行), 이발(理髮)
*예외 1: 리(里): '''몇 理'''냐?, 리(理): '''그럴 理'''가 없다. / '''客車''' '''五十 輛'''(객차 오십 량), '''2分''' 5厘 7厘(2푼 5리 7리)
*예외 2: 나열('''羅列'''), 치열('''齒列'''), 비열('''卑劣'''), 규율('''規律'''), 비율('''比率'''), 실패율('''失敗率'''), 분열('''分裂'''), 선열('''先烈'''), 진열('''陳列'''), 선율('''旋律'''), 전율('''戰慄'''), 백분율('''百分率''')
*예외 3: 신립(申砬), 최린(崔麟), 채륜(蔡倫), 하륜('''河崙''')
*예외 4: 국제연합('''國際聯合''') → 국련(國聯), 한국시각장애인연합회('''韓國視覺障礙人聯合會''') → 한시련(韓視聯)
*예외 4: 역이용('''逆利用'''), 연이율('''年利率'''), 열역학('''熱力學'''), 해외여행('''海外旅行''')
*예외 5: 서울여관(서울旅館), 신흥이발관('''新興理髮館'''), 육천육백육십육('''六千六百六十六''')
;제12항 첫음 '라, 래, 로, 뢰, 루, 르' → '나, 내, 노, 뇌, 누, 느'
*낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓)
*예외 1: 낙원(樂園), 내일(來日), 노인(老人), 뇌성(雷聲), 누각(樓閣), 능묘(陵墓)
*예외 2: 내내월('''來來月'''), 상노인('''上老人'''), 중노동('''重勞動'''), 비논리적('''非論理的''')
;제13항 한 단어 안에서 같은 음절이나 비슷한 음절이 겹쳐 나는 부분
*연연불망('''戀戀不忘'''), 유유상종('''類類相從'''), 누누이('''屢屢이''')
*예외: 열렬히('''熱熱히'''), 늠름히('''凜凜히'''), 연년세세(年年歲歲), 낙락장송(落落長松), 냉랭하다(冷冷하다), 역력히(歷歷히), 염념불망(念念不忘)
* https://db.history.go.kr/unicode/
* https://kostma.aks.ac.kr/segment/segmentList.aspx
* https://www.heritage.go.kr/heri/mem/selectHanjUmka.do
* https://www.hanja.ne.kr/jupsu/jupsu07_01.asp
* https://oriental-dic.dankook.ac.kr/index
* http://www.e-hanja.kr/
* https://hc.jsecs.org/irg/ws2021/app/
* https://db.cyberseodang.or.kr/twochar/index.html#
== + ==
갈곶리(乫串里)
법곳동(法串洞)
대곶면(大串面)
월곶면(月串面)
보구곶(甫口串)
월곶동(月串洞)
장곳리(獐串里)
홍곳리(洪串里)
삼곶리(三串里)
갈곶동(葛串洞)
지곶동(紙串洞)
갑곶리(甲串里)
월곳리(月串里)
석곶리(石串里)
호미곶(虎尾串)
흥환리(興串里)
사곶리(仕串里)
간절곶(艮絶串)
대산곶(大山串)
모월곶(毛月串)
호미곶(虎尾串)
장기곶(艮絶串)
비파곶(比巴串)
송도곶(松島串)
장산곶(長山串)
등산곶(登山串)
전곶(箭串)
공단곶(功端串)
동외곶(冬外串)
장기곶(長鬐串)
장산곶(長山串)
갑곶(甲串)
본곶(本곶)
모래곶(모래串)
활음조 현상
거란(契丹)
동란국(東丹國)
모란(牧丹)
<pre>
"開寧民亂": "개령민란",
"敦寧": "돈령",
"靡寧": "미령",
"玉度靡寧": "옥도미령",
"會寧": "회령",
"武寧": "무령",
"孝寧": "효령",
"遼寧": "요령",
"居寧": "거령",
"巨寧": "거령",
"濟寧里": "제령리",
"宜寧": "의령",
"開寧面": "개령면",
"河寧里": "하령리",
"載寧": "재령",
"會寧里": "회령리",
"保寧": "보령",
"富寧": "부령",
"泰寧": "태령",
"古寧": "고령",
"鐵犂": "철려",
"鋤犁": "서려",
"踏犂": "답려",
"單牛犂": "단우려",
"兩牛犂": "양우려",
"蟉松": "규송",
"瘻癘": "누라",
"縶縲": "칩류",
"縲紲": "유설",
"鶆鳩": "내구",
"水剌": "수라",
"纍纍": "누누",
惹鬧 야료
起鬧 기뇨
熱鬧 열뇨
鬧擾 요요
息鬧 식뇨
息鬧 식뇨
濟州民鬧 제주민요
作鬧 작뇨
乖鬧 괴뇨
紛鬧 분뇨
喧鬧 훤뇨
煩鬧 번뇨
惹起鬧端-- 야기요단
</pre>
== Copyright ==
The Unicode database is released by Unicode Inc. under the following terms:
<blockquote>
Copyright © 1991-2022 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that either
(a) this copyright and permission notice appear with all copies of the Data Files or Software, or
(b) this copyright and permission notice appear in associated Documentation.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.
</blockquote>
cu2h0ocx1g4urv9aquxps5fp59s39lf
User:Enbi/Fortress/config.yaml.js
2
177456
754570
754527
2026-08-01T20:02:27Z
Enbi
72574
754570
javascript
text/javascript
testwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}} (test summary)"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
lhtdf0bscjetlp6hz7hr4kcxqfjt0jq
754580
754570
2026-08-01T20:07:10Z
Enbi
72574
754580
javascript
text/javascript
testwiki:
warnSummary: "Test Summary"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
7diare3pixfllp9xyniszkyqfkklz5l
754597
754580
2026-08-01T20:17:44Z
Enbi
72574
754597
javascript
text/javascript
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
0pyki2xsedgqf4nujuno2qspirkow0u
Stripped & Justified
0
177484
754564
754536
2026-08-01T16:08:44Z
Jaheim2021
75033
754564
wikitext
text/x-wiki
{{Use mdy dates|date=December 2022}}
{{Infobox album
| name = Stripped & Justified
| type = studio
| artist = [[Thicke Levine Timberlake]]
| cover =
| alt =
| released = {{Start date|2022|11|11}}
| genre = {{hlist|[[Pop-rap]]|[[dance-pop]]|[[nu-disco]]|[[electropop]]|[[synth-pop]]}}
| studio =
| length =
| recorded = 2021–2022
| label = {{hlist|[[I Am Other]]|[[222 Records|222]]|[[Interscope Records|Interscope]]}}
| producer = {{hlist|Ammo|[[Anderson .Paak]]|[[Ash Howes]]|[[Calvin Harris]]|[[Charlie Puth]]|Duck Blackwell|[[James Ford (musician)|James Ford]]|[[Justin Timberlake]]|Kiris Houston|Linslee Campbell|[[Ludwig Göransson]]|[[Madonna]]|[[Mattman & Robin]]||Nico Stadi|PhD|[[Biffco|Richard "Biff" Stannard]]|Sky Adams|[[Teemu Brunila]]}}
| prev_title = [[JT Session]]
| prev_year = 2020
| next_title =
| next_year =
| misc = {{Singles
| name = Stripped & Justified
| type = studio
| single1 = [[Miss a Thing (song)|Miss a Thing]]
| single1date = June 17, 2022
| single2 = [[A Second to Midnight (song)|A Second to Midnight]]
| single2date = October 28, 2022
| single3 = Can't Stop Writing Songs About You
| single3date = November 14, 2022
| single4 = Cake by the Ocean
| single4date = March 10, 2023
| single5 = Supernova
| single5date = July 21, 2023
}}
}}
'''''Stripped & Justified''''' is the tenth studio album by American [[Pop-R&B]] group [[Thicke Levine Timberlake]]. It was released on November 11, 2022, via [[I Am Other|I Am Other Entertainment]], [[222 Records]] and [[Interscope Records]]. It features [[guest appearance]]s from [[Halsey (singer)|Halsey]], [[Charlie Puth]], [[Jonas Brothers]], [[Calvin Harris]], [[Anderson .Paak]], [[Meghan Trainor]], [[The Lonely Island]], [[Christina Aguilera]], [[Pharrell Williams|Pharrell]] and [[Kylie Minogue]].
It peaked at number 13 on the [[Top Dance/Electronic Albums]] chart in the United States. It reached number 44 in Italy and number 89 in France.
== Background and release ==
After the release of the group's previous album, ''[[JT Session]]'' (2020), the band released a number of new singles.
In early November 2022, the group announced their new album entitled ''Stripped & Justified'' on Instagram. Like their previous album, ''Stripped & Justified'' contains fifteen songs.
==Track listing==
==Personnel==
==Charts==
===Weekly charts===
===Year-end charts===
==Certifications==
==References==
{{Reflist}}
{{Thicke Levine Timberlake}}
{{Authority control}}
[[Category:2022 albums]]
[[Category:Thicke Levine Timberlake albums]]
[[Category:I Am Other Entertainment albums]]
[[Category:222 Records albums]]
[[Category:Interscope Records albums]]
[[Category:Albums produced by Calvin Harris]]
[[Category:Albums produced by Justin Timberlake]]
4qnptogojhitwzw1648j24gl33e07sm
The Preacher's Man
0
177493
754563
754547
2026-08-01T16:06:06Z
Jaheim2021
75033
754563
wikitext
text/x-wiki
{{Use mdy dates|date=May 2025}}
{{Infobox album
| name = The Preacher's Man
| type = studio
| artist = [[Chris Martin]] and [[Bono]]
| cover =
| alt =
| released = 4 November 2003
| recorded = 2002–03
| studio =
| genre = {{hlist|[[Synth-rap]]|[[synth-pop]]|[[electropop]]}}
| length =
| label = [[Island Records|Island]]
| producer = {{hlist|[[Rik Simpson]]|[[Chris Martin]]|[[Linda Perry]]|[[George Michael]]|[[Daft Punk]]|[[Bono]]|[[Joakim Åhlund]]|[[Rob Dougan]]|[[Rick Nowels]]|[[The Edge]]}}
| prev_title =
| prev_year =
| next_title =
| next_year =
| misc = {{Extra chronology
| artist = [[Chris Martin]]
| type = studio
| prev_title = [[Welcome to the Carnival]]
| prev_year = 2002
| title = The Preacher's Man
| year = 2003
| next_title = [[Welcome to London: Creole 101]]
| next_year = 2004
}}
{{Singles
| name = The Preacher's Man
| type = studio
| single1 = [[I Wanna Be Bad (song)|I Wanna Be Bad]]
| single1date = 30 September 2003
| single2 = Shape
| single2date = 17 November 2003
| single3 = Rise & Fall
| single3date = 18 March 2004
}}
}}
'''''The Preacher's Man''''' is a collaborative album by English singer [[Chris Martin]] and Irish singer [[Bono]], released on 4 November 2003. The album, which was co-produced by Chris Martin, [[Rik Simpson]], Bono and long-time collaborator [[The Edge]], combines elements of [[Synth-rap]], [[synth-pop]] and [[electropop]]. It uses a number of samples, including the [[A&M Records|A&M]]-inspired "Shape", which samples "[[Shape of My Heart (Sting song)|Shape of My Heart]]". The album contains guest appearances by [[Steven Tyler]], [[Annie Lennox]], [[Mis-Teeq]] and [[Kid Rock]], as well as a vocals feature by [[George Michael]] on the song "City Ain't Big Enough".
== Track listing ==
==Charts==
== References ==
{{reflist}}
{{Chris Martin}}
{{Bono}}
{{Authority control}}
{{DEFAULTSORT:Preacher's Man, The}}
[[Category:2003 collaborative albums]]
[[Category:Albums produced by Chris Martin]]
[[Category:Albums produced by Rik Simpson]]
[[Category:Chris Martin albums]]
[[Category:Bono albums]]
[[Category:Island Records albums]]
[[Category:Albums produced by Bono]]
[[Category:Albums produced by the Edge]]
rw3m35pemdavxa7k35nbp6zuun7h7ba
Basura
0
177498
754565
2026-08-01T16:24:23Z
PCendrer
75068
Created page with "Aqui van insultos duros"
754565
wikitext
text/x-wiki
Aqui van insultos duros
an6zcyclciw0a9yqku5vxavbrrmb3ci
User:Enbi/fortress.yaml
2
177499
754610
2026-08-01T21:19:50Z
Enbi
72574
Created page with "Fortress config file. <syntaxhighlight><!----></syntaxhighlight>"
754610
wikitext
text/x-wiki
Fortress config file.
<syntaxhighlight><!----></syntaxhighlight>
jdmizdpbskyszb95qt06nz71qjnnyus
754611
754610
2026-08-01T21:21:41Z
Enbi
72574
754611
wikitext
text/x-wiki
Fortress config file.
<!--START-OF-FILE--><syntaxhighlight lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
1scrzteiif42bhkgge2xdibr5cn8tcy
754612
754611
2026-08-01T21:22:58Z
Enbi
72574
754612
wikitext
text/x-wiki
Fortress config file.
<syntaxhighlight lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
fyrhqg1apftitwinl7iv0gwk6aa5fif
754613
754612
2026-08-01T22:03:09Z
Enbi
72574
754613
wikitext
text/x-wiki
Fortress config file.
<syntaxhighht lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
gbonxlj75wl6ednjhj9icaqs1f3bm02
754614
754613
2026-08-01T22:09:19Z
Enbi
72574
754614
wikitext
text/x-wiki
Fortress config file.
<syntaxhighlight lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
fyrhqg1apftitwinl7iv0gwk6aa5fif
754615
754614
2026-08-01T22:09:41Z
Enbi
72574
754615
wikitext
text/x-wiki
Fortress config file.
<syntaxhighliht lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
4shcurb2pg5vl85koxepl0ci6fupr2n
754616
754615
2026-08-01T22:13:52Z
Enbi
72574
754616
wikitext
text/x-wiki
Fortress config file.
<syntaxhighlight lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
fyrhqg1apftitwinl7iv0gwk6aa5fif
754617
754616
2026-08-01T22:16:03Z
Enbi
72574
754617
wikitext
text/x-wiki
Fortress config file.
<syntaxhighlight lang="yaml">
invalid yaml!!!!!!!!!!"""""""?:?:?:?:?
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
d7pkijqexg7knjf20f1ivv33na34yqv
754619
754617
2026-08-01T22:20:12Z
Enbi
72574
754619
wikitext
text/x-wiki
Fortress config file.
<syntaxhighlight lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: "Warning user: {{[[Template:$1|$1]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
fyrhqg1apftitwinl7iv0gwk6aa5fif
754624
754619
2026-08-01T22:32:39Z
Enbi
72574
754624
wikitext
text/x-wiki
Fortress config file.
<syntaxhighlight lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
0gzzh80mxtcznlt259kvw34z5o1v85c
754625
754624
2026-08-01T22:33:07Z
Enbi
72574
754625
wikitext
text/x-wiki
Fortress config file.
<syntaxhighlight lang="yaml">
testwiki:
warnSummary: "Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}"
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Test)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
enwiki:
warnSummary: 'Warning [[Special:Contributions/$1|$1]]: {{[[Template:$2|$2]]}}'
rollbackOuterSummary: "Reverting $1 by [[Special:Contributions/$2|$2]] (Fortress-Beta)"
keymaps:
# Keymaps that revert and optionally warn. Schema:
# key: JavaScript keyboard event key, can either be a single key or an array of keys to map multiple keys to one action
# summary: summary you want fortress to use when reverting
# template: (optional) warning to leave, without the level number or uw- prefix
# single: (defaults to false if omitted) whether or not the warning is a single issue (no level) warning.
# Do not use left or right arrow, `[`, ` ` (space), `w`, `p` or `g`; these are reserved.
- key: q
summary: non-constructive edits
template: vandalism
- key: d
summary: potentially disruptive edits
template: disruptive
- key: t
summary: test edits by
template: test
- key: r
overrideOuter: true
summary: Reverting edits (Fortress-Beta)
menuCategories:
- name: Vandalism
warnings:
- name: Vandalism
template: vandalism
summary: non-constructive edits
- name: Subtle vandalism
template: subtle
summary: non-constructive edits
- name: Image vandalism
template: image
summary: inappropriate image additions
details: Inappropriate images added to articles
- name: Joke edits
template: joke
summary: non-constructive edits
- name: Conduct/content
warnings:
- name: Personal attacks
template: npa
summary: non-constructive edits
- name: Unsourced
template: unsourced
summary: unsourced additions
- name: Unexplained removal
template: delete
summary: unexplained content removal
- name: MOS
template: mos
summary: potentially disruptive
details: Manual of style violations
- name: Disruption
warnings:
- name: Disruptive editing
template: disruptive
summary: potentially disruptive edits
- name: Factual errors
template: error
summary: factual errors
- name: Test edits
template: test
summary: Editing tests
- name: NPOV
warnings:
- name: Non-neutral
template: npov
summary: non-neutral-edits
- name: Promotional
template: promo
summary: potentially promotional content added
- name: Single issue
warnings:
- name: English variant
template: engvar
summary: incorrect English variants
single: true
</syntaxhighlight>
jak63mtmyyss2ld97aisyskkof8cu9c
User:2NumForIce/styles.css
2
177500
754629
2026-08-02T06:22:47Z
2NumForIce
57336
Created page with "/* */"
754629
sanitized-css
text/css
/* */
2mxuczfr0dl0l45a16e2oujmzw7k0iv
754630
754629
2026-08-02T06:23:04Z
2NumForIce
57336
2NumForIce moved page [[Template:TemplateStyles sandbox/2NumForIce/styles.css]] to [[User:2NumForIce/styles.css]] without leaving a redirect
754629
sanitized-css
text/css
/* */
2mxuczfr0dl0l45a16e2oujmzw7k0iv
754632
754630
2026-08-02T06:24:12Z
2NumForIce
57336
754632
sanitized-css
text/css
#bodyContent {
background-color: black;
color: white;
}
f98z1dlgjch1pxfc11k3ij0gadypaoh
754634
754632
2026-08-02T06:24:59Z
2NumForIce
57336
754634
sanitized-css
text/css
.hw {
background-color: black;
color: white;
}
ontnsbi86s1hz0folenmskshbmn6y1z
754635
754634
2026-08-02T06:25:34Z
2NumForIce
57336
test the extents of ts
754635
sanitized-css
text/css
#mw-content-text {
background-color: black;
color: white;
}
01qwutlg21uo8270y841g9o2pmu5pf4
User talk:2NumForIce/Header
3
177501
754631
2026-08-02T06:23:38Z
2NumForIce
57336
Created page with "<templatestyles src="User:2NumForIce/styles.css" /> Hello world"
754631
wikitext
text/x-wiki
<templatestyles src="User:2NumForIce/styles.css" />
Hello world
cvrlwzdwdasazun3j5wm5yi4h4w4tz9
754633
754631
2026-08-02T06:24:54Z
2NumForIce
57336
754633
wikitext
text/x-wiki
<templatestyles src="User:2NumForIce/styles.css" />
<span class="hw">Hello world</span>
87zhx2y9x4m7usnc2in8dh9hjr9k13g
Insultos
0
177502
754636
2026-08-02T06:57:42Z
PCendrer
75068
Created page with "Insultos muy graves"
754636
wikitext
text/x-wiki
Insultos muy graves
jiq4wrhbch6osdv5ph3tnzxy77n27ry
Badabadum
0
177503
754637
2026-08-02T07:01:11Z
PCendrer
75068
Created page with "Cuando era chiquitito"
754637
wikitext
text/x-wiki
Cuando era chiquitito
q4hvzf9oxwjerjfht92o8qc2en4e9lf
Busara
0
177504
754638
2026-08-02T07:02:24Z
PCendrer
75068
Created page with "dshjhdskdlhs"
754638
wikitext
text/x-wiki
dshjhdskdlhs
ru6qfphse7rbj1ar2feh3f7hh8ddzva
Ourata
0
177505
754639
2026-08-02T07:05:14Z
PCendrer
75068
Created page with "Somos lo piratas"
754639
wikitext
text/x-wiki
Somos lo piratas
dhle17brtda97ap9fhz8medpga8gzt6
Funciona
0
177506
754640
2026-08-02T07:07:25Z
PCendrer
75068
Created page with "haz algo"
754640
wikitext
text/x-wiki
haz algo
6a0pf0vtrk23arr7dun4o65bdqpt49m
Wikipedia:Sandbox/MoveIt e2e 2026-08-02T08-36-11-016Z
4
177507
754647
2026-08-02T08:36:12Z
~2026-42693-51
75122
MoveIt end-to-end test (2026-08-02T08-36-11-016Z), safe to delete
754647
wikitext
text/x-wiki
== Requested move: MoveIt e2e 2026-08-02T08-36-11-016Z ==
MoveIt end-to-end test, safe to delete (2026-08-02T08-36-11-016Z)
<nowiki>{{subst:RMassist | 1 = Example page | 2 = Example page (renamed) | reason = MoveIt end-to-end test, safe to delete}}</nowiki>
== Tail sentinel 2026-08-02T08-36-11-016Z ==
Sentinel: a section-targeted append must land above this heading.
nmo52lvuqkb2jgmc6v0l9yt70n1ae8l
754648
754647
2026-08-02T08:36:19Z
~2026-42693-51
75122
MoveIt end-to-end section append (2026-08-02T08-36-11-016Z), safe to delete
754648
wikitext
text/x-wiki
== Requested move: MoveIt e2e 2026-08-02T08-36-11-016Z ==
MoveIt end-to-end test, safe to delete (2026-08-02T08-36-11-016Z)
<nowiki>{{subst:RMassist | 1 = Example page | 2 = Example page (renamed) | reason = MoveIt end-to-end test, safe to delete}}</nowiki>
MoveIt section-targeted append, safe to delete (2026-08-02T08-36-11-016Z)
== Tail sentinel 2026-08-02T08-36-11-016Z ==
Sentinel: a section-targeted append must land above this heading.
11vix7hpb6293cgaza5gxaro4jotsar